Help with timer/counter programming RX3i PME

Andor

Member
Join Date
Nov 2021
Location
Amsterdam
Posts
77
I don't have much experience in programming. I can do simple configuration.

it is like this. i want to add something to the existing ladder logic in my rx3i (ladder logic pac machine edition 9.8 sim 3).

the current program: is that every time (pt) input comes in, a counter goes up by 1 and the time starts 240 sec. i want the (pt) to be a pulse every time I press the button, 240 seconds must be added. for example. I press 1 time the counter goes up by 1 and the timer of 240 sec starts running. if I press 2 times in a row, then 2 pulses go to the counter and timer and the counter has gone up 2 and the timer is at 480 sec. also with 4 pulses. the counter goes up by 4 and the time of the timer goes up by (4x240sec) so 960 sec. so any pulse that comes in addition to that on top of the current counter and timer running then. how can i do that best by doing this, (move or shift word/bit). I can send the current situation on photo to clarify or via a zip file.

sorry for my bad English. it is not my native language.
 
Are there any limits on how many times the pt input can happen? When does everything get reset? Easy solution is to have the pt input increment a counter and multiply the counter's accumulated value by 240 seconds to get the timer preset.
Assuming you're using a TMR_SEC or ONDTR_SEC instruction, the variable associated with the timer will be a three-element integer array. The second element of the array will be the timer's preset. The UPCTR instruction also uses a three-element integer array. The first elemenet of the array is the counter's accumulated value. You can use a MUL_ INT instruction to multiply the counter's accumulated value by 240 and send the result of the multiplication to the second element of the timer's array.
How and when you reset things is up to you.
 
Are there any limits on how many times the pt input can happen? When does everything get reset? Easy solution is to have the pt input increment a counter and multiply the counter's accumulated value by 240 seconds to get the timer preset.
Assuming you're using a TMR_SEC or ONDTR_SEC instruction, the variable associated with the timer will be a three-element integer array. The second element of the array will be the timer's preset. The UPCTR instruction also uses a three-element integer array. The first elemenet of the array is the counter's accumulated value. You can use a MUL_ INT instruction to multiply the counter's accumulated value by 240 and send the result of the multiplication to the second element of the timer's array.
How and when you reset things is up to you.

this is the current situation. it resets by counting down. I'll get back to your response tomorrow.

E48DDE3C-F7AC-4B5E-9FFE-014C9C0A2CA9.jpeg C4E5241D-DD92-492C-9A7C-82D484967B1E.jpeg 65358A26-D4DE-400E-BB1C-8BC06975625F.jpg
 
Declare two 32-bit integers, i.e. DINTs, call them TARGET and SOFAR, both values are initialized to 0.

Program the button's (debounced?) rising edge to increment the value of TARGET by 1, [ADD TARGET 1 TARGET].

Program a rung with a less-than block, [SOFAR<TARGET], in series with a normally closed contact, [-|/|-], on TDONE, and have that output ("control flow") feeding a 240s timer, and the timer's output feeding a coil [-( )-] that write to bit TDONE.

Program a rung with a normally open contact, [-| |-], on TDONE, and have its output trigger an increment of SOFAR's value by 1 [ADD SOFAR 1 SOFAR].

Program a rung with

  • a greater-than block, [SOFAR>0],
  • in series with an equals block, [SOFAR=TARGET],
  • in series with a normally open contact, [-| |-], on TDONE,
  • and have its output feeding a coil [-( )-]that writes to bit TDONEALL.
TDONEALL will be a one-shot, i.e. have a value of 1 for one scan cycle, every time the timer has completed the most-recently requested incremental number of 240s delays.

Eliminating the third item in that rung, the normally open contact in blue above, will make TDONEALL to be 1 from the time when the timer has completed the most-recently requested incremental number of 240s delays until the the next time the button is pressed.

Doing it this way expands the capacity of the system to around half a Ts ≈ sixteen thousand years, and requires no reset or counting down.

This will probably be uglier than @Steve Bailey's suggestion, but it might have fewer edge cases (e.g. cannot time for more that more than 136 button presses ≡ 32640s ~ 9.07h).

It could also be with only SOFAR and no TARGET, where TDONE decrements SOFAR by 1, and an equals block, [SOFAR=0] in series with a normally open contact, [-| |-], on TDONE would be a one-shot to write a 1 to the value of TDONEALL, or that could SET TDONEALL, and the button press could RESET TDONEALL.
 
Are there any limits on how many times the pt input can happen? When does everything get reset? Easy solution is to have the pt input increment a counter and multiply the counter's accumulated value by 240 seconds to get the timer preset.
Assuming you're using a TMR_SEC or ONDTR_SEC instruction, the variable associated with the timer will be a three-element integer array. The second element of the array will be the timer's preset. The UPCTR instruction also uses a three-element integer array. The first elemenet of the array is the counter's accumulated value. You can use a MUL_ INT instruction to multiply the counter's accumulated value by 240 and send the result of the multiplication to the second element of the timer's array.
How and when you reset things is up to you.

there are no limits, it will probably be pressed 10 times in a row maximum. the reset would be reset every time the coil m stop by a RM COIL (the time is done) as you see in the picture. is that just the result of the counter to be multiplied by MUL_int and forwarded to PV of the timer? I'll try to program it and I'll post a picture of it. thank you very much.
 
Declare two 32-bit integers, i.e. DINTs, call them TARGET and SOFAR, both values are initialized to 0.

Program the button's (debounced?) rising edge to increment the value of TARGET by 1, [ADD TARGET 1 TARGET].

Program a rung with a less-than block, [SOFAR<TARGET], in series with a normally closed contact, [-|/|-], on TDONE, and have that output ("control flow") feeding a 240s timer, and the timer's output feeding a coil [-( )-] that write to bit TDONE.

Program a rung with a normally open contact, [-| |-], on TDONE, and have its output trigger an increment of SOFAR's value by 1 [ADD SOFAR 1 SOFAR].

Program a rung with

  • a greater-than block, [SOFAR>0],
  • in series with an equals block, [SOFAR=TARGET],
  • in series with a normally open contact, [-| |-], on TDONE,
  • and have its output feeding a coil [-( )-]that writes to bit TDONEALL.
TDONEALL will be a one-shot, i.e. have a value of 1 for one scan cycle, every time the timer has completed the most-recently requested incremental number of 240s delays.

Eliminating the third item in that rung, the normally open contact in blue above, will make TDONEALL to be 1 from the time when the timer has completed the most-recently requested incremental number of 240s delays until the the next time the button is pressed.

Doing it this way expands the capacity of the system to around half a Ts ≈ sixteen thousand years, and requires no reset or counting down.

This will probably be uglier than @Steve Bailey's suggestion, but it might have fewer edge cases (e.g. cannot time for more that more than 136 button presses ≡ 32640s ~ 9.07h).

It could also be with only SOFAR and no TARGET, where TDONE decrements SOFAR by 1, and an equals block, [SOFAR=0] in series with a normally open contact, [-| |-], on TDONE would be a one-shot to write a 1 to the value of TDONEALL, or that could SET TDONEALL, and the button press could RESET TDONEALL.

Thank you. this is a bit more complicated for me. i am not very familiar with Sofar term. thank you very much for thinking along. I'm going to try @Steve Bailey's way. that is a bit simpler for me to adapt to the existing situation. thanks again
 
Are there any limits on how many times the pt input can happen? When does everything get reset? Easy solution is to have the pt input increment a counter and multiply the counter's accumulated value by 240 seconds to get the timer preset.
Assuming you're using a TMR_SEC or ONDTR_SEC instruction, the variable associated with the timer will be a three-element integer array. The second element of the array will be the timer's preset. The UPCTR instruction also uses a three-element integer array. The first elemenet of the array is the counter's accumulated value. You can use a MUL_ INT instruction to multiply the counter's accumulated value by 240 and send the result of the multiplication to the second element of the timer's array.
How and when you reset things is up to you.

I just made this but haven't tested it yet. I doubt whether the mul_dint is good. or should the value of the pulses be added to IN1 of MUL_dint?

1F0EBC17-2D34-405F-B3CD-01BC493F3275.jpg B8F13350-DB2D-40CA-BEFC-EA0C8FF4B48E.jpeg
 
Simplify:
CCD26D24-D8B5-49CB-AE2C-6396FB23E200.png
Explanation: there is no need to use an extra rung testing for a value of 0 in the PUSH_BUTTON bit to reset the value of BUTTON_FAILURE to 0, because whenever the PUSH_BUTTON value is 0 the output rung of the timer will be FALSE, so we can use that instead.

In other words, the desired behavior, that the BUTTON_FAILURE value transitions from 0 to 1 ("on") with a 15s (150ds) delay after the PUSH_BUTTON becomes and stays 1 (i.e. push button is "stuck"), is exactly what how the input and output rungs of the Timer ON-delay (TON) instruction behave.

TL;DR

If the timer has expired because the push button was stuck and the PUSH_BUTTON bit value has been 1 for at least 15s so the BUTTON_FAILURE value is 1, and then the push button becomes un-stuck so the PUSH_BUTTON value changes to 0, then the timer's output rung will change from TRUE to FALSE, and the coil will write a value of 0 to BUTTON_FAILURE.

Also, if the timer begins timing but has not yet expired, then the timer's output rung will be FALSE, so the value of BUTTON_FAILURE will also be 0.

Only when the timer has expired, because the push button has been stuck for at least 15s, will the timer's output rung become TRUE, which will cause the coil to write a value of 1 to BUTTON_FAILURE.

The key point to remember is that a Coil instruction always writes something, either 1 or 0, to the value of its operand BUTTON_FAILURE, even if value being written is the same as the value of the operand before the Coil instruction executes.
 
The logic from the push button through the timer to running the pump should be no more than three or four rungs.


For example, that rung with the counter is doing nothing other than copying the value of PT_34 to PT_42 on each scan, so it can be eliminated and PT_42 replaced with PT_34 everywhere else.
 
Also, read this again:

You can use a MUL_ INT instruction to multiply the counter's accumulated value by 240 and send the result of the multiplication to the second element of the timer's array.


It is not the PV that matters, but the second element of the timer's array; once the timer has started timing, the TMR* instruction may not copy the external value from the PV pin to the internal array's PV.

* why bother with the extra complexity of an ONDTR?
 
Same idea; this is more compact, and could be moreso with two rungs, one more branch and the same number of instructions.

But Steve Bailey's code will be easier to follow six months from now, so I think @Andor should go with that.
1F0EBC17-2D34-405F-B3CD-01BC493F3275.png
 
Minor nitpick: @Steve Bailey's LT INT should be LE INT (or LT INT ... 137).

Or use the UPCTR PV to prevent overflow, like the image below.

Caveat: I don't know if PB_Count.Q is legal syntax, but alternatives are trivial (e.g. run UPCTR output to a coil writing a bit PB_Count_At_Max and use that instead of PB_Count.Q, or [LT INT IN1=Duration_timer[1] 32528]).
Untitled.png
 

Similar Topics

Hello every one. I am just beginning with Proface and have no clue how it works. I have read the help section but still im not getting very far...
Replies
2
Views
2,454
Hello my name is Dorrance I am very new to plc programming. I am capable to make simple programs like inputs that trigger outputs but never worked...
Replies
11
Views
3,832
Hi all, This is actually a personal project, if that's ok. My uncle has some property that has a well, he wants to have the well automatically...
Replies
7
Views
2,493
Hi there, I am accustomed to working with Logix 500 but have a program modification I need to do on a CompactLogix.... I created a timer...no...
Replies
7
Views
2,455
I have a conveyor whose speed varies between 20 and 50Hz through a PLC (HMI). I need to program a code with a timer whose value will vary between...
Replies
26
Views
4,439
Back
Top Bottom