I want to build an experiment, that waits for a trigger signal on a TTL input port (Port 1) (possibly up to a certain maximum time), executes as soon as possible, when the trigger is received on the TTL and then counts TTL events on another TTL input port (Port 2).

The two possible ways I found are the following:

1) Open a gate for 60 seconds on port 1 and wait for the timestamp of the trigger. If the timestamp is received, continue with the experiment and try to receive TTL signals on port 2. This runs into the issue, that apparently the port 1 gate time has to finish, before the port 2 gate can be opened. Up until this point execution runs fine. Is there a way to either close port 1 manually once a timestamp has been received, or to run them in parallel in this way?

self.core.break_realtime()
self.t_gate = self.ttl1.gate_rising(60*s)
if self.ttl1.timestamp_mu(self.t_gate) >= 0:
    self.core.break_realtime()
    self.ttl2.count(self.ttl2.gate_rising(1*s))
else:
    print("No start signal received!")

2) Use the watch-API to continously check the value of the TTL input on port 1 and execute the experiment once the value is high. This works, but a delay in between checks of port 1 of roughly 5 us is necessary to avoid RTIOUnderflows. This is too long for the intended application, sadly. Is it possible to speed up the update rate of this procedure below 1 us?

try:
    while self.ttl1.watch_stay_off():
        delay(5*us)
finally:
    delay(5*us)
    self.ttl1.watch_done()

self.core.break_realtime()
self.ttl2.count(self.ttl2.gate_rising(1*s))

If there is any other method, that is better for this problem, I am happy to learn and check if this works more easily with the application.

    9 days later

    steine01 that apparently the port 1 gate time has to finish, before the port 2 gate can be opened

    I'm not sure what that means. In any case, gates on different RTIO channels are independent of each other.

      sb10q That is not what I observed. If I open the gate on port 1 at time T = 0 for 60 seconds and receive a trigger at T = 20s, the program then executes until just before the count function (checked with a logger print in the console), but then waits for another 40 seconds until count is started on port 2.

      This is simply because ttl1.gate_rising() sets the time cursor at that point (see the manual: "The time cursor is advanced by the specified duration."). core.break_realtime() only advances the time cursor or does nothing.
      Use now_mu() and at_mu() to manipulate the time cursor.

      Thank you, now I understand, an at_mu(self.stamp) before the count function solved the issue.