ESP8266 Send / Receive Binary Data using UDP

Introduction

This is a quick introduction into using the ESP8266, more specifically the NodeMCU Dev Board, to send data in binary format over an existing WiFi network.

  • Rating – Easy
  • Total Cost – £1 + £6 if purchasing an ESP8266 NodeMCU breakout

Parts List

  • NodeMCU Dev Board (ESP8266 breakout with USB connectivity)
  • Breadboard
  • Jumper Wires
  • Resistor (appropriate resistance for the LED you use)
  • LED

Wiring Schematic

ESP8266_BinarySendDemo_Breadboard

ESP8266_BinarySendDemo_Schematic


Method

Firstly I need to point out that the NodeMCU pin numbers on the board DO NOT match up with the digital pin numbering when using the Arduino IDE. The Labels for GPIO number in the image below show how the NodeMCU pin number corresponds to digital and anlogue pin numbering in the Arduino IDE. Secondly you will need to install WiFiUDP library for arduino and the UDP library for processing.

Now go ahead and connect your LED and Resistor up as shown in the wiring diagrams between D1 and Ground. Now we have completed the Hardware setup I suggest you upload the Pin IO Test Code. You should see the LED flash on and off once per second.

Now there are a number of methods that could be used for transmitting data over WiFi to the ESP8266. I have chosen to use UDP because it is simple and offers an easy method to transmit data between ESP8266 modules and between a PC running a Processing Script. Now there is very little set up to do here Firstly edit these two lines with the details of the WiFi network that your laptop is connected to.

// wifi connection variables
const char* ssid = “yourSSIDHere”;
const char* password = “YourPasswordHere”;

Once this has been done upload the firmware to your NodeMCU dev board. Once it is uploaded open the serial port at 115200 Baud and you should something like this:

Connecting to WiFi
Connecting…….
Connected to NETGEAR70
IP address: 192.168.1.17

Now take the IP address which has been allocated to your ESP8266 and add it to the following line in your processing script. At this point you may also want to choose a different port (you will have to change it on the Arduino as well) if this number conflicts with something in your current network.

String ip = “192.168.1.17”; // the remote IP address
int port = 8888; // the destination port

Now you are ready to roll! Run the processing script. When you press and hold the space bar the LED should light up. You can also press f once to turn on flicker mode whereby the led will turn on and off continuously until you press f again.

Woo Hoo so it works… but how do you use this for another application? Well i’m not going to explain the UDP protocol, for that Wikipedia does a pretty good job, but I will show you the sections of code you need. On both sides you will need the appropriate UDP library.

On the Processing side to send data you form an array of bytes which you then send using the one line command below. It is easy to split integers and longs into bytes and then reassemble them on the other side.

byte[] message = new byte[2];
message[0] = 0;
message[1] = 0;
udp.send(message, ip , port);

To recieve a UDP packet in processing you use the following code. It utilises a default handler for when a UDP packet is received. Incoming data is stored in an array of byte much like the one used to send the data.

void receive( byte[] data ) { // <– default handler
//void receive( byte[] data, String ip, int port ) { // <– extended handler

for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}

To send data from the Arduino it is very similar but requires a few extra steps. You need to begin the packet, write the data to it and then use end packet to send the data. You also need to specify the size of the byte array.

byte message[2];
message[0] = 0;
message[1] = 1;
UDP.beginPacket(ip,localPort);
UDP.write(message,sizeof(message));
UDP.endPacket();

To receive Data on the Arduino. To avoid error you should check that there is a packet available (packet size not 0). It was read into a packetBuffer of the maximum possible packet size. so the packetSize variable is useful to check you actually received the right amount of data.

char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,

int packetSize = UDP.parsePacket();
if(packetSize)
{

UDP.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);

}

 


Arduino Code

Pin IO Test Code

void setup() {

// put your setup code here, to run once:
pinMode(5,OUTPUT);
}void loop() {
// put your main code here, to run repeatedly:
digitalWrite(5,HIGH);
delay(500);
digitalWrite(5,LOW);
delay(500);
}

Main Tutorial Code

#include <ESP8266WiFi.h>
#include <WiFiUDP.h>

// wifi connection variables
const char* ssid = “yourSSIDHere”;
const char* password = “YourPasswordHere”;
boolean wifiConnected = false;

// UDP variables
unsigned int localPort = 8888;
WiFiUDP UDP;
boolean udpConnected = false;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char ReplyBuffer[] = “acknowledged”; // a string to send back

void setup() {
// Initialise Serial connection
Serial.begin(115200);

// Initialise wifi connection
wifiConnected = connectWifi();

// only proceed if wifi connection successful
if(wifiConnected){
udpConnected = connectUDP();
if (udpConnected){
// initialise pins
pinMode(5,OUTPUT);
}
}
}

void loop() {
// check if the WiFi and UDP connections were successful
if(wifiConnected){
if(udpConnected){

// if there’s data available, read a packet
int packetSize = UDP.parsePacket();
if(packetSize)
{
Serial.println(“”);
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 packetBufffer
UDP.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println(“Contents:”);
int value = packetBuffer[0]*256 + packetBuffer[1];
Serial.println(value);

// send a reply, to the IP address and port that sent us the packet we received
UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());
UDP.write(ReplyBuffer);
UDP.endPacket();

// turn LED on or off depending on value recieved
digitalWrite(5,value);
}
delay(10);

}

}

}

// connect to UDP – returns true if successful or false if not
boolean connectUDP(){
boolean state = false;

Serial.println(“”);
Serial.println(“Connecting to UDP”);

if(UDP.begin(localPort) == 1){
Serial.println(“Connection successful”);
state = true;
}
else{
Serial.println(“Connection failed”);
}

return state;
}
// connect to wifi – returns true if successful or false if not
boolean connectWifi(){
boolean state = true;
int i = 0;
WiFi.begin(ssid, password);
Serial.println(“”);
Serial.println(“Connecting to WiFi”);

// Wait for connection
Serial.print(“Connecting”);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
if (i > 10){
state = false;
break;
}
i++;
}
if (state){
Serial.println(“”);
Serial.print(“Connected to “);
Serial.println(ssid);
Serial.print(“IP address: “);
Serial.println(WiFi.localIP());
}
else {
Serial.println(“”);
Serial.println(“Connection failed.”);
}
return state;
}

 


Processing Code

// Processing UDP example to send and receive binary data
// press f to toggel between LED flickering twice per second or not
// the LED will illuminate when any other key is held down and
// turn back off when the key is released.

import hypermedia.net.*;

UDP udp; // define the UDP object

String ip = “192.168.1.17”; // the remote IP address
int port = 8888; // the destination port

long previousMillis = 0;
int light = 0;
long interval = 500;
int flicker = 0;
int held = 0;

void setup() {
udp = new UDP( this, 8888 ); // create a new datagram connection on port 8888
//udp.log( true ); // <– printout the connection activity
udp.listen( true ); // and wait for incoming message
}

void draw()
{
if (flicker == 1){
if (previousMillis < millis() – interval){
previousMillis = previousMillis + interval;
if (light == 0){
byte[] message = new byte[2];
message[0] = 0;
message[1] = 0;
udp.send(message, ip , port);
light = 1;
}
else {
byte[] message = new byte[2];
message[0] = 0;
message[1] = 1;
udp.send(message, ip , port);
light = 0;
}
}
}
}

void keyPressed() {

if (key == ‘f’){
if (flicker == 1){
flicker = 0;
byte[] message = new byte[2];
message[0] = 0;
message[1] = 0;
udp.send(message, ip , port);
light = 0;
}
else{
flicker = 1;
}
}
else {
if (flicker == 0 && held == 0){
byte[] message = new byte[2];
message[0] = 0;
message[1] = 1;
udp.send(message, ip , port);
held = 1;
}
}
}

void keyReleased(){
if (key != ‘f’){
if (flicker == 0){
byte[] message = new byte[2];
message[0] = 0;
message[1] = 0;
udp.send(message, ip , port);
held = 0;
}
}
}

void receive( byte[] data ) { // <– default handler
//void receive( byte[] data, String ip, int port ) { // <– extended handler

for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}

24 thoughts on “ESP8266 Send / Receive Binary Data using UDP

    • The processing code is Java – if you google processing and arduino there is a website dedicated the to “processing” ide which is useful for interacting with arduino etc.

      Like

  1. If the Arduino is processing some data from a sensor and I want to send it using the ESP8266 to an iPad using the UDP protocol, can you tell me how I should modify the code above? I know it is in there somewhere but I can’t figure it out. Thanks.

    Like

    • Hi Dan,
      You can use some UDP apps on ipad to send and receive data from the sensor. the code on the esp8266 side won’t change (just maybe the data you send will change) and then some apps let you send and receive strings, others work a bit like remote controls and are only 1 way

      Like

  2. Hi !
    I have a little problem with my esp8266, I successed sending UDP packets (I checked it with Wireshark) but no matter what I try the esp don’t seem able to receive Usb packet !

    Any idea why ? Thanks!

    (Sorry if my English is not perfect I’m French)

    Like

    • Can you explain a bit more about what you can’t achieve over USB? UDP that the demo shows is only for transmitting the data of the WiFi connection. To communicate over the usb connection you have to use serial. There are plenty of examples of this as it is identical to the standard arduinl serial communication over usb

      Like

  3. Is the WiFiUDP.h library you use the original one of arduino or another one?
    If it is another one, could you provide it.

    Thanks.

    Like

    • I am not certain they are the same. The one I used was included with the node MCU board package that you can install using the idea board manager option. (I assume it is the same as the arduino one with the exception of any low level changes due to the different chip architecture)

      Like

  4. I’m actually using an Adafruit HUZZAH ESP8266 breakout, so I think the library you used would fit better for my setup too.

    Thanks.

    Like

  5. bonjour,
    avec le skecth de processing, je ne recois rien.

    la fonction receive ne semble jamais appelé par udp.

    j’utilise le port 5000.
    mon ESP et en 192.168.1.18.
    et envoi bien les paquets.

    je suis sous windows 10, processing 3.2.1.

    ou trouver la documentation sur la librairie UDP de processing.

    amicalement Pierre

    Like

  6. Hi there !

    First off all: thousand thanks to you for this tuto ! Best I’ve seen o’ this topic ok the web so far !

    Got a question for you: Is it possible to combine this code with a softwareserial in order to use Esp8266 as a gateway for computer ?
    I tried but stalling on the interrupt I guess.

    Thanks for your reply !
    Cause

    Like

    • Yea you could – you shouldn’t need software serial. The hardware serial through the USB port would work. You would just need to modify code to spit out the information iver serial when it is received. Additionally if the pc is connected to the WiFi you can send data directly to a script on the PC using the same method.

      Like

  7. i am getting the following error in arduino code:

    Arduino: 1.6.7 (Windows 10), Board: “NodeMCU 0.9 (ESP-12 Module), 80 MHz, 115200, 4M (3M SPIFFS)”

    C:\Users\Shaurya\Desktop\esp_udpi\esp_udpi.ino: In function ‘void setup()’:

    esp_udpi:21: error: ‘connectWifi’ was not declared in this scope

    wifiConnected = connectWifi();

    ^

    esp_udpi:25: error: ‘connectUDP’ was not declared in this scope

    udpConnected = connectUDP();

    ^

    exit status 1
    ‘connectWifi’ was not declared in this scope

    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.

    pls help me. thanks in advance

    Like

  8. Hello.
    Thanks for the tutorial. I applied the tutorial. It works very well between PC and ESP8266. But when I configure processing in android mode and I load the same code in my andoid phone it does not work. So between android phone and esp8266 the communication does not pass. Sorry i need help

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s