Anyone knows more elegant way of doing this ?

darkesha

Member
Join Date
Nov 2007
Location
Calgary
Posts
107
Hi everyone,

I am in process of converting one of our lines from RS5 (PLC5) to control logix (RS5000), and its going pretty good, but I got to the point that I am not sure how to solve one small problem.

I submit the way it was done in RS5.
Really simple and elegant. Instruction MOV would start filing #N50:[T34:36.ACC] where this timer is set with 1 second time base.
This in turn mean that every time when this timer's ACC change, a new value would be recorded in next location.

SInce there is no more time bases of 1 second, this means I need to change the original logic. I am kind of inclined to simplify our older and more complex problems so I really hesitate to change this to what it seems as my only solution.
That would involve including another timer (triggered by the original one), set to time out every second, whose DN bit would trigger a counter...and you all can see where all this goes.

Another question is can I keep the MOV instruction, or do I have to use File Fill ? I am asking this, since in RS5, if I put prefix # before the destination in MOV, the program would automaticaly knew.
# does not work in RS5000, and I am afraid that I would be getting new value over writing the old one with every new refresh.

Thanks a lot,

Darko
 
I would just set up a one second timer to trigger a CTU. Set the CTU preset for the same number of seconds as in the original program T34:36.PRE. Add a rung to reset the Counter when it is done, and use the counter.acc in your indirect address. It only adds two new instructions (CTU, RES).

Paul
 
Another thing I have noticed it that you can't use specifier the same way it is possible in RS5:
Pressure[NewCounter.ACC] - will not be accepted, but
Pressure[AccValue] - will if NewCounter.Acc is Alias for AccValue
 
I don't have Logix5000 on this machine and have not used it much. With that said, I still think you are able to use the address of the timer accumulator in your indirect address. I don't believe the alias is required.

EDIT: Maybe I am wrong...looking again at your reply it appears that is exactly what you tried...
 
Last edited:
You can embed computations in indirect addresses in RSLogix5000.

MOV DATA DATA_ARRAY[Timer.ACC/1000]

The only thing to take note of is rounding. i.e. between t=0 and t=.5 the target is DATA_ARRAY[0]. Between t=.5 and 1.5 its DATA_ARRAY[1], Between t=1.5 and 2.5 its DATA_ARRAY[2]. If this is not a problem, then used the embedded computation.
 
Last edited:
Use Alaric's suggestion, and put the timer in a periodic task that's run every 1000 msec.
That will avoid the potential rounding issues.

I've played around with timers in periodic task, and the .acc only increments by the time of the task.
 
Nice trick for the rounding problem there Ken.

You could skip using a timer at all and perform the data move in a periodic task with a DINT as an incrementing pointer.
If Pointer > MaxSize then Pointer := 0
DATA_ARRAY[Pointer] := Data
Pointer := Pointer +1

And just on the off chance the program is storing the data once a second for a running average, then search the forum for running average to see some other tricks.
 
Last edited:
You can embed computations in indirect addresses in RSLogix5000.

MOV DATA DATA_ARRAY[Timer.ACC/1000]

The only thing to take note of is rounding. i.e. between t=0 and t=.5 the target is DATA_ARRAY[0]. Between t=.5 and 1.5 its DATA_ARRAY[1], Between t=1.5 and 2.5 its DATA_ARRAY[2]. If this is not a problem, then used the embedded computation.

Hm...There is probably something that Im overlooking, since trying to follow your example, I end up with an error.
First MOV is not elegant way (aliasing the .ACC value), and second MOV is the quoted one (that hadnt been accepted by the software).

Anyone sees where's my mistake ?

untitled.jpg
 
Nice trick for the rounding problem there Ken.

You could skip using a timer at all and perform the data move in a periodic task with a DINT as an incrementing pointer.
If Pointer > MaxSize then Pointer := 0
DATA_ARRAY[Pointer] := Data
Pointer := Pointer +1

And just on the off chance the program is storing the data once a second for a running average, then search the forum for running average to see some other tricks.

No, I am trying to leave logic as much the same as before, just for the sake of commissioning, since I dont want to be stuck with deeper changes and then trying to trace it back all the way.
All I am changing is grouping the old data table words and bits into new created arrays and have (let's say), N51: and N34: and other bits and pieces moved to HydroWord array or HydroBit array. Even this change scares me since its going to make it harder to trace it back in the event of malfunction.

And we all know, after 10 days of shutdown of the line, its always PLC's fault.
Especially if the PLC is brand new, never used before and never comissioned.
I will get 3 hours of the last day just to verify the communication between racks, and everyone expects it to run as before.
 
HI,
Okie says:
if you can do that, then surely you can put a counter.acc in the indirect address.
Yes it can be done but... in 5000 there isn't a choice for the timer "Base" value. It is always Milliseconds in the base. So if the timer.acc was used, the CPU would try to advance the indirect address on every millisecond instead of the PLC-5's every one second interval.

I would make a self re-setting one second timer & use the done bit to increment a counter. The counter.acc value can be used in the MOV. But then you will need a reset for the counter to make sure the data does not exceed the file boundrys. I can't think of a cleaner way to do it.

BD
 
HI,
Okie says:
Yes it can be done but... in 5000 there isn't a choice for the timer "Base" value. It is always Milliseconds in the base. So if the timer.acc was used, the CPU would try to advance the indirect address on every millisecond instead of the PLC-5's every one second interval.

I would make a self re-setting one second timer & use the done bit to increment a counter. The counter.acc value can be used in the MOV. But then you will need a reset for the counter to make sure the data does not exceed the file boundrys. I can't think of a cleaner way to do it.

BD

This is exactly what I have done, except it really looks like you cant have specifier such as .ACC bit in the MOV instruction:
Error: Rung 2, MOV, Operand 1: Invalid array subscript specifier.
You have to alias this .ACC with new DINT tag
I was just wondering if there was other way.
 
Last edited:
On the picture above you have brackets inside another set of brackets that is invalid with logix
XX[YY[ZZ]] is invalid structure
 
On the picture above you have brackets inside another set of brackets that is invalid with logix
XX[YY[ZZ]] is invalid structure

Contr_Conn is right. If you want to use the embedded mathematical expression then you need to create a stand alone timer that is not a part of an array. Using the accumulator of a timer that is part of an array is not going to work for your indirection whether a mathematical expression is embedded or not. The same goes for a counter. That may not fit exactly with your desire to translate the program one for one, but that is how it is.

If you feel that creating a stand alone timer for this messes you up too much then insert a DIV instruction in front of your MOV and write the result to a standalone DINT (a DINT array element also won't work here) and use the standalone DINT for your indirection.
DIV Timer.ACC 1000 POINTER_TAG MOV DATA DATA_ARRAY[POINTER_TAG]



I understand you are feeling the crunch to complete this project. But you could actually save yourself some time if you allow some flexibility for a few common sense deviations from the old code that take advantage of the CLX features and power - the use of periodic tasks being one of those.
 
Last edited:

Similar Topics

Hi. Do anyone know if there are exist any supplier of ready-to-use load-cell and display units, calibrated with certificate and all ? I have...
Replies
11
Views
3,291
Hello everyone i m using codesys with wago modules,i have 1 output module and i give power with cables to input(8 output,8 input)i try to make a...
Replies
10
Views
3,304
Does anyone knows how to upload code from a G&L Electronic, PiC0 controller? It has an ethernet port for comm. What kind of software would I...
Replies
2
Views
1,376
Hi all - I have a project where I will replace a GE Fanuc PLC, with Allen Bradley hardware. This PLC looks very old and I do not know much about...
Replies
8
Views
3,921
Apologies for abusing this forum for this, but I am running out of options. Has anyone contacted Comptrol Technologies Inc (Burlington, Ontario)...
Replies
5
Views
3,574
Back
Top Bottom