Arduino ESP8266 UDP communication that makes sense
I am working on a way to get 433 door sensors into a real automation system like Crestron without using a RS232 port but instead leveraging the dirt cheap ESP8266. I decided for simplicity I want to simply do a UDP broadcast on my network of whatever sensor was last tripped that means I dont have to do any configuration to find and configure the device. I just listen for UDP broadcasts on a specific port.
This also can be used to auto configure your ESP devices. let them listen on a broadcast port and reply with their IP Address. so I decided to generate some code to do just that.
Sadly I ran into a problem right away. Arduino libraries are as poorly documented as C# libraries. By looking up the documentation on the WiFiUdp.h module you get the bare minimum of info that assumes you know the module already inside and out. In reality this is not the case and extremely far from it. One of the most important things they miss is what the hell does Udp.write() want? I assumed a string, WRONG. It needs a Char array. that means you have to convert everything to a char array when you are ready to send it. It would be nice of the author to tell you this, but it's the current trend in library documentation is to hide any and all details like that and you are supposed to just know what they want.
So Below is a example program that sets up a ESP8266 onto a wifi network and listens on One port and responds on the port higher. You do not have to use separate ports, you can absolutely talk and listen on the same port, just understand that when you go to the broadcast address of the network you are going to be running into everyone else's broadcast traffic.
Is this clean and complete? nope. but it solved the issues I was running into and all the Google searches out there were cryptic and vague. The answer was the collection of about 10 forum posts and a couple of AHA moments.
https://gist.github.com/timgray/77b0f5d696616420a8722f8fae53a901
#include
#include
const char* ssid = "MySSID";
const char* password = "SecretPassword";
WiFiUDP Udp;
unsigned int localUdpPort = 4210; // local port to listen on
char incomingPacket[255]; // buffer for incoming packets
char replyPacket[] = "Hi there! Got the message :-) "; // a reply string to send back
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting to %s ", ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");
Udp.begin(localUdpPort);
Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}
void loop()
{
int packetSize = Udp.parsePacket();
if (packetSize)
{
// receive incoming UDP packets
Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
}
Serial.printf("UDP packet contents: %s\n", incomingPacket);
// send back a reply, to the IP address and port we got the packet from
Udp.beginPacket("192.168.41.255", localUdpPort+1);
Udp.write(replyPacket);
Udp.endPacket();
String tmp = incomingPacket;
if(tmp.indexOf("STATUS") >= 0)
{
// lets send back our IP address
String temp = "ADDR:"+ WiFi.localIP().toString();
temp.toCharArray(replyPacket,temp.length());
Udp.beginPacket("255.255.255.255", localUdpPort+1);
Udp.write(replyPacket);
Udp.endPacket();
}
if(tmp.indexOf("RSSI") >= 0)
{
int mysignal = WiFi.RSSI(); // get the signal strength
String temp = "RSSI:"+ String(mysignal);
temp.toCharArray(replyPacket,temp.length());
Udp.beginPacket("255.255.255.255", localUdpPort+1);
Udp.write(replyPacket);
Udp.endPacket();
}
}
}
This also can be used to auto configure your ESP devices. let them listen on a broadcast port and reply with their IP Address. so I decided to generate some code to do just that.
Sadly I ran into a problem right away. Arduino libraries are as poorly documented as C# libraries. By looking up the documentation on the WiFiUdp.h module you get the bare minimum of info that assumes you know the module already inside and out. In reality this is not the case and extremely far from it. One of the most important things they miss is what the hell does Udp.write() want? I assumed a string, WRONG. It needs a Char array. that means you have to convert everything to a char array when you are ready to send it. It would be nice of the author to tell you this, but it's the current trend in library documentation is to hide any and all details like that and you are supposed to just know what they want.
So Below is a example program that sets up a ESP8266 onto a wifi network and listens on One port and responds on the port higher. You do not have to use separate ports, you can absolutely talk and listen on the same port, just understand that when you go to the broadcast address of the network you are going to be running into everyone else's broadcast traffic.
Is this clean and complete? nope. but it solved the issues I was running into and all the Google searches out there were cryptic and vague. The answer was the collection of about 10 forum posts and a couple of AHA moments.
https://gist.github.com/timgray/77b0f5d696616420a8722f8fae53a901
#include
#include
const char* ssid = "MySSID";
const char* password = "SecretPassword";
WiFiUDP Udp;
unsigned int localUdpPort = 4210; // local port to listen on
char incomingPacket[255]; // buffer for incoming packets
char replyPacket[] = "Hi there! Got the message :-) "; // a reply string to send back
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting to %s ", ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");
Udp.begin(localUdpPort);
Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}
void loop()
{
int packetSize = Udp.parsePacket();
if (packetSize)
{
// receive incoming UDP packets
Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
}
Serial.printf("UDP packet contents: %s\n", incomingPacket);
// send back a reply, to the IP address and port we got the packet from
Udp.beginPacket("192.168.41.255", localUdpPort+1);
Udp.write(replyPacket);
Udp.endPacket();
String tmp = incomingPacket;
if(tmp.indexOf("STATUS") >= 0)
{
// lets send back our IP address
String temp = "ADDR:"+ WiFi.localIP().toString();
temp.toCharArray(replyPacket,temp.length());
Udp.beginPacket("255.255.255.255", localUdpPort+1);
Udp.write(replyPacket);
Udp.endPacket();
}
if(tmp.indexOf("RSSI") >= 0)
{
int mysignal = WiFi.RSSI(); // get the signal strength
String temp = "RSSI:"+ String(mysignal);
temp.toCharArray(replyPacket,temp.length());
Udp.beginPacket("255.255.255.255", localUdpPort+1);
Udp.write(replyPacket);
Udp.endPacket();
}
}
}
Comments
Post a Comment