Closed ttamttam closed 4 years ago
The access to camera features by using attributes of the Camera object is implemented in such a way, that the available camera features are loaded when the camera connection is opened. This is done because different cameras can expose different features. Creating the feature objects during opening allows the user to have more "pythonic" code by accessing featues with cam.TriggerSource.set("Software")
instead of cam.get_feature_by_name("TriggerSource").set("Software")
. That is why you won't find implementations for every feature in the VimbaPython source code. The features you want to access (TriggerSource
and TriggerSoftware
) should however be available. And your attempts at accessing them look fine.
I am not sure what it is exactly that you want to achieve. But in order to demonstrate a way of using software triggers to grab single images I made some changes to the asynchronous_grap.py example. You can find that version here.
The main change is that in setup_camera
I set the AcquisitionMode
to SingleFrame
so I would only trigger a single image. TriggerSource
is set to SoftwareTrigger
and the TriggerMode
is turned On
so the camera actually listens for them.
cam.AcquisitionMode.set("SingleFrame")
cam.TriggerSource.set("Software")
cam.TriggerMode.set("On")
Next I defined a class to run the software triggering in a separate thread. This makes it easy to stop the thread from the outside by using the stop
method that sets a threading.Event
.
class SoftwareTriggerThread(threading.Thread):
def __init__(self, cam: Camera):
threading.Thread.__init__(self)
self.cam = cam
self.killswitch = threading.Event()
def stop(self):
self.killswitch.set()
def run(self):
# with Vimba.get_instance(): # still opened in main thread. So it can be left out in THIS example. Generally this is required
# with self.cam: # still opened in main thread. So it can be left out in THIS example. Generally this is required
while not self.killswitch.isSet():
print("RUN TRIGGER HERE", flush=True)
self.cam.TriggerSoftware.run()
time.sleep(1) # Just to make it easier to follow terminal output
print("REARMING FOR NEXT TRIGGER", flush=True)
self.cam.AcquisitionStart.run()
time.sleep(1) # Just to make it easier to follow terminal output
Lastly I simply have to create the thread and start it in order to generate software triggers every two seconds. This is done in the main function after the frame_handler
is registered and the camera was told to start streaming.
cam.start_streaming(handler=frame_handler, buffer_count=10)
software_trigger_thread = SoftwareTriggerThread(cam)
software_trigger_thread.start()
input()
software_trigger_thread.stop()
software_trigger_thread.join()
With this you should see the following output in your terminal: /////////////////////////////////////////// /// Vimba API Asynchronous Grab Example /// ///////////////////////////////////////////
Press
RUN TRIGGER HERE
Camera(id=DEV_1AB22D01BBB8) acquired Frame(id=0, status=FrameStatus.Complete, buffer=0x23153fd5040)
REARMING FOR NEXT TRIGGER
RUN TRIGGER HERE
Camera(id=DEV_1AB22D01BBB8) acquired Frame(id=1, status=FrameStatus.Complete, buffer=0x231544bb040)
REARMING FOR NEXT TRIGGER
...
As before the acquisition can be stopped by pressing enter. The software trigger should run every two seconds and the frames should be acquired accordingly.
I hope this helps. If you have further questions feel free to reopen the issue. But as the features are available once the camera is opened, I would not consider this an issue with VimbaPython and will therefore close this for now.
see Vimba Python Manual 1.0.0, page 17.
Trying to switch to
cam.TriggerSource.set('Software')
without success, because I can't findcam.TriggerSoftware.run()
?I just grepped for 'trigger' in the source code:
Best regards