Keywords for a google search about the subject: Data buffering, buffering, queue implementation, FIFO buffer, ...
Lately I come across similar questions about buffering mechanism in automation engineering forums. I've already written a simple introduction to this problem two-three months ago in Turkish. When I see the same question in linked-in, I wanted to translate this blog into English...
The very first introduction is to understand when to decide to use a buffering mechanism.
Assume, there is conveyor and a camera is evaluating parts on the entrance of this conveyor. At the end of the conveyor, there is a gripper to pick&place the incoming parts, and a boxer is taking out the defected products out of the converyor belt. To make it simple, lets assume that any two parts gap distance is fixed. So a conveyor with a limited length can carry a fixed number of parts. Which can simply be calculated as;
iMaxPartNumberOnConveyor := iDistanceBetweenCameraAndConveyorEnd / (iPartLength + iGapLength);
So our buffer should have at least that much empty cells...
I think it will be more clear to describe the solution with some drawings...
Then you may also read the following pseudo-code, in ST language.
If you have further questions, feel free to ask.
The very first introduction is to understand when to decide to use a buffering mechanism.
Assume, there is conveyor and a camera is evaluating parts on the entrance of this conveyor. At the end of the conveyor, there is a gripper to pick&place the incoming parts, and a boxer is taking out the defected products out of the converyor belt. To make it simple, lets assume that any two parts gap distance is fixed. So a conveyor with a limited length can carry a fixed number of parts. Which can simply be calculated as;
iMaxPartNumberOnConveyor := iDistanceBetweenCameraAndConveyorEnd / (iPartLength + iGapLength);
So our buffer should have at least that much empty cells...
I think it will be more clear to describe the solution with some drawings...
Then you may also read the following pseudo-code, in ST language.
R_TRIG_PartSensor(CLK := DI_PartSensor);PartDetectedPulse := R_TRIG_PartSensor.Q;(*part recording to buffer*)if PartDetectedPulse then(*record position to buffer store cell*)Buffer[StoreCell] := ConveyorPosition;(*increase store cell, if buffer size reached then store to the first buffer cell (circular buffer)*)if (StoreCell < (Buffersize - INT#1)) thenStoreCell := StoreCell + INT#1;elseStoreCell := INT#0;end_if;end_if;(*part reading - to give an idea how to do it, several needs can cause a part read. For instance; if the part passes over the minimum working area...*)R_TRIG_ReadPart(CLK := ReadPart);PartReadPulse := R_TRIG_ReadPart.Q;if PartReadPulse thenif NOT (StoreCell = UseCell) then(*Get part position *)PartPosition := Buffer[UseCell];(*increase UseCell, if buffer size reached then store to the first buffer cell (circular buffer)*)if (UseCell < (Buffersize - INT#1)) thenUseCell := UseCell + INT#1;elseUseCell := INT#0;end_if;else(*warn user*)NoPartInBuffer := TRUE;end_if;end_if;
NOT: Code seems better in notepad++ ;)(*delete user warning*)if not ReadPart thenNoPartInBuffer := FALSE;end_if;
If you have further questions, feel free to ask.
Hiç yorum yok:
Yorum Gönder