Post Go back to editing

libm2k python get_samples is blocking?

Hi,

I'm using libm2k (v0.3.2-g567fd42) in a python environment. I have a data collection script which I would like to use to A) generate a triggering event from a separate device and B) measure the resulting waveforms through the M2K. My problem is that calling m2k.getAnalogIn().getSamples(N_SAMPLES) seems to cause all interpreter threads to block, so I haven't been able to capture the results from my triggering event.

Here is some pseudocode of what I'm trying to do:

def event_loop():

    for i in range(100):

        generate_event()

        print("event")

        time.sleep(0.01)


thread = threading.Thread(target=event_loop)

thread.start()

samples = m2k.getAnalogIn().getSamples(N_SAMPLES)

print("join")

thread.join()

The output looks something like:

event
event
event
event
I0802 14:25:20.687490 24504 m2kanalogin_impl.cpp:296] [BEGIN] M2kAnalogIn getSamples
I0802 14:25:20.687490 24504 devicegeneric.cpp:200] [m2k-adc][sampling_frequency][read] 10000000.000000
I0802 14:25:20.687490 24504 channel.cpp:140] [m2k-adc][voltage0] Enable channel
I0802 14:25:20.687490 24504 channel.cpp:140] [m2k-adc][voltage1] Enable channel
I0802 14:25:20.687490 24504 buffer.cpp:84] [m2k-adc] RX buffer created (8192 samples)
I0802 14:25:23.195003 24504 buffer.cpp:530] [m2k-adc] Buffer destroyed

The program exits before "join" gets printed since no triggering event happens after the call to getSamples.

Is there a way to fix or get around the blocking behaviour of getSamples to allow for the event call to happen?

  • Hi,

    It's expected to have the thread blocked by "getSamples" until a trigger event is captured.
    The problem in what you describe is that all the other threads are also blocked.
    I would think this is caused by the threading system in Python.
    You could try using "multiprocessing" instead of "threading", for the described Python script.

    One way to go around the blocking aspect of the function is to use the function "ctx.setTimeout" (documented here: analogdevicesinc.github.io/.../group__context.html ). This should be set right after creating the M2K context. Using this, the "getSamples" call will only block and wait on the trigger event for the specified amount of time. After that, it will drop the acquisition and your thread will move forward.

    I do need to mention one thing for the "setTimeout" solution: if libm2k is built with enabled exceptions, getSamples will throw an Exception/Error when the specified timeout is reached. Using a "try: ... except:.." block around the "getSamples" call will allow you to better manage the execution flow.

    Also, I recommend using the latest libm2k version (0.6.0) instead of v0.3.2-g567fd42 . There were a lot of bug fixes added and the library is more stable.

    Thank you!
    -Alexandra

  • Hi,

    There would be another way to run the data acquisition. Using the startAcquisition method ( https://analogdevicesinc.github.io/libm2k/group__analogin.html#ga7dab519b883bb7e4aa1543fd48c20c51 ).
    - you need to setup the trigger settings first
    - startAcquisition(nb_samples) will create the buffer and try to fill it with data - but it will only be done when you send the trigger event later on
    - generate the trigger event - this will fill up the previously created buffer
    - run getSamples(nb_samples) - this will just return the buffer that was previously created and contains all the data triggered by your event.

    -Alexandra

  • Hi Alexandra,

    Thanks for your helpful answer. If I add stopAcquisition() after, this solution works.
    However, sometimes the triggering event may not actually generate during data collection, in which case the buffer will be empty. When this is the case, getSamples simply causes the program to exit. Is there a way to get check whether the buffer is full or empty so that I can avoid calling getSamples in these cases?

  • Hi,

    Can you check if using a "try/except" block around getSamples fixes this?

    -Alexandra