Hello,
I'm very new to Arduino programming so I need some help with UDP messages.
I am using the program MAX MSP to send UDP messages to an Arduino MEGA with an ethernet shield attached. I aim to be able to control 32 solenoids with the Arduino by sending some kind of UDP message. What is the best type of message for me to send to control and separate these simple booleans and how do I translate the incoming UDP strings in the right way?
I have this code (based on the UDPsendRecieveString example) running and working but the packet contents just reads as list, int, and so on at the moment.
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#define SDSelect 4
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xA8, 0x61, 0x0A, 0xAF, 0x03, 0xBC
};
IPAddress ip(192, 168, 1, 56);
IPAddress dns(8, 8, 8, 8);
IPAddress gateway(192, 168, 1, 57);
IPAddress subnet(255, 255, 255, 0);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[255]; // buffer to hold incoming packet,
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup() {
Ethernet.init(10); // Most Arduino shields
delay(10);
pinMode (SDSelect, OUTPUT);
digitalWrite (SDSelect, HIGH);
delay(10);
// start the Ethernet
Ethernet.begin(mac, ip, dns, gateway, subnet);
delay(10);
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
delay(10);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
else if (Ethernet.hardwareStatus() == EthernetW5500) {
Serial.println("W5500 Ethernet controller detected.");
}
delay(3000);
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
else if (Ethernet.linkStatus() == LinkON) {
Serial.println("Ethernet cable is found, all good.");
}
else if (Ethernet.linkStatus() == Unknown) {
Serial.println("Link status unknown.");
}
while(!Ethernet.linkStatus() == LinkON) {
;
}
delay(100);
// start UDP
Udp.begin(localPort);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i=0; i < 4; i++) {
Serial.print(remote[i], DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBuffer
Udp.read(packetBuffer, 255);
Serial.println("Contents:");
Serial.println(packetBuffer);
}
}
Forget about using booleans and Strings. All you need to send is 32 bits. On receipt of the 32 bits you can parse the individual bit values and use them to control your solenoids
Well I haven't decided what type of message to send yet since I don't know what would be the best to receive to control the different solenoids.
But if i send a 1 I get:
and if I send more ints i get 'list'
but if i send 'hey' I get the message that was sent, 'hey'.
But since Im just interested in boolean values I dont know if its best to send lists or ints? To keep byte usage down.
Well now it is how to parse the 32 incoming bits from the UDP message and have them control the Arduino pins. Don't really know how I should go about handling the incoming UDP message to begin with.
If you can send and receive a 32 bit variable then you can use bitRead() to find the value of each of its bits and use it in place of a boolean variable
Okay, thank you I'll try it out!
Just to get me started can I ask how to handle the incoming UDP packet as a group of bits instead of as a char buffer?
wow thanks! That result looks like exactly what I'm looking for but I'm too new to Arduino to understand your code or how to implement this into my UDP setup...
presumably you're reading a ASCII string of a number representing a 32-bit value, for example, 2166653220 as in the code i posted. That string can be converted to an unsigned long using atol()
char s [90];
void
decode (
unsigned long val)
{
sprintf (s, "decode: %6lu 0x%08lx", val, val);
Serial.println (s);
for (int n = 0; n < 32; n++) {
sprintf (s, " %2d %ld", n, val & 1L);
Serial.println (s);
val >>= 1;
}
}
void loop() {
if (Serial.available ()) {
char packetBuffer [255];
int n = Serial.readBytesUntil ('\n', packetBuffer, sizeof(packetBuffer)-1);
packetBuffer [n] = '\0';
unsigned long val = atol(packetBuffer);
decode (val);
}
}
void setup() {
Serial.begin(115200);
}