In order to use ejector module in driver settings dialog items
"Line counter" and "Ejector control" must be
checked. "Ejector control" can be checked only for one
camera (if several cameras are used).
Those settings mean that:
driver will listen for commands for the ejector device.
The ejector commands will be synchronized with the current chunk
counter value.
The work flow for the ejector module from Scorpion perspective is
as follows:
- The frame is captured by camera, retrieved by Scorpion, and
inspection is done.
- After frame is grabbed a tool or script extracts the chunk counter from
the frame
- Based on inspection results the tool/script generates
data matrix for the ejector device
- The tool/script sends the generated data to the driver. The data sent
must refer to the chunk counter position forward by at least 1 frame
(frame length = height / Lines per trigger). When frame is captured
the real chunk counter in the driver will be positioned at the end of that frame (i.e.
the difference between counter embedded in the image and the current
value will be size of one frame in chunks) therefore commands must
be sent for the "future" chunk counter positions.
- Goto 1
Calculate conveyor length
Conveyor length should be measured in chunk counter units and
should not exceed 10000 (e.g. if lines per trigger is set to 20 then
it will be equal to 200 000 image lines).
Snippet below shows how to calculate conveyor length of 2.3 frame
lengths:
camera = GetCamera("0")
lineCounterResolution = camera.getProperty("LineCounterResolution")
imageHeight = camera.height
linesToEjector = int(imageHeight * 2.3)/lineCounterResolution
Extract Chunk Counter From Image
Each frame will have a chunk counter embedded as the 1st 3 bytes
of the image (3 pixels for B/W and 1 pixel for color).
Snippet below shows hot to extract chunk counter:
startIndex = ejectorModulePlugin.GetEjectorModule().GetImageLineCounter(Image)
Generate Ejector Data and Send To
DriverEjector data is sent via driver. Call setProperty method for
camera with following parmeters. The property name must be a formated
string. The format is as follows:
EjectorLine $chunkCounter $data
$callback $mask
where:
$chunkCounter
- must be a chunk
counter value for which data for the ejector device will be sent.
Integer value (example: 7238)
$data
- is 4 byte hex formated
data for the ejector device. It is represented as hex string of length
8 chars (Example: 010AFFFF). This means, that 4 ports are supported. All
port values are interpreted left to right (in the example above - port 0
will have value 01, port 1 = 0A, etc.). Each bit in the bytes
represent 1 output for the ejector device.
$callback - 0/1 - one character for callback to Scorpion when ejector command is
executed - OPTIONAL
$mask - 4 byte hex bitmask for which bites in data to use - OPTIONAL
Example 1: Set ejector output lines to a defined value
when chunk counter = 7238:
camera.setProperty("%s %d %s" % ("EjectorLine", 7238, "010AFFFF"), 0)
Example 2: Set ejector output lines to a defined value
when chunk counter = 7238, use two bits only by mask:
camera.setProperty("%s %d %s 1 %s" % ("EjectorLine", 7238, "00000001"
"0000003"), 0) #uses 2 last bits only
camera.setProperty("%s %d %s 0 %s" % ("EjectorLine", 7245, "00000000"
"0000003"), 0) #uses 2 last bits only
Example 3: Activate all ejector outputs after
conveyor moves 2.3 frames:
dword = 0xFFFFFFFF
startEjector= startIndex + linesToEjector
for i in range(startEjector, startEjector + (imageHeight / lineCounterResolution)):
# send line to a camera driver
camera.setProperty("%s %d %.8X" % ("EjectorLine", i, dword), 0)
Ejector Static Mode
In static mode ejector continuously transmits the same eject command. To
activate static mode use EjectorStaticMode
property:
camera.setProperty('EjectorStaticMode', 1)
To set static mode ejector command call setProperty for camera in following format:
EjectorStaticCommand $data
Example 4: Activate Static Mode
camera.setProperty('EjectorStaticCommand EFEFEFEF', 0)
camera.setProperty('EjectorStaticMode', 1)
Example 5: Generate ejector pulse and process ejector command callback
def SetEjectorPulse():
'''
sets ejector pulse in Basler driver
we requests a command callback for first line set
'''
pixelsize = GetFloatValue('Cal.PixelSize_x')
ejectdist = GetFloatValue('ProcessSetup.EjectorDistance')
pulselen = GetFloatValue('ProcessSetup.EjectorPulseLength')
start = GetIntValue('Results.ChunkCounter')
x = GetFloatValue('Results.TopCenter_x')
camera=GetCamera("0")
lineCounterResolution=camera.getProperty("LineCounterResolution")
if lineCounterResolution==None:lineCounterResolution=1
ejectpos = start+int((ejectdist+x)/pixelsize/lineCounterResolution)
length = int(pulselen/lineCounterResolution/pixelsize)
if not GetBoolValue('System.CameraSimulation'):
prop0 = '%s %d %s' % ('EjectorLine',ejectpos,'00000001 1 00000001')
prop1 = '%s %d %s' % ('EjectorLine',ejectpos+length,'00000000 0 00000001')
#print '--->> SetEjectorPulse: %s %s' % (prop0,prop1)
camera.setProperty(prop0, 0)
camera.setProperty(prop1, 0)
#add the command to send to PLS on command callback
rs232queue[ejectpos]=('rs232cmd',GetStringValue('Results.RS232'))
def Handle_System_CameraCommand(Camera,Cmd,Params):
#
# Camera = VT_BSTR
# Cmd = VT_BSTR
# Params = VT_BSTR
#
#print "<<--- CameraCommand ",Cmd,Params
if Cmd=="EjectorLine":
line=int(Params)
if rs232queue.has_key(line):
rs232cmd=rs232queue[line]
ExecuteCmd(rs232cmd[0],rs232cmd[1])
del rs232queue[line]