I’m using the MSO thru the Python API. I have code that’s working to grab both analog and digital captures together. (I’m using the digital capture to watch a trigger I have and trim the analog after the fact, but that’s less relevant to my Q here.) I do this as a timed capture.
In my test code, I notice that the command that invokes the capture takes a while to set up the device and then does the capture. The amount of time is large enough that there’s an issue synchronizing this with the rest of my system.
While I can deal with a setup time on the order of seconds, I need the timed capture to happen very promptly. Is there a way to invoke the setup to happen, but the timed capture to only happen on a subsequent call from my software?
(Side note: Until digital triggering is implemented, this approach seems like it will work for what I need. I’m trimming the analog data by looking for the trigger edge in the digital capture.)
Hi @trevor.marvin!
There are two things I think we should probably fix in the short term to support you on this. Digital trigger will probably take more time.
Before jumping into what we should do, in the short term I just wanted to share that the device setup time should only be incurred one time, when taking the first capture. subsequent captures from the same python script should have minimal capture startup overhead. One possible short term solution would be to run a short “throw away” capture at the start of your setup, so subsequent captures are performant.
Next, I want your feedback on some proposed changes:
- We’ll make sure any device initialization is done ahead of time, before the first capture. (I need to check where we’re currently spending the most time. Device initialization must be done at least once per run of the API. We could do this in the constructor or we could add an extra method, e.g.
initialize() or similar.
- Currently, we offer a single blocking
capture() command. This handles configuring the device, starting the capture, and waiting for the capture to complete, waiting for the data to process, export, and parse, etc. This is not great for synchronizing the capture with anything else. What do you think about adding a second, non-blocking API, such as: start_capture() which takes the same configuration argument. This function would block until the device has initialized. In the case of timed recordings, this would mean the device has started recording. In the triggered case, we would need to decide if we should wait for the full pre-trigger buffer to finish filling before returning or not. Longer term we want to allow the user to optionally skip the pre-trigger buffer when using trigger mode.
wait() can be called to simply block until the capture is complete. (e.g. trigger was found and post-trigger buffer was recorded, or the timer duration was satisfied, etc).
stop() can be called to simply end the capture where it is now. Any data recorded would still be available for processing, so you could use this to stop the capture the moment you’re done exercising your device under test.
Let me know what you think! These suggestions are based on our more mature automation interface used by our pre-MSO devices. details here: Getting Started — Saleae 1.0.6 documentation
Indeed, the capture takes off faster if I chain a second one after the first one. I can deal with throwing away a capture for the short term.
I’m presuming that there isn’t another setup time when I give a new save path? It didn’t seem like there was.
My application is already threaded, so I can work with blocking calls. But having something that will handle its own thread(s) behind the scenes is nice. Maybe a bool option in the start_capture() method for people to select blocking or not?
Along with wait(), maybe done() or ready()? And raise an exception if a capture was not invoked.
If you can grab the computer’s system clock (i.e. time.time()) to the best of the ability of the API when the capture is believed to have started, that would work very well for my system to know if it triggered properly. I have a free running pulse-per-second input triggering my capture devices and I have my software arm them at 0.2 after the second of the system clock. With the expected sync quality of the system clock on NTP (which I get from NTP), and the slop in Python not running in a real-time mode, this has worked quite well in my existing application being able to trigger multiple units at exactly the same time.
If your code doesn’t get too complicated to do this, reflecting the system clock into the time stamps reported in the capture would be really nice. Failing that, just knowing the system time when it believes it triggered would allow me to do this adjustment externally.
Oh… and specifically to one of your questions… I like the notion of an initialize() function. I would presume to send the configuration on this call too. My channel config doesn’t change very often, and I can re-init when it does.
What would change often for me is the directory I save to. Right now, my capture time doesn’t change often, though I could see that being something more apt to change.