News:

  • May 05, 2026, 09:45:29 PM

Login with username, password and session length

Author Topic: Timers in For Loops, other details.  (Read 29907 times)

CReese

  • Hero Member
  • *****
  • Posts: 184
Timers in For Loops, other details.
« on: July 03, 2013, 06:41:07 PM »
Hello again.

I'm currently using a for loop to check conditions over a few dozen IO using arrays, and I'd like to be able to log how long a particular IO has been on/off. A number of questions popped up today:

1. Any reason I cannot set up my own labeled timer variables? It is nice that I can parameterize using a loop variable, e.g. T[V0], if V0 is my loop variable, but would be ideal if I could do something like LightStatusTimers[V0] or something like that. I can block out groups in the timer block, but it makes the names much more descriptive if I can name the blocks individually.

2. I know this is getting greedy, but is there any plan for double-nesting instructions? It seems silly until you try to enable an output using an element of an array. For example, if my output addresses are OutputAddresses0-31, I would enable them using SET Y[OutputAddreses[V0]], if V0 is my loop variable. At the moment I use a move function to move OutputAddreses[V0] into a temporary Vmem address and use that. Also, it appears only V variables can be used for indexing arrays?

3. Lastly, what would be the best way to create a bunch of synchronous timers without having to create them all explicitly? I could create an array of variables to store time using NOW() and some logic on top, but that has only 1s resolution and seems like a pretty ugly hack. There has to be a sneaky way to do this. 10ms resolution is sufficient.

Thanks,
C

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6154
  • Yes Pinky, Do-more will control the world!
Re: Timers in For Loops, other details.
« Reply #1 on: July 03, 2013, 07:21:25 PM »
1. Any reason I cannot set up my own labeled timer variables? It is nice that I can parameterize using a loop variable, e.g. T[V0], if V0 is my loop variable, but would be ideal if I could do something like LightStatusTimers[V0] or something like that. I can block out groups in the timer block, but it makes the names much more descriptive if I can name the blocks individually.

Yes, you can create blocks of timers in the memory config, which can be named any valid block name up to 16 characters.

2. I know this is getting greedy, but is there any plan for double-nesting instructions? It seems silly until you try to enable an output using an element of an array. For example, if my output addresses are OutputAddresses0-31, I would enable them using SET Y[OutputAddreses[V0]], if V0 is my loop variable. At the moment I use a move function to move OutputAddreses[V0] into a temporary Vmem address and use that. Also, it appears only V variables can be used for indexing arrays?

Can't do it as simple parameters in instructions...the encoding is already like 10 pounds crammed in a 5 pound bag. You can use a complex expression in a MATH box, with basically no limitations, but only there...at least for now. The Do-more engine actually has the ability to do full math expressions in virtually every input parameter, but that obviously isn't implemented yet in Designer. Not sure when that will happen...possibly Rel 2.

One of the compromises for making the encoding work was array indexes had to be limited to one type. By nature of being 16 bit and unsigned, V was the best choice.

Since you seem to be using the heck out of arrays, this might be of interest. In addition to the basic V index, you can also do 'block[Vn + disp]', where disp is an integer in the range of 1 to 63. Displaced array refs are great for indexing groups of variables being treated as structures. Eliminates the need for multiple Vs.

3. Lastly, what would be the best way to create a bunch of synchronous timers without having to create them all explicitly? I could create an array of variables to store time using NOW() and some logic on top, but that has only 1s resolution and seems like a pretty ugly hack. There has to be a sneaky way to do this. 10ms resolution is sufficient.

The MATH box has two functions to access the PLC's internal timers: TICKus() and TICKms(). If you don't mind doing the work, you can use TICKms() to snapshot the time, and then do your own math.

"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3607
  • Darth Ladder
Re: Timers in For Loops, other details.
« Reply #2 on: July 04, 2013, 12:48:20 AM »
2D or n-D arrays would be very cool too.  (I think it was said that this isn't feasible, but don't recall for sure).

For example, I have an app where I could really use a 2D bit array, maybe 1000 x 64 or 128.  The reason the 2D-ness would be helpful is that I have to set the values along the 1000 dimension, and read 64 or 128 bits or whatever at a time in the cross direction.
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
Re: Timers in For Loops, other details.
« Reply #3 on: July 04, 2013, 06:35:30 AM »
2D or n-D arrays would be very cool too.  (I think it was said that this isn't feasible, but don't recall for sure).

For example, I have an app where I could really use a 2D bit array, maybe 1000 x 64 or 128.  The reason the 2D-ness would be helpful is that I have to set the values along the 1000 dimension, and read 64 or 128 bits or whatever at a time in the cross direction.

You could do it with a user block of unsigned Dwords 2000 long, index the block by two and MOVER:
Source: MyBlock[n]:0
Dest: C0
Num elements: 32

MOVER:
Source: MyBlock[n+1]:0
Dest: C32
Num elements: 32

(you may be able to just set the first MOVER to 64 and do it with just the one.)
I know it's not real 2-D but there is enough flexibility in Do-more to get a lot done! ;D
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3607
  • Darth Ladder
Re: Timers in For Loops, other details.
« Reply #4 on: July 04, 2013, 11:03:06 AM »
Yeah, that's what I thought of so far too, and it's fine for reading (small direction) but no convenient way for setting (long direction).

I'm not expecting anything to get added soon, so that's probably what I'll do (or actually the syntax would probably be slightly simpler to just use an array of 100K bits).  It will help tremendously that we have indirect addressing for everything now!   :)
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
Re: Timers in For Loops, other details.
« Reply #5 on: July 04, 2013, 11:35:27 AM »
You got me thinking (it's scary I know)

I had to set it up a little different than what I would like, But here is a screenshot that I think will explain my logic.
You could create 64 (or even 128) contiguous Bit Blocks, and then set the "From" of the outer loop to the first of those blocks.
If C1000 is on then the state of C0 through C999 would be stored in the Array.
If C1000 was off then C0 through C999 would reflect the state of the first bit in your Bit Blocks.

The example obviously would be unusable with nested FOR's, but I think it may help to demonstrate what could be done.
« Last Edit: July 04, 2013, 11:41:18 AM by plcnut »
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3607
  • Darth Ladder
Re: Timers in For Loops, other details.
« Reply #6 on: July 04, 2013, 11:42:50 AM »
I agree, FORing was what I came up with as well as the best I could achieve without 2D or 2+ D arrays.  Hadn't thought about using REFWRITE though; have to look into that.  It just shows how higher order arrays would simplify things in certain situations.  Thanks for your help!   :)
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
Re: Timers in For Loops, other details.
« Reply #7 on: July 04, 2013, 11:52:32 AM »
I drew the ladder wrong.
Leave the inner loop out, and place your desired step into MyIndexPointer.
This will give 64 X 1000 Array of fully indexable bits. ;D

New Screenshot:

EDIT: Changed screenshot
« Last Edit: July 04, 2013, 12:09:07 PM by plcnut »
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com

CReese

  • Hero Member
  • *****
  • Posts: 184
Re: Timers in For Loops, other details.
« Reply #8 on: July 08, 2013, 11:29:09 AM »
Quote

The MATH box has two functions to access the PLC's internal timers: TICKus() and TICKms(). If you don't mind doing the work, you can use TICKms() to snapshot the time, and then do your own math.


So what would this look like if I wanted the time in hours with ms resolution, or at least time differential resolution? I store NOW() in one memory location, TICKms() in another memory location, then do (NOW()-NOWinit())+(TICKms()-TICKinit)/1000 and store it in a real memory location, or multiply by 1000 and put it in DWord?

CReese

  • Hero Member
  • *****
  • Posts: 184
Re: Timers in For Loops, other details.
« Reply #9 on: July 08, 2013, 11:45:04 AM »
Nevermind. Tickms is perfect as is.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6154
  • Yes Pinky, Do-more will control the world!
Re: Timers in For Loops, other details.
« Reply #10 on: July 08, 2013, 11:50:08 AM »
I think that would work. You are using relative seconds and relative ms converted to seconds. That sounds fine.

Please note that if you plan on going to a real, you need to promote the math to real somewhere. Dividing an integer by 1000 still produces an integer, but dividing by 1000.0 produces a float.

If you want to convert the output of NOW() back to a date/time struct, you can use EPOCH2DT, and the Math box's NOW() is essentially just DT2EPOCH($Now).
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6154
  • Yes Pinky, Do-more will control the world!
Re: Timers in For Loops, other details.
« Reply #11 on: July 08, 2013, 11:50:48 AM »
Nevermind. Tickms is perfect as is.

Easier is almost always better. ;D
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

CReese

  • Hero Member
  • *****
  • Posts: 184
Re: Timers in For Loops, other details.
« Reply #12 on: July 08, 2013, 11:56:11 AM »
While you're here, why do I get warnings on PD/ND in for loops? I have it set up to store an INIT value on PD and ND. An alarm condition stores an init value, and in real time the math function calculates how long the alarm condition has been on, and when it's been on for some period, the alarm is activated. A pretty typical on delay without the use of the timer struct.

Anyway, so it appears to work just fine. Is there a reason why edge structures would not work well in loops, hence the warning?

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3806
    • Host Engineering
Re: Timers in For Loops, other details.
« Reply #13 on: July 08, 2013, 01:57:42 PM »
Differentials (or any edge trigger) CAN work within loops, but you have to realize that the input logic driving the edge may not be changing while within the loop.  So, traditional input logic to an edge trigger will most likely NOT work (e.g. when X0 goes from OFF to ON), the power flow within the loop will never change while within that loop.

The only input logic values that can change within a loop (in the same PLC scan) are variables contained WITHIN the loop (e.g. a relation contact on an index that is being incremented within the loop).  Also, if you are taking advantage of .TimeSlice, especially "no time slice" where your looping is only executed once per PLC logic scan, then edge triggers can also work there.  However, looping and PLC logic scans are not exactly "intuitive", hence the warning.

We hope to implement an "ignore this specific Program Check Message/Warning Rule on this specific rung" feature, where you understand what the warning is, but know you it can be ignored in this specific instance.

CReese

  • Hero Member
  • *****
  • Posts: 184
Re: Timers in For Loops, other details.
« Reply #14 on: July 08, 2013, 05:27:07 PM »
Yes, the reason it is working is that the transition always occurs in the same execution, on the rung or rungs above. Makes sense.