DLO6 - Timer Woes

Terry Woods said:
"Another little tidbit for AD PLC's:Make it a firm habit to only use ODD ( or EVEN) numbered timers and counters, don't mix them up. AD uses two timers worth of space in some cases...it will realy screw you up...."

Good God... idiotcy!

Not really. The issue is really overstated, and not at all diffucult to keep track of.

It a matter of using the memory more efficently. This is only the case with the accumulating timers. (TMRA, or TMRAF). TMRA can count to 999,999.9 seconds; TMRAF can count to 99,999.99 seconds. Both of these timers accumulators require two Vmem locations. If you assign an accumulating timer to T0 then you've used V0 & V1, so the next timer should be T2 that will accumulate with Vmem V2. If you use a standard timer (TMR or TMRF) they only require ONE Vmem for the timer accumulator.

Directsoft has a "Usage View" window that allows you to quickly look and see what memory locations are currently in use by your program. A couple of clicks and a quick look will prevent you from overlapping memory.
 
It's true that the AD systems require you to be a lot more careful than in AB. The data memory space is not nicely broken up into different types. YOU are responsible for looking up (it IS all documented) and enforcing your selections, not only Timer and Counter types with their different word usage but also numeric types, BCD/Binary. YOU are responsible for invoking the proper number type conversions and using the proper instructions based on number type. But, if I keep these in mind, I find the instruction set very powerful.
 
OK... I got this from the DL405 Manual...

Caution: The TMRA uses two consecutive timer locations, since the preset can now be 8 digits, which requires two V memory locations. For example, if TMRA T0 is used in the program, the next available timer is T2. Or if T0 was a normal timer, and T1 was an accumulating timer, then the next available timer would be T3.

What this means is... Timer Memory is assigned like so...

Timer Memory
Reference Address USAGE
T0 V0 T0 Standard
T1 V1 T1 TMRA - Word-1
T2 V2 T1 TMRA - Word-2 T2 is NOT available!
T3 V3 T3 Standard
T4 V4 T4 Standard
T5 V5 T5 TMRA - Word-1
T6 V6 T5 TMRA - Word-2 T6 is NOT available!
T7 V7 T7 TMRA - Word-1
T8 V8 T7 TMRA - Word-2 T8 is NOT available!
T9 V9 T9 Standard
T10 V10 T10 Standard
Next available Timer is T11


.
This is the compacted version I spoke of earlier. This is nothing less than idiocy! They HAD to provide that "Caution"... it's to cover their short-sightedness!

However, in light of this, I can now see the rational behind using only the Even, or only the Odd Timers. Of course, that means that the total number of timers is cut in half at the git-go.

So... if there are 1000 Timer References available (T0 to T999) then you can have as many as 1000 Standard Timers, or as few as 500 Accumulating Timers, or some combination between 500 and 1000.

The basic design problem here is that AD has chosen to bind the Timer Reference Number, regardless of the timer-type, directly to a V-mem address. Bad move.

In effect, by referencing a particular timer number, the programmer references a specific location in Timer Memory. He then declares, by declaring the timer-type, how many locations are required for the particular timer. That would be 1 location for a Standard Timer, and 2 consecutive locations for an Accumulating Timer.

Having designed it this way, each Accumulating Timer Reference precludes the use of the next Timer Reference in sequence. If T0 is Accumulating, then the next timer in the sequence, T1, is not available. If the programmer references T1 then he is "stepping" on T0.

They could have done better. They could have taken one of two other approaches...

They could have built in a Timer Memory area for each type. That is, T0, T1, T2... and TA1, TA2, TA3... Then, you would have access to ALL of the particular timers without "stepping" across any timer boundary. Of course, depending on the number of available Timer References, that might mean that AD would have to add more memory for timers. Or, if there were only 1000 timer-memory locations, they could simply say... you can have up to 500 Standard Timers (T0 to T499) and up to 250 Accumulating Timers (TA0 to TA249).

Or, using only a single timer memory area, they could have had the timer memory locations dynamically allocated by timer-type. This is a tougher way to go, but it can be managed. It is, after all, the way the better systems manage "virtual memory". In this case, the processor recognizes the timer-reference and the declared timer-type. The processor maintains two look-up tables, one for Standard and one for Accumulating.

The processor then goes through the timer-memory area to find the first available slot that matches the type (1-location for Standard, or 2 consecutive locations for Accumulating). The processor then records that, or those, locations into the particular Timer Reference look-up table. At the same time, the timer-memory locations are "marked" as used. If a timer reference is removed from the program then the timer-memory locations associated with that timer is "unmarked" and made available for subsequent use. Then, that timer, in the particular look-up table, is cleared. In terms of memory usage, this is no worse than the existing scheme.

A "smart" programming package would be capable of detecting and indicating when you tried to use a timer that is already in use. Also, at each compile, the processor could compact the timer-memory area, while updating the look-up tables. This would make more 2-location slots available.

The benefits of either of these methods is that you would have access to ALL of the timer references AND you would not be capable of "stepping" on any other timers. Another benefit is that you would be able to access the data in each timer by timer reference as opposed to V-mem reference. That means that V0, V1, V2 etc. would be available for normal V-Mem use.

Granted... we all have to use our PLCs the way they were designed. But damn! AD sure could have done a much better job on this issue.
 
Terry,

I think calling it idiocy is a tad harsh. After all, the method they chose allows the the maximum flexibility in mixing the two types of timers in the memory space allocated to them. If you have 100 bytes of memory allocated, you can have 100 TMR instructions, 50 TMRA instructions, or any mix of the two that adds up to 100 bytes.

The only drawback to the approach is that it places some of the responsibility for managing the use of the memory on the shoulders of the programmer. All in all, not a bad tradeoff in my opinion.

Now, if we're going to throw around the word 'idiocy', there's the decision to use BCD arithmetic instead of binary...
 
Terry Woods said:
This is the compacted version I spoke of earlier. This is nothing less than idiocy! They HAD to provide that "Caution"... it's to cover their short-sightedness!

However, in light of this, I can now see the rational behind using only the Even, or only the Odd Timers. Of course, that means that the total number of timers is cut in half at the git-go.

I dont, that would be a total waste of possably valuable memory space. I just dont understand what's so diffucult about keeping track of your timers....

Terry Woods said:
So... if there are 1000 Timer References available (T0 to T999) then you can have as many as 1000 Standard Timers, or as few as 500 Accumulating Timers, or some combination between 500 and 1000.

That's actually the beauty in it. Given a fixed amount of available memory, you can use whatever memory for whatever your applicatiuon calls for.

Terry Woods said:
The basic design problem here is that AD has chosen to bind the Timer Reference Number, regardless of the timer-type, directly to a V-mem address. Bad move.

Actually binding the Vmem makes it much simpler to program. How much extra time and more complex would it be if you had to assign memory for each timer?? Quite a bit. Additionally if you dont use the timer; for example timer T21, then V21 would be available as user memory. So it's only dedicated if your using that timer.

Terry Woods said:
In effect, by referencing a particular timer number, the programmer references a specific location in Timer Memory. He then declares, by declaring the timer-type, how many locations are required for the particular timer. That would be 1 location for a Standard Timer, and 2 consecutive locations for an Accumulating Timer.

Having designed it this way, each Accumulating Timer Reference precludes the use of the next Timer Reference in sequence. If T0 is Accumulating, then the next timer in the sequence, T1, is not available. If the programmer references T1 then he is "stepping" on T0.

Sounds pretty simple to me...

Terry Woods said:
They could have done better. They could have taken one of two other approaches...

They could have built in a Timer Memory area for each type. That is, T0, T1, T2... and TA1, TA2, TA3... Then, you would have access to ALL of the particular timers without "stepping" across any timer boundary. Of course, depending on the number of available Timer References, that might mean that AD would have to add more memory for timers. Or, if there were only 1000 timer-memory locations, they could simply say... you can have up to 500 Standard Timers (T0 to T499) and up to 250 Accumulating Timers (TA0 to TA249).

Why? Why add dedicated memory for something that is actually so infrequently used, (Accumulating timers). You cant expect them to provide infinate memory? So what they did is provide a flexable and efficent way to use memory, and maximize the amount of timers that your application requires without having to add additional memory and cost.

Terry Woods said:
Or, using only a single timer memory area, they could have had the timer memory locations dynamically allocated by timer-type. This is a tougher way to go, but it can be managed. It is, after all, the way the better systems manage "virtual memory". In this case, the processor recognizes the timer-reference and the declared timer-type. The processor maintains two look-up tables, one for Standard and one for Accumulating.

The processor then goes through the timer-memory area to find the first available slot that matches the type (1-location for Standard, or 2 consecutive locations for Accumulating). The processor then records that, or those, locations into the particular Timer Reference look-up table. At the same time, the timer-memory locations are "marked" as used. If a timer reference is removed from the program then the timer-memory locations associated with that timer is "unmarked" and made available for subsequent use. Then, that timer, in the particular look-up table, is cleared. In terms of memory usage, this is no worse than the existing scheme.

A "smart" programming package would be capable of detecting and indicating when you tried to use a timer that is already in use. Also, at each compile, the processor could compact the timer-memory area, while updating the look-up tables. This would make more 2-location slots available.

The benefits of either of these methods is that you would have access to ALL of the timer references AND you would not be capable of "stepping" on any other timers. Another benefit is that you would be able to access the data in each timer by timer reference as opposed to V-mem reference. That means that V0, V1, V2 etc. would be available for normal V-Mem use.

It's entirely possable that a program might require two references, or more then one timer using the same timer reference. Your "Smart" package would preclude that possability. I've done many application where "stepping" on a particular Vmem location was intentional.

Terry Woods said:
Granted... we all have to use our PLCs the way they were designed. But damn! AD sure could have done a much better job on this issue.

There are good arguments for and aganst how AD decided to assign memory for the timers & counters. From my own perspective it took a little bit of getting use to, but after doing hundreds of applications with AD PLCs, I can see the logic in it.
 
Ah - the BCD versus binary math thing. I was tripped by this when I started using the AD line. The binary math instructions are so much faster that for any math intensive areas I use them. Even with the conversion instructions it goes faster. Fortunately the compare instructions (whether inline or in boxes for double words) operate correctly whether the operands are BCD or binary (as long as they're both the same type - if not, the compare will be correct as if both were binary numbers but would probably not be what was expected.)

Any BCD type instruction needs CPU cycles to check that operands are valid BCD as well as checking the result of the math for possible nibble BCD overflows and correction.

All of the math used to set up and use pointers is also binary. They say the BCD decision was from the days of thumbwheel switch entry. To bad they can't provide a firmware option to convert all default usage (including in timers and counters) to binary.

[Edit] Adding to the Timer/Memory Space discussion, another strategy is to consiously use one end, lets say the low end, of timers for standard singl word type and using those above some arbitrary point for accumulating (double word usage) timers.
 
Last edited:
Hi group,

I posted that note about odd/even just in case the thread-starter was not aware of the fact that AD CAN require two memory locations for certain functions...I sure did not mean to set off a slugging match.
I now assign any two part instructions with numbers starting at 200, this works well for me as most of my programs are in the range of 75 to 200 rungs, babies really, and rarely include more than 25 timers, if that...TPTB here do not like timers that they cann't play with, and since they won't spring for the fancy HMI's, I just work around them. Heck, it saves me time, and I can tell by the way the pilot lights blink whats going on, so I,m happy.
Bernie, I am just going to start a project that will involve a lot of math, so thanks for the hint on BCD v. Binary.

David
 
Last edited:
First let me start by asking, Did you find the answer to your problem?

Second, here’s a tip for when you use Timers and Counters that require (2) memory locations. When I use Timer or Counter instructions that require (2) memory locations I use the documentation to help keep track of the extra memory location.

 
Element Nickname Description

T0 Pump 1 Tmr Pump 1 Timer
T1 Pump 2 Tmr Pump 2 Timer
T2 (Pump 2 Tmr) **Do Not Use**

TA0 Pump 1 Tmr. Pump 1 Timer Value
TA1 Pump 2 Tmr. Pump 2 Timer Value
TA2 (Pump 2 Tmr.) **Do Not Use**



Now if anyone or myself tries to use Timer 2, you are either going to figure out why the documentation says not to use that timer or just use a different timer.

Terry, how AD has laid out their times makes perfect sense. They could have used your first approach, but that would be a waste of memory. They could have used your second approach, but that would add to the cost of the PLC. That’s a cost I’m not interested in paying for, nor are my customers. IMHO, AD isn’t interested in making the best PLC on the market, they make the best PLC for the best price. Because of this, there are some tradeoffs.
 
I do the same thing as Tark. Every time I use a timer (or counter) that uses 2 V-memory locations, I immediately document it.

I simply add an "R" to the end of the nickname, and the description gets labeled "Reserved (Tnnn)".

Sorry Terry, but this 'idiocy' has never caused me any grief. DirestSOFT is just soooooo intuitive to use... (y)

On the other hand, GE's use of 3 registers for a timers HAS aggravated me. Who counts comfortably by 3?... :rolleyes:

Also, GE starts their memory tables at 1 instead of 0... o_O

🍻

-Eric
 
David,

Thanks for asking.

The thread has kind of wandered into another topic, but that is not necessarily a bad thing. After all, this is a place to exchange viewpoints on different topics.

To put in my two cents on the discussion, I don't feel that AD has done anything wrong in setting up the timer memory allocation like they have. Sure, if you are using all accumulators, the maximum number of timers is cut in half. But on the other side of the coin, if you are using non-accumulating timers, you get twice as many. Is the glass half empty or half full? This is for you to decide.

Regarding one of the other forum members stating that I may not understand how the timers are addressed, this is not the case. Honestly, for this application I need about 10 timers at the very most. If I can circumvent the whole issue by using only the evens or odds, then I will do so just for simplicity sake. What would happen if I had all of my timers 'squished' together to make the memory range as small as possible and I need to change a non-accumulator to an accumulator? I would have to place it after my last timer and have an empty memory space in what used to be an optimized range. To me, leaving two spaces for each timer is the best alternative when you are confident that using up all of your timers is not a concern.

Rgarding how I made out with the accumulating timers resetting, setting my timer memory ranges to retentive did the trick. On occasion, the machine will be completely powered down to do some maintenance. This in turn, powered down the PLC and my accumulators were lost while the actual count, target count, etc. were still held in memory. I am not sure if this is standard, but seem to remember other PLCs keeping the accumulated values on power down by default. In any case, everything is working like a charm now.

Thanks again for the help on this one. Sometimes it is the simplest things that we do not see.
 
DL06 said:
Rgarding how I made out with the accumulating timers resetting, setting my timer memory ranges to retentive did the trick
Chalk one up for Tark. Where do I get my gold star at?
 

Similar Topics

Hello everyone, I am new to your forum but I did buy the learning book afew years back. I need to do some programming and need advice on what is...
Replies
18
Views
3,922
I have some logic that I have written within a 5380 series controller that tracks the time an event is started, while the event is running an RTO...
Replies
2
Views
100
Hi all, I have a simple question that I have overcomplicated and gotten stuck on. I have a variable, we can call it "light" that I need to stay...
Replies
4
Views
332
Question to anyone with ideas about my thoughts on upgrading a very vintage timer, which is being used to switch between 2 5hp domestic water...
Replies
14
Views
445
why my timer only executes once here? After first time i use it, ET stays at 0ms all the time. It is in FB
Replies
5
Views
320
Back
Top Bottom