basler / pypylon

The official python wrapper for the pylon Camera Software Suite
http://www.baslerweb.com
BSD 3-Clause "New" or "Revised" License
566 stars 207 forks source link

camera link + frame grabber gpio OUT issue #644

Open emilyjanedennis opened 1 year ago

emilyjanedennis commented 1 year ago

hey folks,

Is there a way to trigger a TTL programmatically in python? Reasoning below: tl;dr I want to debug with our oscilloscope and can't get any signal under any circumstances and documentation for our camera is hard to find or doesn't exist.

I'm trying to get our microenable 5 marathon ACL framegrabber front GPIOs to output a TTL-like pulse using the rising trigger from either exposure or acquisition (doesn't matter as long as we're getting a pulse for each frame) on our Basler ace acA2040-180kmNIR which is connected via 2 camera link cables. I've hooked up an oscilloscope to our GPIO out and see nothing regardless of settings, and I've tried triggering acquisition via python and microdisplay X to no avail. I do have a working python script that saves video from the camera, so we have good connection, etc.

The online documentation for Line Source, etc. doesn't have our camera model, and I've tried using pylon, microdisplay X parameters and can't find either sufficient documentation to be sure I'm doing things right. So, I'm hoping there's a way to use python and get the framegrabber to send a TTL via front GPIOs.

Any/all help much appreciated. I also contacted Basler support a week ago and still haven't heard back, seems like this is more frequently updated. Thanks! -Emily

BryanLiou commented 7 months ago

Hello Emily,

I also encountered the same problem, have you solved it?

Thanks! Bryan

emilyjanedennis commented 7 months ago

Unfortunately no, we ended up buying the TYL board and it's still difficult and basler help has been extremely unhelpful

On Tue, Mar 19, 2024, 06:12 劉庭嘉 @.***> wrote:

Hello Emily,

I also encountered the same problem, have you solved it?

Thanks! Bryan

— Reply to this email directly, view it on GitHub https://github.com/basler/pypylon/issues/644#issuecomment-2006673704, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABXL3DXZL3VQEZKY5UHXPRTYZAFQ3AVCNFSM6AAAAAA32B76XGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMBWGY3TGNZQGQ . You are receiving this because you authored the thread.Message ID: @.***>

cpt-wojtech commented 7 months ago

Hi @emilyjanedennis would it be an option for you to use the cameras GPIO outputs? They are well described in the cameras manual, which is not on the Online Product Documentation but can be downloaded here https://www2.baslerweb.com/de/downloads/downloads-dokumente/basler-ace-camera-link-users-manual/ You could use the ExposureActive signal on one of the Lines to get an high signal every time the exposure of an image starts.

The second hurdle that I can see is that pypylon is not necessarily the best option to work with the framegrabber. Maybe take a look at the Python Wrapper for the Framegrabber SDK https://docs.baslerweb.com/frame-grabbers/python-wrapper They are different API's: the pypylon API is good for CXP cameras and CXP Framegrabbers, while the Python-Wrapper is in general better for Framegrabbers.

I can try to check if there is a possibility to use the Outputs of the grabber using the cameras ExposureActive signal.

floesche commented 3 weeks ago

I helped with getting a TTL signal out of the framegrabber and wanted to document what we did, in case someone else tries to solve a similar issue (e.g. @BryanLiou).

The framegrabber can load different "applets", which programs the FPGA inside the Basler microEnable 5 marathon ACL. While Basler provides a visual programming language for the FPGA, I was able to use an existing applet to get a TTL.

For the combination of camera and framegrabber, I chose the "Acq_SingleBaseAreaGray" applet. I used the python wrapper of the Basler Framegrabber SDK to interact with the applet. Following the documentation for the applet, I used the following snippet to switch the camera to software trigger (line 2), set the maximum triggers per second to 200 (line 3), initialized a pulse generator with a certain width and delay (lines 4…5), and set the output to the front GPIO (line 6). Finally I make the trigger active (line 7):

import SiSoPyInterface as s
s.Fg_ParameterWithInt(frame_grabber, s.FG_AREATRIGGERMODE, s.ATM_SOFTWARE, port)
s.Fg_ParameterWithDouble(frame_grabber, s.FG_TRIGGER_FRAMESPERSECOND, 200, port)
s.Fg_ParameterWithDouble(frame_grabber, s.FG_TRIGGER_PULSEFORMGEN0_WIDTH, width, port)
s.Fg_ParameterWithDouble(frame_grabber, s.FG_TRIGGER_PULSEFORMGEN0_DELAY, delay, port)
s.Fg_ParameterWithInt(frame_grabber, s.FG_TRIGGEROUT_SELECT_FRONT_GPO_0, ⏎
    s.CAM_A_PULSEGEN0, port)
s.Fg_setParameterWithInt(frame_grabber, s.FG_TRIGGERSTATE, s.TS_ACTIVE, port)

After this setup, a TTL with a certain width and delayed by delay can be triggered by the following lines:

err = s.Fg_setParameterWithUInt(self.__fg, s.FG_SENDSOFTWARETRIGGER, 1, self.__port)
if (err != 0):
    print(f"Trigger failed {err}: {s.Fg_getLastErrorDescription(self.__fg)}")