Keep parallel sequences syncronised. Wanting "real time" test steps

I’m wanting to run a test that uses multiple parallel sequences with a multi-channel relay box; one sequence per relay channel. This test requires that the relay channels stay in sync with each other.
I have written a driver for this relay box as well as a test step to toggle the state of a relay and wait for a specified time using the python plugin. Here is the relevant code from the test step:

def Run(self):
    self.Info("Toggled Relay " + str(self.Channel) + " state, Waiting for " + str(self.Time) + "ms")

Where self.Time is the number of milliseconds the step should take and self.Channel is the relay channel to toggle.
The problem is that the Toggle command takes a few milliseconds to complete and over time, the channels get out of sync with each other (approx 1 second per 100 toggles) as they toggle at different frequencies.
Does anyone here know of a way to ensure that the Run method executes in exactly the right number of milliseconds?

@stenstorpmc because neither Windows nor Linux (not sure which you are using) is a Real Time OS, having any exact timing over an extended period of time is not possible.

There are some tricks you can do to ensure subsections of code execute in as close to real time as possible, but staying in sync across threads is fundamentally not possible due to the nature of the OS.

For this to work, you’d likely have to have a synchronized clock within your relay box.

That’s a bit of a pain.
As a bit of a workaround, I’ve coded in a bit of compensation for the time it takes to execute an instruction:

def Run(self):
    t1 = time.time_ns()
    [The Function]
    t2 = time.time_ns()
    OpenTap.TapThread.Sleep(int(int((self.Time * 1000000) - (t2 - t1)) / 1000000)))

Takes the desired wait time in milliseconds, converts it to nanoseconds, subtracts the time taken to execute the function in nanoseconds and converts it back to milliseconds.
Improves things a bit, should bring it within tolerance.

1 Like

@stenstorpmc great. Yeah depending how in sync you need, you can do stuff like this to get close.