Best way to receive UDP data form sensors
Hi all,
I've built two sensors, each one creates a wi-fi network and communicates via UDP.
for each I have different:
1) Network name (like "Network001")
2) an IP address (like "192.168.2.1") (without password)
3) a port set (same for both, 5010)
4) a hostname (like "Host2001")
I need to capture their information with Max, but don't know which is the best way to go.
Any suggestion?
Thanks a lot!
Hi,
if your sensors send OSC-formatted data, then you should check the [udpreceive]
object, which is part of Max. If not, then I suggest you to use [sadam.udpReceiver]
from The sadam Library: https://cycling74.com/forums/announce-the-sadam-library-version-2012-10-08 .
HTH,
Ádám
Thanks Adam, I already downloaded it! You did such a great job, compliments!
Unfortunatley I don't know why i can't receive messages on port 5010 with [sadam.udpReceiver], I don't know why,
I'm not receiving OSC data, but a list of 4 int:
(1) 0-10 (2) 0-1024 (3)0-1024 (4) 0-1024
it says: "Can't bind to UDP port 5010"
false, alarm. that port was simply already taken by another object! :-)
now the only obstacle I see is that my stream of int is from 0 to 1024, while it seems to be capable of handling 0-255 int only.
Hi,
[sadam.udpReceiver]
will output you the network stream byte-by-byte. The reason for getting data between 0 and 255 is that this is the numeric range that a byte can represent. To proceed, you need to know how exactly your sensor transmits data over the network. My guess is that the first parameter (0-10) gets transmitted using a single byte and the other three would use two bytes each. If this was the scenario, you simply need to [unpack]
the incoming data stream, take the byte-pairs, multiply the high byte by 256 (that is, shift by 8) and add it to the low byte:
However, this might or might not work, depending on the exact format of your sensor's output (if my guess is wrong, then it wouldn't work for sure). The best would be if you could tell me the exact output that [sadam.udpReceiver]
gets from your sensor (as a byte stream) and also the expected int values as well. In that case, I could help you more.
Best,
Ádám
thanks for your reply!
the sensor will transmit a list of four numbers, already packed.
the first one wiil be 0, 1 or 2.
The second is a value between 0 and 1024 (x axis) the third and the fourth the same 0-1024 (x and Y axis)
Hope this helps!
If you're trying to send the 10-bit values (0-1023) as a single 16-bit int, you'll never get the right value on the receiving end with this setup. You need to break the int into low-byte and high-byte values and send them out sequentially, then reassemble them at the receiving end.
Or you can ditch the 0-1023 (10-bit) resolution at the sensor end and just use 0-255 (8-bit), which for most things is OK, but not sure about your situation.
I was wondering, how did you build the sensor to use wi-fi? Sounds interesting!
Hi again,
could you just try to send out from your sensor a single list containing the highest possible values and let me know what you receive in Max? That would help me to tell you a solution.
Thanks,
Ádám
well... the sensors is actually transmitting a *string* of character, as i see now:
it is like this: "m=0;x=123;y=455;z=800" !
Hi,
what do you mean by that. Are you receiving with [sadam.udpReceive]
109 61 48 59 13 120 61 49 50 51 59 13 121 61 52 53 53 59 13 122 61 56 48 48
for the sensor values of "m=0;x=123;y=455;z=800"? If yes, you just need to convert it with the [itoa]
object...
Best,
Ádám
thanks a lot for the support Siska!
It's the first time I'm dealing with UDP :-)
Ok, so i got it working and now I have integers which i already converted to proper numbers with atoi and fromsymbol in the 0-1024 range, as it should be.
Is there a way to have two objects receiving information on the same port but different addresses?
I succeded in parsing the first sensor, but I am missing the second one, and since it is transmitting on the same port (5010) i am having difficulties in having it set up!
Thank you again, your help is greatly appreciated!
of course it is same port but different IP address :-)
Hi,
unfortunately that's not possible at the moment, but that has to do with the way how sockets work. You see, when you send an IP packet to a computer, the operating system will collect that packet from the network card and register the port number on which the packet arrived. If you have a process that is expecting data, your process needs to tell the OS that 'hey man, I'm waiting for data and I'm expecting it to arrive on port .......!' and as soon as any packet arrives on that specific port, the OS will forward it to your process. Now, the problem is: since the OS doesn't have any clue about what kind of data is arriving on the specified port, it can't make any decisions about routing that information. Therefore, only one process can read a given port at the same time.
In your case, if you instantiate an UDP reader process (no matter whether it is [sadam.udpReceiver]
or [udpreceive]
or even another program which is not even related to MaxMSP) on a specified port (in your case, port 5010) and then instantiate another UDP reader process on the same port (again: no matter what kind of process or program or external or whatever stuff; the point is, that it attempts to read the same incoming port), then the second stuff that you instantiate will get an error from the OS telling that 'sorry kiddo, but there's another guy who took this port before you were even born...' so, there's not much to do. For a single port, you have to live with a single receiver (I mean, OS-wide).
There are two things that you could do: either tell the second sensor to use another port and then read two ports, or force the sensors somehow to send also some sensor-ID thing which would let you split the incoming information within Max.
Actually, to make a complete story for you, the OS also registers the IP address of the source of the packet (moreover, it also registers the port on the remote source that was used for sending the packet, which usually is not the same port than the one where you're listening), but unfortunately the current versions of my networking externals won't give you this information (these objects were part of a paid commission, the commissioner didn't need the incoming addresses and at that time I didn't know that I can also retrieve that information from the incoming packet). It is among my future development plans to extend my networking objects with an extra outlet telling you the source IP address and port, but since the project went freeware, I only have time for developing it during my free time (which I don't really have currently).
If I were you, I would change the second sensor's port, which seems the easier way to go.
Hope this helps,
Ádám (which is my first name BTW)
Thank you so much, again, Adam.
I'll figure out to change the port so ;-)
Again, compliments for your work!
Luca
@seejayjames,
the sensors use the openpicus flyport, btw ;-)
each one creates a network which i connect to from wireless adapters
Hey, those boards look pretty cool, will need to read up more on them. Thanks for the link!
As mentioned, you can pretty easily add an ID number at the start of your string of data and just use [route] at the Max end, either before or after converting to numbers. But because that means making a change on each board, you could (maybe) just as easily change the port on each board too, and change the [sadam.udpReceive] objects to match. Don't know how hard it is to change the port versus changing the data though.
By the way, that was a FANTASTIC explanation of ports and the OS...thank you Ádám!
Hi,
just letting you know that there's an update on my networking objects. Now the receivers will give you the port number and IP address of the sender on success. Maybe this is too late, but hope that it would still help. See https://cycling74.com/forums/announce-the-sadam-library-version-2012-10-08 for details.
Cheers,
Ádám
How you can listen to specific port?
Sadam.udpreceiver which port is using and if I want to listen to multiple ports how?