Simple XY movements using FWD RE and stop commands on each axis

SonusI

Member
Join Date
Oct 2023
Location
Dalmatia
Posts
18
Hi all! I am using unitronics Unistream plc, controlling two axis X and Y of polishing machine. Control is very simple as I have movement in each direction one by another. So to say I go 100 cm in X than 11 cm Y, than again back 100 in x etc..... I did this by having greater or equal or less then equal block and checking when value from counter reaches value, motor stops and activate another axis and same way. It is working , but thing is when for example someone needs to change movement direction i need to change complete LD block......or made few , so for each movement pattern.

I was thinking maybe to implement arrays and to fill array with cordinates and when X starts from 0 it reads array 0 where max count number, direction etc are store and next step, so when it reaches it moves to array 1 where again, next step are stored....and so again.

Or if someone had better idea/approach I am open to suggestions, i working with unitronics unistream plc, but idea can be implemented from other too.

Also, we have 32 pulses per each cm of movement, but this is not servo or so, as precision is not key factor, where +/- 2 cm is great. in my approach now I am satisfied with it, but as I say, I would like to get it more flexible, than full LD with bunch of great or equal compare blocks......plus setting/reseting many coils on each rung so that plc knows what to do after it count to end of each movement.
 
An array is certainly the way to go unless you have some form of other system like CAD that can produce the points & export them, the one thing is depending on what this pattern is going to be i.e. like drawing as a plotter then it does become complicated, however, it appears you are just moving in X direction, then y, then -x back to 0,Y so a 2 dimentional array should be ample.
however, if the x & y are the same for every operation then there is only 2 X positions (from 0 to X) & (from X to 0), in the y direction only 1 i.e. it is multiple of first Y distance plus current position
so you could have X movement constant for example 400mm.
Y constant 50mm
Z number of strokes (for example if piece to polish is 200mm wide & each Y increment is 20mm then y is just incremented by 20mm until it reaches 200.
In that case for each recipe you only need
X start position
X finish position
Y start position
Y end position
Y increments (obviously some relationship with polisher head size).
Maybe X & Y start position is always 0 but if not then the 4 variables above in some sort of recipe selection be it stored on an HMI or stored in PLC memory.
If my understanding is correct theren it is pretty simple, I did something similar on a glue applicator, it was for some pre-cut shape, however, there were two operations like yours depending on size the glue gun did a reciprocating stroke on left side, then one on the bottom trailing edge of the shape.
 
Welcome to the world of Object-Oriented Programming (OOP or just OO)!

The key concept is separation of

  • the code
    • what the PLC does in general
      • e.g. make moves along X and/or Y axis
  • from the data
    • what it does in a specific instance or at a specific time
      • the actual X and Y movements as cardinal numbers
      • the designation of the specific instance
        • e.g. the current step number represented as the current value in your counter, or
        • a time
So in your case, there is a two-dimensional array, which is like a table with two columns and some number of rows. The first dimension (e.g. columns in the table) indicates the axis: the first column model movement along the X axis; the second column models movement along the Y axis. The second dimension (e.g. rows in the table) represent steps, that is individual single movements, in a larger series of movements. The row number is analogous to the value of the accumulator in your counter.

The advantage to such is a system is that the code to execute a single X-Y movement need be written but once, and that same code can be re-used for any number of movements, because a single value i.e. the accumulator of the counter, which is also the table row number, models the step and can be used by the code to look up the details of the move. So by separating the hard-coded move's immediate values ("+100" for X; "-100" for Y) from of the move logic ("code") and replacing it with the row number of a table ("data"), a simple modular piece of code, which reads a table row and performs the single move described in that row, can be used to perform a complex, user-configurable sequence of many moves.

Even better, separating the code and the data makes enhancement much easier as well. For example, say the user, in addition to specifying the moves, a some point wants to control the device speed of each move. That can be done by

  • adding a third column to the table
    • increasing that dimension of the array from 2 to 3
  • providing a way for the user to write to that third column
    • which is trivial because they can already write X and Y values to the first two columns
  • modifying the code to read the new column and use that when making the X,Y move indicated in the other columns.
I have a friend who says the first thing he does when he starts programming for a new process is to design a database apropos that process. Because almost all computer, and especially PLC, programs are a model of a real-world process.

The primary design choices of that model revolve around the level of fidelity. For example, you have a process where the process can position a device along two axes by sending pulses. Thirty-two pulses will move the machine by 1cm. Since a pulse is a series of discrete (atomic) transitions, 0 to 1 then back to 0, there can be no fractional pulses. So the smallest movement, which is the highest fidelity, in this model is 1/32 of a cm; there is no way to move the device by 1/64 of a cm.

Another part of choosing a level of fidelity involves aspects of the process that are not modeled. As a silly example, your program does not need to model the color of the operator's socks.

There is no such thing as an OO programming language, only OO programmers.
 
Thanks both for replays, and yes, key is to separate code and data. At first, this should be some simple movement routing, where, when installed users started to have ideas, can that done that way, this way, etc...... Making routing for each wish is possible, and calling it when needed. It works, but, but, as you both pointed out, it rely complicates code and speed of process (even cpu's are so fast that that is not even noticed).

I know how to make array or in unitronics now they have DataTable (similar to array, only there are some offline update possibilities).

In practice, when I fill array, for example operator chose two points and i calculate data for array from there (X,-X, Y, -Y, Y move , X move etc) should i have for example counter and trigger array data for each finished move? For example I start X move and when counter stops X, i trigger array 1 and read data, where it says start Y move , and then next next etc...? Or there is better approach to this?
Maybe array with FIFO where I would just trigger table based either or X or Y axis end trigger (when it reaches end of couting - end position)?
 
It was a long time ago when I did the glue spray system but it was pretty simple, the x movement was constant for that particular product in other words each product was sort of square or oblong of different sizes, so we had recipes in the HMI, a product code was picked & loaded into the running recipe.
The recipe had the following (bear with me on this difficult to remember exactly).
X position: only needed one as it always went from Home (0) to a set position depending on the recipe loaded.
Y Finish position: this was the last movement of the Y position i.e. the last stroke.
Y Step position: this was the amount to move in the Y direction each stroke.
Speed: this determined the speed of movement.
If I remember correctly, there was at least two more, these being the X start spray position & Y start position for the spray to start, however, I believe these were eventually set at fixed values as the bottom left corner of the part was always in the same place
Pretty simple really.
so the current recipe array was only
X finish Position
Y Finish position
Y Step position
Speed (both drives were set at same speed so only one speed required).
Originally, the recipes were held in the PLC retentive memory, however, over time the limited memory & increase in recipes (types of product) meant we upgraded the HMI which had more storage for the recipes.
 
Are the X and Y moves all relative moves? Because if they are, then an array with two columns is all that is needed. If a move has the device moving only along the X axis, so there is not movement along the Y axis, then putting a 0 as the move along the Y axis would accomplish that i.e. inhibit movement in Y.

E.g. the data for a 10-unit square move sequence, which starts at the bottom left and goes counter-clockwise assuming +X is right and +Y is up, would look like this:

Step ∆X ∆Y Comment
==== == == =======
0 +10 0 Move Right to (10,0)
1 0 +10 Move Up to (10,10)
2 -10 0 Move Left to (0,10)
3 0 -10 Move Down return to origin (0,0)


By designing the data "table" to have both X and Y moves at every step, this allows the user to specify alternating moves in X and Y for each step, but also leaves open the possibility of simultaneous moves in X and Y in a single step in the future. E.g. an "hourglass" path would look like this:

Step ∆X ∆Y Comment
==== == == =======
0 +10 0 Move Right to (10,0)
1 -10 +10 Move Left and Up to (0,10)
2 +10 0 Move Right to (10,10)
3 -10 -10 Move Left and Down return to origin (0,0)


 
I would like to have absolute moves, because that way error will not become bigger (acconulated) with repeating moves.

In this system biggeet error is because when counter valute is reached it won't stop on that exact location, but few count in that direction, which is acceptable. But, if i count another move from that location starting from 0, than when axis is back i will have that location + error in few count while stopping. Instead i would always like to refer all moves count to zero position because that way errro would always be eqal and same, which is ok. For example, if i need to move X for 100 counts forwars and than y 10 and X back 100. I go fwd X for 100 and stop will be maybe 105, and when counting back i will not move for 100, but i will move untill 0 is reached, same with forwars, i will not move for 100, but untill 100 is reached. So in array i would actually put end values for axis. I
 
I would like to have absolute moves, because that way error will not become bigger (accumulated) with repeating moves.

...
I understand.

Does the "command" from the PLC to the positioning device use an absolute position, and the positioning device always ends up ±5 of the commanded absolute position?

Or is there feedback from the positioning device to the PLC, so that after the ∆X = +100 move from X = 0 and the ∆Y = +10 move, when the PLC wants to move back to X = 0, the PLC "knows" the device is actually at absolute position 105 instead of the targeted absolute position 100 from the first move?

Either way, the array or table approach will still work, it only changes how the PLC calculates the move. With absolute positioning, if the ∆Y move is 0, then the absolute Y position will be the same value before and after the move e.g. the square move sequence would look like this:

Step X Y Comment
==== = = =======
0 +10 0 Move Right
1 +10 +10 Move Up
2 0 +10 Move Left
3 0 0 Move Down


 
The trouble is expecting it to go to 0 it may still be out for example if it missed pulses, the usual way is to have home sensors in the home position, so rather than count to 0 (still can) but when it reaches the sensor(s) X & Y then you re-zero the position counts that is what most systems do.
It is simple
Move from home in X pos until X is reached, move Y by increment, Move x back to 0 & sensor re-calibrates to 0.
repeat until Y position => Y max then when X at 0 move Y back to home position & re-calibrate on sensor, that way you will always have the 0 point.
 
I have home routine done also. When machine is powered on it goes to -X and -Y max until it reaches limit switches, than it goes forward for some distance and stops, that is 0,0 point where counter is reset. On both axis drive shaft I have 8 pulses per rotation encoder done by high speed proxy switches which are counting and that is done very good and is not missing pulses. So I am always moving axis by counting pulses and stops when count is reached. That way if I always miss +/-5 pulses i always stay in that range. Since unit is working now, even when is working for 2 hrs it always stay at given limit, which is great! Now, task is to implement array in LD app :D
 
...That way if I always miss +/-5 pulses i always stay in that range. ...


By "always miss ±5 pulses" I assume you mean "always place axis within ±5 pulses of absolute position target."

So it sounds like the PLC is sending commands to move forward or backward, and keeping track of the absolute position by the encoder prox pulses (quadrature encoder?) feedback to the PLC.

So after several cycles, if the PLC thinks the X absolute position is -5, and you wanted to move to X absolute position +100, you would send some command(s) to move forward (increase X), all the while counting encoder pulses as feedback, until that incremental count since the start of the move gets to ~105 (or even 100 or 102), so an absolute position mode of 100 (or even 95 or 97), and at that point you would stop the forward motion command(s), but still keep counting pulses as the device coasts to a stop, at which point the absolute position, as modeled by the PLC, would be somewhere between 100 and 105.

Is that roughly correct?
 
Last edited:
PLC output to VFD are only forward and back (it has MODBUS RTU also, but for error, speed set etc).

Feedback is quadrature encoder with 8PPR. So, PLC is always keeping track where axis are. For example if machine is on 0 and need to go to 100, than PLC send logic signal to VFD to go FWD and waits untill it reach desired couting number, PLC stops vfd, but axis will not stop there, but few counts forward, for example at 103 or 105 (either are error in just few mm). When PLC sends signal to axis to go back to 0, it will count until 0 and will stop it when it reaches 0, axis will stop maybe at -2, -5....
So, i always have error few counts -start position and few counts +end position.

In case of increment counting, then if i would stop for example at 105, then in reverse PLC would stop vfd at 5. Axis would stop at 2 for example, next step, axis would count up to 102, stop back at 5, then next step count up to 105 etc.....distance would always be 100, but start and end position would be moved.

Anyway, I am very satisfied with result now. Only to implement array, need to figure out how to implement it in unitronics. Either i will trigger table with start command and use as index (read out data) or trigger it with stop function. So every time when axis reach end position and PLC stops it, than that it reads parameters for next move!?
 
... So every time when axis reach end position and PLC stops it, than that it reads parameters for next move!?


Exactly. The only complication will be that, when moving forward, the code will terminate

  • EITHER the FWD command when the encoder feedback position reaches or exceeds the target position,
  • OR the REV command when the encoder feedback position reaches or is less than the target position.
So the program will need

  • A Start/Stop Circuit pattern (see here) for the FWD command bit
  • Another Start/Stop Circuit pattern for the REV command bit
  • Some sort of one-shot logic that detects when a new row of the table is active, and that will trigger either a FWD or a REV command, again on a single scan cycle because it is a one-shot;
    • this will trigger
      • EITHER a START_FWD tag as the Start bit of the Start/Stop Circuit pattern for the FWD command bit.
      • OR a START_REV tag as the Start bit for the Start/Stop Circuit pattern for the REV command bit.
  • Logic to trigger the Stop bits of those Start/Stop Circuit patterns
    • actually this can be one rung and one STOP_FWD_OR_REV tag, because an axis cannot be going both FWD and REV at the same time.
  • Perhaps a delay or other logic (wait until positions do not change for 5s) at the end of each step to prevent the next step from starting before all motion from the current step, including coasting (inertial movement) to a stop, is complete.
  • Logic to load, start, increment, and stop a sequence of steps of X,Y pairs from the table/array.
Also note that there should be a deadband around the start conditions to prevent unnecessary movement e.g. if the table looks like this:

Step X Y
==== = =
0 0 0
1 100 0
2 100 10


Say after step 1 is complete that the feedback X position has coasted to, and settled at, a stop position X=105. When Step 2 then starts, the X=100 target would trigger an X-axis REV command from that current position of X=105 to the Step 2 target position of 100. That REV command is possibly unnecessary, so coding a deadband around the target positions might be a good idea.
 
For now, I use greater or equal to or less than or equal too. So when X position count is reached great or equal block reset X FWD coil, and SET Y fwd for untill Y is reached, then again depending on pattern. So basicly for RUN FWD OR REW i use SET/RESET coils on PLC. So i think i can use same with array. For example i can trigger array and read row, in case in row target is less than current position then command is REW and opposite if current position is higher than current command is FWD.

As dead band, when patter is done and when X/Y are back to zero, i use some dead band to stop it on zero position.
 
For now, I use greater or equal to or less than or equal too. So when X position count is reached great or equal block reset X FWD coil, and SET Y fwd for untill Y is reached, then again depending on pattern. So basicly for RUN FWD OR REW i use SET/RESET coils on PLC. So i think i can use same with array. For example i can trigger array and read row, in case in row target is less than current position then command is REW and opposite if current position is higher than current command is FWD.

As dead band, when patter is done and when X/Y are back to zero, i use some dead band to stop it on zero position.

I would use the Start/Stop Circuit pattern instead of the Set/Reset pattern, because (i) it ensures nothing is commanded to run when the PLC enters RUN mode, and (ii) it ensures each FWD and REV bit is controlled by one easily understood rung, but that is six of one vs. half a dozen of the other.

I suspect you should be able to start with just your current ladder logic for just one step of the current sequence, and modify it to use elements from the X/Y array (or table) instead of the hardcoded values in the current code.

On each scan cycle calculate the difference, DIFF, between the current measured position, as measured by the encoder's quadrature signal, and the current target position from the array at the current step. That difference will be used to control the FWD and REV output commands.

Say we use a deadband of ±5: any time the current measured position is outside the [current target position ± 5], i.e. when either DIFF > 5 or DIFF < -5, one of the drive command bits' values will become (be set to) 1:
  • EITHER set REV value to 1 if DIFF > 5 (measured > (target + 5)),
  • OR set FWD value to 1 if DIFF < 5 (measured < (target - 5))

In like manner, when the measured value reaches or passes the target value, one of the drive command bits' values will become 0:
  • EITHER set REV value to 0 if measured < target,
  • OR set FWD value to 0 if measured > target

The trickier code will be dealing with the array or table and managing the step number. For example, you may want to ensure there is a pause between one step and the next, so e.g. the motor does not start in a new direction on step N+1 when it is still coasting to a stop in the opposite direction from step N. Also, if the trigger to advance to step N+1 is the falling edge of the last command bit (FWD or REV) transitioning to 0 while on step N, what happens if the device is already within the deadband for step 0, perhaps at the home positions, when the step counter is initially set to step 0 i.e. the motors will not need to run to complete step 0, so there will be no falling edges of the command bits?
 

Similar Topics

Hello, I´m having a problem trying to program in Ladder. An output should be trigged by two possible contacts. Take a look on the printscreen...
Replies
5
Views
170
Hello again..trying something on an existing poorly written program and just wanted to double check something system is an A-B MicroLogix 1200 In...
Replies
5
Views
198
Hi all, Writng a FB in ST on Beckhoff TC for a pulser which turns on and off on a cycle, is paused by turning bControlInput to FALSE, but resumes...
Replies
6
Views
282
I'm trying to build my Classic Step 7 programming skills this weekend. I get stuck on little things that are not covered in YouTube tutorials. I'm...
Replies
7
Views
338
I have a program that does a 7 second "scan" sensor calibration routine whenever a setting (setting is called assistance level or "AL" and ranges...
Replies
3
Views
229
Back
Top Bottom