External Trigger

Hello everybody

I use a Python script to collect images from my cameras. Each time I run the script for both my cameras are taken and saved.
Now I got an external trigger and would like to rearrange my script in a way, that each time the external trigger gives a signal, images from both cameras are made and saved.

here is my current script:

import cvb
import os
import numpy as np
import matplotlib.pyplot as plt
import time

os.chdir("C:/Users/xy/Imagetest/Feldtest")
 
vin_device_RGB = cvb.DeviceFactory.open("C:/Program Files/STEMMER IMAGING/Common Vision Blox/drivers/GenICam.vin",port= 0)
vin_device_NIR = cvb.DeviceFactory.open("C:/Program Files/STEMMER IMAGING/Common Vision Blox/drivers/GenICam.vin",port= 1)

stream = vin_device_RGB.stream
image, status = stream.get_snapshot()
i = 0
while os.path.exists("110219BRGB_%s.tif" % i):
    i += 1
image.save("110219BRGB_%s.tif" % i)
 
stream = vin_device_NIR.stream
image, status = stream.get_snapshot()
i = 0
while os.path.exists("110219BNIR_%s.tif" % i):
    i += 1
image.save("110219BNIR_%s.tif" % i)

I guess I got to integrate something like this, but with “trigger” instead of “exposure”?:

device = cvb.DeviceFactory.open(os.path.join(cvb.install_path(), "drivers", "GenICam.vin"), port=0)
dev_node_map = device.node_maps["Device"]

exposure_node = dev_node_map["ExposureTime"]
exposure_node.value = exposure_node.max / 2

print("Exposure time set to: " + str(exposure_node.value) + " " + exposure_node.unit)

Thanks
Stefan

Hi @stmoe

when you connect an external trigger you have to set the appropriate trigger mode and trigger source in the node map. This is usually set up once and saved to one of the cameras user sets.

As external trigger refers to a dedicated electrical signal your script must perform the following stepps:

  1. start the stream
  2. wait for images
  3. stop the stream once you are done

Please note that triggers are only accepted when the stream is started. As take snapshot performs all three steps in one call it is not usable for triggered approach.

1 Like

Thanks Andreas

Thanks for your Help. So I will set the triggermode in the camera settings and start a script like:

import os
import cvb

with cvb.DeviceFactory.open(os.path.join(cvb.install_path(), "drivers", "GenICam.vin"), port=0) as device:
     
    stream = device.stream
    stream.start()

    for i in range(10):
        image, status = stream.wait()
        if status == cvb.WaitStatus.Ok:
            image.save("110219BRGB_%s.tif" % i)

    stream.abort()

So it works now perfectly for one of my CCD. The trigger gives signals and pictures are stored. But I have two CCD in my camera and the second camera can’t be triggered because I can only stream one sensor at the time. Maybe the trigger should activate the camera on a higher level, where one signal starts the acquisition and makes an image for one CCD ends the acquisition and then makes the same for the other CCD?

Hi @stmoe

not sure if I understood you correctly. In fact you stream from multiple sensors simultaneously.
However before choosing the right consider these two distinct camera configurations:

a) A hardware trigger triggers one sensor and the camera’s internal trigger system triggers the other sensor as well (Master-Slave config).

How to acquire in case of a)

In that case you can simply open two devices, start two streams and wait for the images on each stream in any order you like. The second wait will return immediately as the images arrived synchronously and all the required waiting was done in the first wait.

b) Both sensors run independently from each other. In that case you basically have two cameras within one housing.

How to acquire if in case of b)

Applying method a to such a configuration will cause the faster sensor to loose images at some point. However you can still acquire safely using the following tutorials:

  • StreamingParallel
  • StreamingAsync

Both methods do the same job. The first one uses dedicated native threads and the second uses an event handler.

1 Like

Thanks Andreas

It is case a. Everything works fine now.
Here is my code if anybody got the same issue:

import os
import cvb

os.chdir("C:/")

vin_device_RGB = cvb.DeviceFactory.open("C:/Program Files/STEMMER IMAGING/Common Vision Blox/drivers/GenICam.vin",port= 0)
vin_device_NIR = cvb.DeviceFactory.open("C:/Program Files/STEMMER IMAGING/Common Vision Blox/drivers/GenICam.vin",port= 1)

##Set Trigger mode
#For RGB
dev_node_map1 = vin_device_RGB.node_maps["Device"]

triggerModeNode = dev_node_map1["TriggerMode"]
triggerModeNode.value = "On"

triggerSourceNode = dev_node_map1["TriggerSource"]
triggerSourceNode.value = "Line7"
triggerActivationNode = dev_node_map1["TriggerActivation"]
triggerActivationNode.value= "FallingEdge"  #Wird bei absteigendem Signal ausgelöst

#For NIR
dev_node_map2 = vin_device_NIR.node_maps["Device"]

triggerModeNode = dev_node_map2["TriggerMode"]
triggerModeNode.value = "On"

triggerSourceNode = dev_node_map2["TriggerSource"]
triggerSourceNode.value = "Line7"
triggerActivationNode = dev_node_map2["TriggerActivation"]
triggerActivationNode.value= "RisingEdge" #Wird bei ansteigendem Signal ausgelöst

###################################
stream1 = vin_device_RGB.stream
stream2 = vin_device_NIR.stream
stream1.start()
stream2.start()
for i in range(19):
    image1, status = stream1.wait()
    image2, status = stream2.wait()
    if status == cvb.WaitStatus.Ok: 
        while os.path.exists("RGB_%s.tif" % i):
            i += 1
        image1.save("RGB_%s.tif" % i)
        while os.path.exists("NIR_%s.tif" % i):
            i += 1
        image2.save("NIR_%s.tif" % i)

stream1.abort()   
stream2.abort()
3 Likes