I am trying to figure out the fastest way to communicate with my OPTO 22 DAQ.
Right now I’m communicating to it through peer-to-peer using python and rest API calls for groovManage. The response times are anywhere between 0.1ms - 0.15ms with waiting for a response code, and anywhere between 0.02ms - 0.05ms utilizing threading and not waiting for a response code.
Does anyone know a faster way to retrieve and set data that can still interact with python from a separate computer? I don’t have any of the OPTOMMP cards, only ODCSRC-24, IV-24, IVI-12
REST (as you have discovered) is about the slowest way.
Philip is spot on with the UDP streaming. @torchard did some Python MMP benchmarking, he might have some thoughts on this.
Set index 4 to 1 to enable, 0 to disable the stream.
Index 5 is the interval in milliseconds.
Index 6 is the UDP port to stream to
Index 8 is the IP address of the system you are streaming to, each octet of the IP uses a byte of the value.
Default is to stream every IO channel possible, which is 2,308 bytes on the PR1 - this can be optimized by setting up the custom configuration area for the addresses you need and setting the streaming configuration to use the custom configuration area (check the OptoMMP Protocol Guide).
When streaming all 2,308 bytes and setting the index 5 to 1 for 1 ms, I was averaging a little over 2 ms for each push.
Note for Opto22 Devs: If I have the streaming set to 1 or 2 ms and then set index 4 to 0 to stop streaming, the streaming doesn’t stop - I think there is a bug here. I have to set the interval to 3ms or higher first, then I can write a 0 to index 4 and it stops.
Ugly Python UDP listener code that times the intervals and averages the last 100 and displays the results repeatedly:
import socket
from timeit import default_timer as timer
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", 10500))
lstTimes = [0.0]*100
i=0
start = 0
while True:
data, sender = sock.recvfrom(2500)
end = timer()
duration = end-start
start = timer()
lstTimes[i]=duration
i = i + 1
if i == 100:
i = 0
size = len(data)
avg = sum(lstTimes)/100.0
print("Received a message of size %d bytes. Time since last packet: %6.4f. Average: %6.4f" % (size, duration, avg), end='\r')
Thanks guys! I got the OPTOMMP protocol working and it is fast enough for my applications (around 0.3ms). I’ll look into UDP streaming if I have faster requirements but for now this is all good information.
Also not sure if this changes between OS’s but importing the optommp library into Python didn’t work natively for me. I had to edit the “init.py” to go from “import O22SIOUT” to “from . import O22SIOUT.” Not sure if you guys have some devs that want to update the github for that.
My bad, just revisited my code I had a conversion error.
Should be 0.3ms.
I would take also take this measurement with a grain of salt though, since it’s written in Python and I’m not even sure if Python can output that kind of resolution. I’m using the perf_counter_ns() function from the time library to calculate just a single function call (for example: “GetAnalogPointValue()”)
Hey Philip, how were you able to get this page? The closest page I could get to this was under Generic MMP in I/O configuration, but the addresses don’t match so I’m assuming I’m in the wrong area