Accumulating timer from a analog input

Brandon_K

Member
Join Date
Mar 2016
Location
Pittsburgh, PA
Posts
150
I'm having a hard time wrapping my head around this today. Very likely due to being sick and not thinking straight, plus my inexperience with ladder logic.

I have a pair of pressure transducers that send off to analog inputs.

The scaling is done in PSI and I have some compare values set with two timers.

Right now I have it configured as;

*If the pressure is between 4-15psi or greater than 23psi, Timer A accumulates.

*If the pressure is between 16-22psi, Timer B accumulates.

What I want to add is a function that only allows the timers to accumulate if the pressure value has been constant for more than lets say, 300ms. So, if the pressure is increasing or decreasing, unless it stands on a value for more than 300ms, I do not want the timer to start. Example; if the 7psi is present for longer than 300ms, timer A starts accumulating. If the value changes, the timer stops, until another value is present for 300ms or greater.


Some background on the process to possibly help understand better;

This is part of a game (attraction industry). The players need to set a pair of regulators to a the correct values (19psi and 55psi, +/- 3psi) in order to proceed to the next step. If they set it to the incorrect pressure, "bad time" (Timer A) starts accumulating, which part of their score is based on. As it currently sits, they players are forced to accrue "bad time" even if they know to correct values before they start playing with the regulators. Initially I was going to put a deduction of time in as a constant for the formula that calculates their scores, but I've found people wildly vary in the time it takes to get there. For me, I could start from 0psi and set 19psi in ~1400ms. One employee took ~9000ms to get there, another 6000ms.

I figure if I they sit on a given pressure value for more than ~300ms or so, they've made a choice to set that pressure as the "puzzle solve", so I want Timer A to start accumulating.

I can't think of any way to do this without creating a timer for every value between 4 and 125, each setting a bit to start Timer A. That's a lot of timers and I know there has to be a better way to do it. With my inexperience with ladder logic, I don't know of a more efficient way to do it.

Thoughts? I'm using a Productivity 2000 PLC.

I've attached a screenshot of my current timer setup for one of the transducers. This setup works, but has no consideration for what I spoke about above. There are some additional contacts in there to stop accruing bad time once they solve the puzzle, as well as to not start accruing any time until they complete the tasks needed prior to this particular game. There is also a contact that resets the "good time" if they go outside of the "good" range before the determined time value is set. The game is designed that they must be in the good range for 3 seconds to trigger that complete. Once it is complete, no additional "bad time" is possible to accrue.

flask_timers.jpg
 
Last edited:
*If the pressure is between 4-15psi or greater than 23psi, Timer A accumulates.

If the pressure is between 4-15psi or greater than 23psi, Timer A0 (300mS) starts. When Timer A0 is DN, Timer A accumulates.

*If the pressure is between 16-22psi, Timer B accumulates.

*If the pressure is between 16-22psi, Timer B0 (300mS) starts. When Timer B0 is DN, Timer B accumulates.
 
Hi,

I hope I have understood your question properly but it has been a long day.....

Can you not load the analogue to a temporary register and then compare that to the current reading after your allotted time, if they are the same start the counter, if not then don't but put the current analogue into the temporary register and repeat.
 
I edited my original post, looks like while some of you guys were replying.

If the pressure is between 4-15psi or greater than 23psi, Timer A0 (300mS) starts. When Timer A0 is DN, Timer A accumulates.



*If the pressure is between 16-22psi, Timer B0 (300mS) starts. When Timer B0 is DN, Timer B accumulates.

Correct, but it needs to be an individual value. IE, if 7psi to 8psi is less than 300ms, no time accrued. If 7psi is seen for more than 300ms, time starts accruing.

Hi,

I hope I have understood your question properly but it has been a long day.....

Can you not load the analogue to a temporary register and then compare that to the current reading after your allotted time, if they are the same start the counter, if not then don't but put the current analogue into the temporary register and repeat.

That sounds plausible, but I'm not sure how to go about it? Would it be as simple as

Compare, if "Temp_analog_value" = "temp_analog_value" for >300ms, set "Start_TMR_A" bit?

Now that I write that out, that would work, but how would I go about resetting the timer when it moves to the next value? The Productivity 2000 does not seem to have a non-accumulating timer instruction. In both of the included timer instructions (simple timer, timer), if time has accrues, it retains that count even if the timer-up rung is no longer activated. Back when I did my PLC basics training on a Direct Logic cpu, there was an instruction that was basically a non-accumulating timer, it would reset to zero if the rung went false.
 
Hi,

I hope I have understood your question properly but it has been a long day.....

Can you not load the analogue to a temporary register and then compare that to the current reading after your allotted time, if they are the same start the counter, if not then don't but put the current analogue into the temporary register and repeat.

Analog values are rarely "the same", even if they are !!

It might work in this context since his scaled range is low, and very granular, but wouldn't work over a larger scale range.

I think my solution is better, and is very similar to "debouncing" an input. The conditions must be met for a certain time before you act on it.
 
The Productivity 2000 does not seem to have a non-accumulating timer instruction. In both of the included timer instructions (simple timer, timer), if time has accrues, it retains that count even if the timer-up rung is no longer activated.

Sorry I am not familiar with that PLC, I have done a quick search on the net and the timer has a reset facility, could you not link that to a timer done tag. This may not be correct as I have never seen one of these PLC, let alone programmed one.
 
I edited my original post, looks like while some of you guys were replying.

Correct, but it needs to be an individual value. IE, if 7psi to 8psi is less than 300ms, no time accrued. If 7psi is seen for more than 300ms, time starts accruing.

I can't see what you changed in your edit, but I believe you have missed the point.

You already have logic that determines if timer A or B should accumulate, all i did was interpose "debounce" timers on those conditions, before you let the accumulator timers run.

I'm confused as to why you think you need a timer for every value in the scaled range, your existing "limit" code generates the required permissives.
 
Analog values are rarely "the same", even if they are !!

It might work in this context since his scaled range is low, and very granular, but wouldn't work over a larger scale range.

I think my solution is better, and is very similar to "debouncing" an input. The conditions must be met for a certain time before you act on it.

Could you give me a little more detail to your original reply? I don't understand the instructions that you've used. In addition, I'm not sure that it would work, unless I'm misunderstanding it entirely. The way I read that is that it would be if the value is anywhere between 4-15psi for more than 300ms, the timer would start. This would be true constantly as it took me ~1400ms to get from 0 to 19. I need it to compare individual values for greater than 300ms. But it's certainly possible that I'm completely misunderstanding what those instructions mean! (Bear in mind, I have very little experience with address based PLC's. I've mostly self taught myself on the Productivity which is tag based, so some of what I see here on the forums are completely foreign to me).


Sorry I am not familiar with that PLC, I have done a quick search on the net and the timer has a reset facility, could you not link that to a timer done tag. This may not be correct as I have never seen one of these PLC, let alone programmed one.

I think I may have the reset figured out, once I get past the original issue.

Compare, if "Temp_analog_value" = "temp_analog_value" for >300ms, set "Start_TMR_A" bit?

Not sure what I was thinking when I replied with this. This won't work as the rung would be true 100% of the time.
 
Not sure what I was thinking when I replied with this. This won't work as the rung would be true 100% of the time.

Like I say I am not familiar with this type of plc but I would have thought it would have to be:

Compare, if "Real_analog_value" = "temp_analog_value" for >300ms, set "Start_TMR_A" bit?

We have used a similar code on Bradley and Siemens where we load the real Value into a temporary value every scan and compare them, if they stay the same for a preset time then an output is activated. It maybe a crude way of doing it but it should work I think.
 
I can't see what you changed in your edit, but I believe you have missed the point.

You already have logic that determines if timer A or B should accumulate, all i did was interpose "debounce" timers on those conditions, before you let the accumulator timers run.

I'm confused as to why you think you need a timer for every value in the scaled range, your existing "limit" code generates the required permissives.


I am certainly missing something.

The logic I have is for a broad range. The way I see it, the debounce timer would take that entire range into play. IE, if it takes them longer than 300ms to get from 4psi to 8psi, it will start timing until they get to 16psi. This is not want I want. Again, I may be missing something to the logic of this.

With your way;

4 to 5 takes 150ms
5 to 6 - 150ms
6 to 7 - 150ms
7 to 8 - 150ms
8 to 9 - 150ms
9 to 10 - 150ms

With a simple 300ms debounce, your way would have started the timer after it reached 6psi (4 to 6psi = 300ms) and accrued 600ms of time.

With the way I'm suggesting (or at least, the problem), the timer would never start since none of those single values were present longer than 300ms.
 
OK, Brandon, I can see what you are getting at with a re-read of your requirements.

You want the respective timers to accumulate only if the analog input remains at a single value for ~300mS.

I'll write this in a "generic" statement list, as I don't know your platform...

IF Current_Value = Last_Value, Same == 1
Last_Value == Current_Value

IF Same = 1, Run Timer_Dwell ;~300mS
ELSE Reset
Timer_Dwell

IF {whatever pressures you need} AND
Timer_Dwell = Done, Run Timer_A ;

IF {whatever pressures you need} AND Timer_Dwell = Done, Run Timer_B ;

With this pseudo-code, the main accumulator timers will only accumulate if the value remains constant for more than ~300mS.

You'll get away with this because your scale range is small and very granular. For higher resolution scales, you would have to introduce or hysteresis maths.




 
OK, Brandon, I can see what you are getting at with a re-read of your requirements.

You want the respective timers to accumulate only if the analog input remains at a single value for ~300mS.

I'll write this in a "generic" statement list, as I don't know your platform...

IF Current_Value = Last_Value, Same == 1
Last_Value == Current_Value

IF Same = 1, Run Timer_Dwell ;~300mS
ELSE Reset
Timer_Dwell

IF {whatever pressures you need} AND
Timer_Dwell = Done, Run Timer_A ;

IF {whatever pressures you need} AND Timer_Dwell = Done, Run Timer_B ;

With this pseudo-code, the main accumulator timers will only accumulate if the value remains constant for more than ~300mS.

You'll get away with this because your scale range is small and very granular. For higher resolution scales, you would have to introduce or hysteresis maths.





Like I say I am not familiar with this type of plc but I would have thought it would have to be:

Compare, if "Real_analog_value" = "temp_analog_value" for >300ms, set "Start_TMR_A" bit?

We have used a similar code on Bradley and Siemens where we load the real Value into a temporary value every scan and compare them, if they stay the same for a preset time then an output is activated. It maybe a crude way of doing it but it should work I think.

I've setup the compares just like you guys have recommended (as well as most of the rest of the logic that daba has suggested). The problem I'm running into is that the values always equal each other through the entire range, so the rung is always true, always activating the 300ms timer. There is never a "break" in the compare instruction,

If anyone feels so inclined to look at my logic, I've attached it. I changed the extension to .zip. It will need changed back to ".adpro"

I've mentioned it a few of the posts as far as the platform I'm on, which is Automation Direct's Productivity 2000. Their programming suite is available (for free!) here; http://support.automationdirect.com/products/p3000.html Here is the direct download link too.
 
confuse question

confuse post?

I've spelled out what I am trying to do as best as I can.

If you take everything else out of the equation and break it down to it's absolute simplest of things, I need;

Code:
IF 4 = 4 > 300ms = true

But I need that to compare against every number from 4 to 125.
 
Code:
IF 4 = 4 > 300ms = true
But I need that to compare against every number from 4 to 125.

calculate first input with hysteresis values, then compare if on next scans input stays between calculated values.
If input stays between hysteresis over 300ms then accumalate your second timers


So something like this. There is oneshot, if input is changed more than hysteresis allow.
you can let 300ms timer accumalate when oneshot is at zero state.


value_plus_hyst:= saved_value + hysteresis
value_minus_hyst:= saved_value - hysteresis

input_changed:=0; //oneshot bit


if input > value_plus_hyst
then
saved_value:= input;
input_changed:=1;
end_if;

if input < value_minus_hyst
then
saved_value:= input;
input_changed:=1;
end_if;
 

Similar Topics

Hi all, Can anyone tell me why the MinDuractionACC isn't accumulating in the example below? Is it just a visual bug? I've tried in multiple...
Replies
4
Views
1,206
I AM Using a AB micro1500 PLC and the PTO instruction. I need a program or technique to keep a running total of all pulses produced from the PTO...
Replies
0
Views
1,083
Hello everyone, so I added some inputs and 2 TON timers to an existing program that I knew was working just fine before I added these. I verified...
Replies
3
Views
2,326
Hey guys, we have a big trouble with our drives; In our application we have often to disable the drive and hold it on brake; The problem is after...
Replies
2
Views
1,630
In a system I'm working on, remote well pump sites report to a central controller. Amongst other signals, the remote well pumps report the daily...
Replies
9
Views
4,718
Back
Top Bottom