Hey there!
Our team have some cameras that we want to control with TTLs from artiq during an experiment run. We have a python function that we can call as an rpc that will set the cameras up and tell them to wait for a trigger, and save the captured image to a local directory when triggered, but the script gets stuck there waiting for the trigger, and the downstream parts of the code where we are telling artiq to send the TTLs never gets executed.
The code works, however, if I run the setup/wait-for-trigger function in one terminal, and then run the sequence on artiq with a different terminal.
Is there a better way to have the RPC function that has the cameras wait for the trigger run in the background on the host machine while artiq is doing other things, including sending the trigger pulses, preferably without requiring me to open an extra terminal for each camera by hand for each shot of the experiment.

Here's a minimal sample where I try to do this
`from artiq.experiment import *
import alvium

class TTL_Output(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("ttl49")


def prepare(self):
    alvium.setup('DEV_1AB22C051761',5000,0) # code gets stuck here

@kernel
def run(self): # and none of this ends up getting run.
    self.core.reset()
    self.ttl49.output()
  
    delay(1*us)
    self.ttl49.pulse(1*s)`

where "alvium.setup()" is the function that tells the camera to wait for the trigger.

Thanks!

it seems like your camera code (i.e. alvium_setup) doesn't return until it receives the trigger.
however, the prepare method blocks until completion, which is why it never enters your run() method.

a few options:

  • run your camera code via async rpc; however, this might create synchronization issues (i.e. the TTLs might fire BEFORE your camera is ready to receive triggers)
  • use python's threading library to run your camera code in a separate thread (e.g. during prepare()); however, you might still run into the synchronization issue
  • separate the camera setup code into a "setup" method (where you e.g. set up the cameras and tell them to wait for a trigger), and a "process" method (where you process the camera results etc.)
    • this would make synchronization etc. a lot easier, since you could run setup => synchronize timeline => fire ARTIQ TTLs => process results

Synchronizing ARTIQ hardware with other hardware is often tricky, so it might be helpful to search through the forum for examples/discussions of RPC synchronization , e.g. https://forum.m-labs.hk/d/749-understanding-asynchronous-rpc-functions/3

Good luck!

a month later

Generally I would not run the camera code (which accesses a physical device) in the preparation phase as it is run during the run phase of the last experiment if you queue multiple experiments. This leads to the issue that you program the camera already for the next experiment while the previous has not yet released the camera/took all pictures.