Receiving Streamed UDP data

Hello,

I have a device that steams serial data (a simple ASCII string) over the Ethernet network the controller is connected to.
It uses an UDP socket, the destination IP address and port number can be changed.

How can I receive the string with a Snap-PAC-R1?

The existing documentation explains how to stream memory data from the controller; I want to receive a simple string.

Any pointers will be appreciated.

Luis

1 Like

Hi Luis,

I’m glad you asked. The SNAP-PAC controller firmware currently has support for communicating via udp using communication handles (just like tcp), we just don’t “officially” support it.

That is, we haven’t fully documented/tested all the ways it could be used and abused so it’s an “at your own risk” feature at the moment, partly because udp is tricky, and using it with our current implementation you have to handle sequencing of packets yourself.

However, every time a SNAP-PAC controller communicates to an Ethernet brain, it’s using an internal udp comm handle. This feature is on the list of undocumented features we plan to officially support/document in the (hopefully near) future. Be sure you’re subscribed to OptoNews to make sure you don’t miss when it’s officially supported.

In the meantime, using a udp comm handle is very similar to tcp, just use “udp” in place of “tcp” in your comm handle’s initial value or set it using the Set Communication Handle Value command BEFORE doing the Open Outgoing Communication command. You can omit the IP address if you don’t need it (so the comm handle might be something like “udp:22004”).

Other tidbits that may be helpful:

• A document on port numbers: http://www.opto22.com/documents/1940_TCP_and_UDP_Port_Assignments_Tech_Note.pdf

• Controller firmware version 9.1 has get.src & set.dest options in Send Communication Handle Command:
[INDENT]If you haven’t already, you may want to upgrade to 9.1 firmware since Send Communication Handle Command now includes these options which may be useful to you:

  •        For both udp and tcp, the new [B]get.src[/B] command returns the IP address from which the connection originated. 
    
  •        For upd, the new command, [B]set.dst:n.n.n.n:pppp[/B], sets the destination for the next messages, until another set.dst command is sent.
    

[/INDENT]
• [B]PAC Sim[/B]: Your udp comm handles should work in [URL=“http://www.opto22.com/site/downloads/dl_drilldown.aspx?aid=3690”]PAC Sim too, which might be helpful for testing.

-OptoMary

Hello OptoMary,
Thanks a lot for your quick response, after a bit of trial and error I got the UDP comms working, I can send a string and receive a string.
I found a couple of free UDP testing tools on the net to test the PAC code.
I am including the code here in case someone else needs the example:

SetCommunicationHandleValue(“udp:22004”,chHealth_Monitor);

intFunction_Status = OpenOutgoingCommunication (chHealth_Monitor);

if (intFunction_Status) Then
NumberToString(intFunction_Status, strError_Message);
strError_Message += " - Failed to open Health Monitor channel";
endif

DelaySec(5);

SetEndOfMessageTerminator (chHealth_Monitor , 10);

intFunction_Status = SendCommunicationHandleCommand(chHealth_Monitor, “set.dst:192.168.1.46:12345”);
if (intFunction_Status) Then
NumberToString(intFunction_Status, strError_Message);
strError_Message += " - Failed to set destination for Health Monitor channel";
endif

DelaySec(5);
intFunction_Status = ReceiveString (strHealth_Monitor, chHealth_Monitor);

if (intFunction_Status) Then
NumberToString(intFunction_Status, strError_Message);
strError_Message += " - Failed to receive string from Health Monitor channel";
endif

DelaySec(3);

intFunction_Status = TransmitString(“test Text”, chHealth_Monitor);
if (intFunction_Status) Then
NumberToString(intFunction_Status, strError_Message);
strError_Message += " - Failed to transmit string from Health Monitor channel";
endif

Regards,
Luis

Luis,

Thanks for the code snippet, a great timer saver for other UDP pioneers.

We used UDP at the hospital for years and years (it’s still in and running as far as I know) to talk to the main paging system.
Believe it or not, it was the only way to communicate with the system outside of the VT100 terminal on the switchboard operator’s desk!
Hooking the Opto 22 system up to the paging system was an important step in notifying staff of the different statuses that the Opto system was controlling in the hospital. (We still use the paging system a lot, even now that ‘everyone’ is carrying cell phones; the Opto system simply sends text messages as well, via email).

Since we were only talking to one device, we set up our comm handle a little different. Here is a screen shot showing the details:


The chart is pretty much the same as your OptoScript, so similar in fact, that I am not going to bother to display it.
I just thought the comm handle was different enough to be worth a comment.

Ben.

Is UDP still inching closer to official support? If not, referencing this thread in the manual could be a time saver too. In the absence of any other guidance, I would probably have guessed UDP can be inserted in the comm handle value in place of TCP, since it is sort of referenced in the documentation of the “Synchronize Clock SNTP” command. However, it was nice to find this thread and get confirmation.

Good question, thanks for asking. Not sure when it’ll be “official” yet, but in the meantime, besides the set/get commands I mentioned above, these addition options are also supported in the latest-and-greatest firmware:

  • get.srcport to get the port from which an incoming packet originated
  • get.ttl to get the current time-to-live value
  • set.ttl to set the current time-to-live value

Hello! Bringing this thread back from the dead. I’m having a VERY aggravating UDP issue with a PolyScience chiller. I can send messages (e.g. set a temperature setpoint), and it’s receiving them (new setpoint shows on their local display), but I’m not receiving any characters on my comm handle in return. The Set Communication Handle Value (“udp:10.40.188.76:1024”, Poly_ch) must be working, or the chiller wouldn’t receive my setpoint message. RIght?

When I use Packet Sender from my laptop (set for udp with same IP address and same port number) to send the same messages and Wireshark to receive responses, the Chiller is in fact sending the correct responses back and Wireshark picks them up just fine.

Any thoughts? I’m using Transmit String, Get Num Chars Waiting, then ReceiveString (only if NumChars > 0). Not getting any errors on Open Outgoing Communication or Transmit String – I’m just not getting any Characters in response (Num Chars is always == 0). Thanks! Let me know if you need more of my code.

Also tagging @Beno

Thanks!!!

Are you looping (with small delay and optional timeout) on the Get Num Chars Waiting until you have more than 0? If you call it immediately after the Transmit string it will likely still be 0 as it is not a blocking call.

Thanks @philip - I’m not looping, but I’ve been testing it in debug and stepping through each step of the code, so it has PLENTY of time between the Transmit and GetNumChars commands (and there’s also a DelaymSec 500 in between). I can write in a looping delay (with timeout, of course), but pretty sure it would timeout each time.

When I send the same commands using Packet Sender, the response comes back immediately from the Chiller.

Are you sending the same command from the laptop? Are there any network devices between the Opto controller and the chiller that may be blocking the response packet?

Yes, sending the same command from the laptop as from PAC-R1. The commands are ASCII, such as:

I have one Ethernet switch that all three devices were plugged into: the PAC-R1, the Chiller, and the laptop. So the same switch is between the laptop >> chiller and the PAC-R1 >> chiller. The switch seems to allow the response packet get back to the laptop, so I wouldn’t think it’s the switch. That being said, I didn’t set up the switch (and it is a managed switch) and I have no idea how it’s configured.

I did have one cross-over cable between the laptop and switch, but the switch should account for that, so it should not make a difference.

I /could/ try to change which port on the switch each device is plugged into, but I wouldn’t think this would make a difference (and I’ve dismantled the setup with the switch, for other troubleshooting on this skid).

Maybe try an unmanaged switch, or better, a managed switch that you can turn port mirroring on so you can run wireshark and see what is going through the switch if switching switches doesn’t solve the issue.

Thanks @philip - I think port mirroring is the next step. I need a window into what’s going on on the rest of the network. I’ll have to get my IT dept involved. Boo.

It’s weird, right!?

@philip and @Beno - I got the results from the port mirroring, and the chiller is definitely sending the characters, but the Comm Handle isn’t picking them up.

The communication chart is sending four commands via UDP (see table, all with a CR at the end, and responses get a CR on the end too. I have the EOM set to CR). On each of these transmit commands, Comm Handle should be picking up 2 - 6 characters (including the CR).

I’ve attached the Wireshark file as well as a text dump of the Data from Wireshark, showing the characters it’s seeing. There’s also a screenshot of my code in Debug, taken right after the TransmitString command, showing the lack of Num Chars Waiting on the Comm handle.

Would LOVE to hear any thoughts you have! I can punt and do this via RS-232, but that seems silly when this should work. Are there any communication settings I can tweak for the UDP?

Thanks!!!

PolyscienceChiller.zip (13.6 KB)

Command Meaning Response Meaning
RO[CR] Read Operating Status 1[CR] Running
RT[CR] Read Internal temperature 24.37[CR] (temperature)
RF[CR] Read alarm status 1[CR] Fault
RS[CR] Read setpoint temperature 21.10[CR] (temperature)

Thanks for the packet capture, that really helps see what is happening.

From the text dump I see the PAC sending from port 47091 to 1024, as expected. However the chiller is responding from 1024 to 1026 instead of 47091. That behavior is not normal.

I suspect there is a setting in the chiller that is set so that it always responds to port 1026. Maybe that can be turned off. If not, then you can setup your comm handle to transmit from 1026 by using a udp listener at that port (you can still transmit) like so:

SetCommunicationHandleValue("udp:1026",Poly_ch);
SendCommunicationHandleCommand(Poly_ch, "set.dst:10.40.188.76:1024")

I am pretty sure the rest of your logic would be the same.

Edit: I assume you are using some sort of ethernet to RS-232 device since it looks like the chiller only has RS-232. That device would be causing your issue. It is what would need its configuration changed so that it will respond back to the source port. Also note, that the 47091 port the PAC is using is selected by the PAC when the comm handle is opened, it will change so don’t tell the device to respond to that port as it will not work in future connections.

Thanks, @philip ; this is amazing! I was not expecting to get any kind of real answer, so I’m grateful you took the time to look through the info.

The Chiller has an option to buy with an ethernet port, so no intermediate device was required. I had to contact the chiller company for the Port they were receiving on (1024). I’ve attached the doc they sent me with that info. In the Wireshark screenshot on page 4, it does look like they’re sending back to 1026 /sigh/.

PolyScience AD-UDP-information 20170503.zip (444.0 KB)

I will try your fix and let you know!

Holy stromboli it worked!!! Thanks so much @philip !

I just had to finagle where the Set Comm Handle and Send Comm Handle Command commands went in the chart (have to Send Comm Handle after the Open Command).

HOORAY! There’s nothing quite like the feeling of getting a stupid thing to communicate. Now, onto the next stupid thing that I need to get to communicate.