Trigger by encoder suggestions

20,000 cycles per hour, that's 20,000 of 20 inch moves?
Interesting.

You are very likely to have too much cumulative error with even 10% of that volume.

Set the encoder resolution to its highest, set it up for circular counting. On first configuration(operator pressing the button) grab the current counter value and add the goto value and that is your target/trigger count which you feed to HSC as reference/compare value.
The reference value= current count event will generate hardware interrupt in which you trigger the camera "and" grab the current count to setup the next position (in regular scan).

Verification and adjustment for rollover maybe done in regular scan and so is calculating the next position and loading it to HSC.

Putting a sensor ahead of the camera would be the best approach for precise positioning. Every trigger of the sensor loads current count and sets ups the counter as described above; the error, and there always is, would negligible that it would be hard to detect by eye.
 
20,000 cycles per hour, that's 20,000 of 20 inch moves?
Interesting.

You are very likely to have too much cumulative error with even 10% of that volume.

Set the encoder resolution to its highest, set it up for circular counting. On first configuration(operator pressing the button) grab the current counter value and add the goto value and that is your target/trigger count which you feed to HSC as reference/compare value.
The reference value= current count event will generate hardware interrupt in which you trigger the camera "and" grab the current count to setup the next position (in regular scan).

Verification and adjustment for rollover maybe done in regular scan and so is calculating the next position and loading it to HSC.

This process is similar to the machine I'm working on: https://youtu.be/J4dXlr_77GM

I will look into your suggestions today, thanks a lot so far everyone!
 
Here is another approach:
Code:
trig := (lastPV <  trigPV AND trigPV <= currPV)
     OR (currPV <  lastPV AND lastPV <  trigPV)  (* currPV wrap; trigPV ~ max *)
     OR (trigPV <= currPV AND currPV <  lastPV); (* currPV wrap; trigPV ~ 0 *)
 
lastPV := currPV;
Not as concise perhaps, but it does not involve detecting the encoder counter via the range [trigger:trigger+DELTA), and therefore does not need to determine an empirical value of DELTA.

This approach was inspired by @Peter Nachtwey's base algorithm, although this code should correctly detect all trigger-PV crossings as long as the scan time is less than one Z-cycle, while that base algorithm could miss 90%+ of the trigger events; cf. the attached, admittedly coarse, but reasonable, model.

N.B. lastPV should be initialized to trigPV, to ensure no false detections on the first scan.
 
This process is similar to the machine I'm working on: https://youtu.be/J4dXlr_77GM

I will look into your suggestions today, thanks a lot so far everyone!


Thanks, that helps.


If the conveyor speed and product position is precise, as the video seem to indicate, I would consider not putting a sensor ahead of the camera. Everything else stays the same, high encoder resolution, the counter setup for circular counting, not resetting, and just keep adding positions and loading them into HSC. You will have between 5-6 interrupts per second based on the numbers you posted above; that won't add much at all to your scan cycle.


I'm curious who long does the camera need to be on for and is that controlled by the PLC output/trigger or is it integrated in the camera.



Let us know how it eventually turns out and if you have a chance to test more than one approach that would be great feedback.
 
If I was doing it in software I wouldn't reset the counter every Z pulse, I would let the counter keep counting and store the value at each trigger point, then compare current value plus trigger value to the target value. Using the Z input to check that the encoder is counting correctly.

Bryan, could you explain how one would do this? I experimented with an on going counter which solves a few of the problems I had, only it doesn't stay in sync.
Every trigger I add a 1000 pulses to the triggerv reference value for the next trigger, but that way it slowly runs out of sync.

I'm trying to find out how to use the Z pulse to keep the pulse counter in sync but I could use some info about it.

Thanks in advance.
 
Bryan, could you explain how one would do this? I experimented with an on going counter which solves a few of the problems I had, only it doesn't stay in sync.
Every trigger I add a 1000 pulses to the triggerv reference value for the next trigger, but that way it slowly runs out of sync.

I'm trying to find out how to use the Z pulse to keep the pulse counter in sync but I could use some info about it.

Thanks in advance.


I am also interested in Bryan's answer.


And the way you described how you are setting up the trigger counts is similar to the way I suggested which is to grab the current value and add the goto count to it, is a *bad* idea. It came to me then and hoped you did not consider it.
My suggestion exactly creates cumulative error.

Setting up the trigger counter value in the interrupt is pointless specifacally for the reason that you only have one sensor trigger at the beginning of the line (as I recall) and the spacings between the parts are exact and identical.
In that case I would just create a table (array or whatever you want to call it) for all upcoming camera trigger counter value.

Sensor trigger caputered the counter at 10 than its 10+1000,+1000,+1000,+1000 etc.


If you have a sensor detecting the product before each camera then my suggestion would've worked.


Hwo are you calculating for rollover.
Edit: to clarify a subtle but important point.
 
Last edited:
Every trigger I add a 1000 pulses to the triggerv reference value for the next trigger, but that way it slowly runs out of sync.


This will only work if the parts to be imaged are exactly 1000 pulses apart.


Are they 1000 pulses apart? If not, how many pulses apart are they?
 
I am also interested in Bryan's answer.


And the way you described how you are setting up the trigger counts is similar to the way I suggested which is to grab the current value and add the goto count to it, is a *bad* idea. It came to me then and hoped you did not consider it.
My suggestion exactly creates cumulative error.

Setting up the trigger counter value in the interrupt is pointless specifacally for the reason that you only have one sensor trigger at the beginning of the line (as I recall) and the spacings between the parts are exact and identical.
In that case I would just create a table (array or whatever you want to call it) for all upcoming camera trigger counter value.

Sensor trigger caputered the counter at 10 than its 10+1000,+1000,+1000,+1000 etc.


If you have a sensor detecting the product before each camera then my suggestion would've worked.


Hwo are you calculating for rollover.
Edit: to clarify a subtle but important point.

This will only work if the parts to be imaged are exactly 1000 pulses apart.


Are they 1000 pulses apart? If not, how many pulses apart are they?

In one machine cycle the encoder does one revolution. Mechanically all shafts including the encoder stay in sync, but without a zero reference

I can inmagine that in let's say a thousand scans, a few pulse counts will always be missed. For example a high input state during a certain part of the plc's scan where it's not detected.
 
Hwo are you calculating for rollover.
Edit: to clarify a subtle but important point.

Code:
FOR loop0:= 0 TO 4 DO
	
	IF hs_cntr_pv >=encVal_array[loop0] THEN 
		
		trigger_array[loop0]:= TRUE; [COLOR="Red"](*set trigger output*)[/COLOR]
		encVal_array[loop0]:= (hs_cntr_pv +pulse_per_rev); [COLOR="Red"](*set next trigger at (current pulse count +one revolution)*)[/COLOR]
	END_IF;
	
	IF hs_cntr_pv >=encVal_array[loop0] -(pulse_per_rev /2) THEN 
		trigger_array[loop0 +1]:= FALSE; [COLOR="Red"](*reset trigger output after 1/2 revolution*)[/COLOR]
	END_IF;
END_FOR;
 
Last edited:
OK, so I haven't thought about this since January, so forgive me if I repeat myself, or get confused, or cause confusion, or if I explain things too simply.

An Interrupt tells a device to stop what it is doing, run another bit of code, then pass control back to the main program. The 'another bit of code' should be as short as possible.

PLCs can usually be programmed with a range of Interrupts, Interrupts can be called by external signals such as a change of state of an input, or by PLC internal values, a timer reaches a set point, a high speed counter (HSC) reaches a set point, a high speed counter changes direction, a message is available on a communications port, plus others.

I am suggesting that you use two Interrupts, one internal to the PLC, triggered by the HSC reaching a set point, and an external rising edge signal which is the Z output from the encoder.
First just look at the HSC at Set Point Interrupt, it is called when the HSC reaches a Set Point but there is nothing that says the set point has to be the same value for every Interrupt, you can calculate a new set point every machine cycle. I don't know how you set the machine to a start point, but whichever control method you use, you will always need a know start point. The Operator enters a Set Point (OP_SP), and presses a Start button. The PLC reads the current HSC value (HSC_Initial) and adds it to the OP_SP to give the High Speed Counter a first set point. You pass this start value to the HSC Interrupt, then you start the machine moving. At some point there will be an Interrupt raised when the HSC reaches the set point. Within the HSC Interrupt you grab the HSC current value and add the OP_SP to that value to calculate the next Set Point for the HSC. (see note 1). And keep doing that every machine cycle, the HSC counter will keep increasing in value.

On to the encoder Z output PLC rising edge input Interrupt (Z_INT). Encoders can go faulty and stop giving out the right number of pulses per revolution. It is very useful to be able to spot the error and raise a fault on the machine. So with the Interrupt called by Z_INT you read the current HSC value Z_CURRENT and subtract from it the last value (Z_LAST), the calculated value should be the number of pulses per rev of the encoder. If not, raise a fault. The first value will always be wrong, so discard it. On the machines I work with a small error isn't a problem, so I don't raise an alarm unless the error is outside of the 'small'. If you want to be a real smarty pants you can adjust the Operator Target by the error value to try to keep the machine running. But from experience once an encoder starts to go faulty it rapidly fails completely.

Note 1
Depending on how quickly the encoder pulses are received there is a chance that another pulse will have been received by the HSC, in which case you have to compare the Set Point to the HSC current value and adjust the new Set Point by the difference.

I hope I have explained that well enough, if not I don't mind questions :).

B
 
Originally Posted by drbitboy
This will only work if the parts to be imaged are exactly 1000 pulses apart.

Are they 1000 pulses apart? If not, how many pulses apart are they?
In one machine cycle the encoder does one revolution. Mechanically all shafts including the encoder stay in sync, but without a zero reference

I can imagine that in let's say a thousand scans, a few pulse counts will always be missed. ...
Ah. The penny drops.

Let me re-state my query and statement more explicitly:
This will only work if the parts to be imaged are exactly 1000 detected pulses apart.

(1) Are they 1000 detected pulses apart?

(2) If not, how many detected pulses apart are they?
The following assumes, from OP's latest statement in bold red above, that the answer to (1) is apparently "No," or at least "Not always," and that the answer to (2) is apparently "We don't know."

All computer programs are models of something, typically something in the real, physical world. The primary design choice to be made when writing a program is choosing that model's level of fidelity; all subsequent design decisions flow from that primary choice.

If "a few pulse counts will always be missed," then OP's problem is not with the code, it is with the assumption OP's code makes, i.e. the assumption that the PLC's encoder counter data values provide the PLC with an adequately accurate model of the physical process it is monitoring and controlling.
Sidebar: it seems odd that a high-speed counter (HSC) cannot keep up with the hardware encoder, because avoiding that problem is usually the reason for using an HSC. Aren't there usually filters and other settings for the HSC to tune it for the particular signals the HSC is detecting and counting? Or am I misunderstanding OP's statement in bold red above?
However, if it is indeed the case that the HSC is missing pulses, then OP's problem is ultimately with the hardware, and the best solution is to solve that problem.

If the hardware problem cannot be resolved, then the poorer, but sometimes necessary, alternate choice is to characterize the actual encoder behavior and model this drift in the PLC program. Such an approach is described in @BrianG's latest post.

Again, this all assumes the pulses are being missed in the HSC; if the OP was only saying that the PLC scans do not see every counter pulse, then that can be dealt with in the program via algorithms provided earlier.
 
Last edited:
OT: bad models

P.S. I was in a perhaps somewhat similar situation a decade and a half ago: the data specification for the Deep Impact spacecraft clock quoted a microsecond sub-second counter, which I assumed meant 1,048,576 (2**20), not 1,000,000, counts per spacecraft-measured second (i.e. bad model ;)).

We eventually fixed it, see the statement "corrected the interpretation of ... clocks ... errors of about 40 milliseconds" in this document.
 
Code:
FOR loop0:= 0 TO 4 DO
    
    IF hs_cntr_pv >=encVal_array[loop0] THEN 
        
        trigger_array[loop0]:= TRUE; [COLOR=Red](*set trigger output*)[/COLOR]
        encVal_array[loop0]:= (hs_cntr_pv +pulse_per_rev); [COLOR=Red](*set next trigger at (current pulse count +one revolution)*)[/COLOR]
    END_IF;
    
    IF hs_cntr_pv >=encVal_array[loop0] -(pulse_per_rev /2) THEN 
        trigger_array[loop0 +1]:= FALSE; [COLOR=Red](*reset trigger output after 1/2 revolution*)[/COLOR]
    END_IF;
END_FOR;
Thanks andepand.


Judging by your FOR loop, you are setting the triggers (multiple) in program scan. You are not using HSC hardware interrupt for counter value = reference value. In that case you have to bear in mind the speed of the line/pulses vs. the duration of program scan. How many pulses does the counter counts from the time your code reads the counter value and evaluates it till the time it updates the outputs?

You stated a line speed of 20,000 parts per hour and the distance between parts is 1000 Pulses which is equivalent to one encoder revolution. (These are amazingly *square* numbers).
That would give you roughly 5 pulses per millisecond.
What is you scan cycle?


Note: My question with regard to "rollover" was with regard to counter rolling over from maximum value to start value and how you accounted for that. But at this point I am aware that your program implementation is not what I thought it was. So the question may or may not be important.





At some point there will be an Interrupt raised when the HSC reaches the set point. Within the HSC Interrupt you grab the HSC current value and add the OP_SP to that value to calculate the next Set Point for the HSC. (see note 1). And keep doing that every machine cycle, the HSC counter will keep increasing in value.


Note 1
Depending on how quickly the encoder pulses are received there is a chance that another pulse will have been received by the HSC, in which case you have to compare the Set Point to the HSC current value and adjust the new Set Point by the difference.


Bryan, that will have cumulative error, at the speed the line is going, and I do not see the benefit of updating counter current value when there's no reference point. There's only one trigger at the start of the machine and that's it. If the counter value is not what it is supposed to be , mathematically, then everything that follows from that will also be off.
The system relies, entirely, on everything (conveyor, product,camera position,encoder) being exactly where they should be at all times; whether that is a fact of not is a different matter.
(by the way that was what I suggested and later realized was a bad idea so I'm diffidently contradicted myself )
 
P.S. I was in a perhaps somewhat similar situation a decade and a half ago: the data specification for the Deep Impact spacecraft clock quoted a microsecond sub-second counter, which I assumed meant 1,048,576 (2**20), not 1,000,000, counts per spacecraft-measured second (i.e. bad model ;)).

We eventually fixed it, see the statement "corrected the interpretation of ... clocks ... errors of about 40 milliseconds" in this document.


You worked with spacecrafts, what the hell are you doing here? :ROFLMAO:
 

Similar Topics

I am running into some problems trying to trigger a camera to take a picture every 15 degrees when I spin the part I am looking at one full...
Replies
6
Views
3,624
Hi i would like to ask! Im using Omron CP1E PLC May i know how to use one input to trigger two outputs alternatively? Meaning press X0 on, Y0...
Replies
11
Views
399
Hi all, I use e won for my OPCUA to back up my PLC (B&R X20 system) data. Whenever e won does maintenance updates, I need to reboot the e won in...
Replies
2
Views
477
Hello ladies and gents I’ve hit a road block on a project, it’s AB for preface this is a converting line including Winder tailsealer and...
Replies
4
Views
772
Hi, I'm using CX Programmer and just seeing what the best way to trigger an output from the plc clock time would be. I need this to come on at 9am...
Replies
4
Views
1,742
Back
Top Bottom