I've recently bought a connect 4 + MIO expansion and setup everything.
In the current setup I'm reading DigitalInput_1 and when high, use it to drive DigitalOutput_4 high.
For context the digital input is connected to a trigger (a laser that checks presence of an object) and the digital output is connected to a strobe light and I'm able to capture a video at 60fps. To verify the delays I'm using this video recording with an accuracy of around 1/60=16ms.
What I've observed is that if I'm controlling everything from python with an async function I'm able to see consistently that in 4 frames the light goes on while if I'm doing that in node-RED the light goes on after around 15 frames.
In short to control a digital output from a digital input I'm observing the following delays:
python code: ~66ms(4frames)
Node-RED: ~250ms(15frames)
In Node-RED the flow is the simplest as possible (input connected to output).
I've also tried to control the output from the input with a flow that trigger continuously with an inject node each N ms and a downstream exec node by putting the "piTest -1 -r DigitalInput_1", then processing it with a js function to extract the value and then with an exec node that change the digital output. Still the Node-RED delay is there with the same magnitude.
Do you think we may have reached the limits of Node-RED for IO tasks and it's better to consider CODESYS or python in case this performance is insufficient?
Maybe there are some Node-RED options I've not considered?
Suggestions are welcome.
Thanks in advance.
Node-RED version: v3.1.9
PiCtory version: 2.11.0
Product: RevPi Connect 4 WLAN 32/8GB Version: 1.1 Data Version: 1 Id: PR100380R01
image release: 2024-04-25-revpi-bullseye-arm64.img
Example fast python code:
Code: Select all
"""Event control cycle."""
import revpimodio2
import time
# Define global variables
counter = 0
def evt_i_1(name, value) -> None:
"""Event function for input I_1 will light up strobo"""
global counter
global STROBO_LIGHT_TIME_MS
counter += 0
print(counter)
rpi.io.DigitalOutput_4.value = True
print("light on")
def toggle_strobo(name, value) -> None:
"""By changing the LED, we will start the next timer event."""
# Show the health of your program, by flashing the green A1 led
rpi.io.DigitalOutput_4.value=False
print("light off")
def clean_up():
"""Will be called at the end of the program."""
# Create the RevPiModIO object
rpi = revpimodio2.RevPiModIO(autorefresh=True)
rpi.cycletime=20 # defautl
print(f"current cycle time in ms {rpi.cycletime} (min is 5ms for Connect 4 and default 20ms)")
# This will catch exit signals and calls the clean_up function
rpi.handlesignalend(clean_up)
# Register an event function to input I_1 for changing state to True
rpi.io.DigitalInput_1.reg_event(evt_i_1, edge=revpimodio2.RISING)
# Register an event function to output O_4 for changing state to False
# Register a timer event to change state of strobo to 0 every 10 ms
rpi.io.DigitalOutput_4.reg_timerevent(toggle_strobo, 10, prefire=True)
rpi.mainloop()
Code: Select all
$ piTest -d
Found 2 devices:
Address: 0 module type: 136 (0x88) RevPi Connect 4 V1.0
Module is present
input offset: 117 length: 6
output offset: 123 length: 7
Address: 31 module type: 118 (0x76) RevPi MIO V1.2
Module is present
input offset: 0 length: 34
output offset: 34 length: 27
Code: Select all
$ piTest -1 -r RevPiIOCycle
1 Byte-Value of RevPiIOCycle: 6 dez (=06 hex)