Are you wanting to learn how to quickly and easily link two ESP8266 modules using Arduino?
This article provides an easy step-by-step solution and you don’t even need a router!
In order to get you up and running quickly, we shall be using UDP due to its simplicity.
Both client and server examples will be given in this tutorial, simplified in order to help you understand how to implement them in your own application.
Table of Contents
Prerequisite
You will need to have the Arduino IDE installed and configured to flash ESP devices. You will also need two ESP-based boards such as the Wemos D1 Mini, you can get them here on Amazon.
I would recommend that you first follow my tutorials on how to configure the Arduino IDE for ESP devices and how to send and receive data using UDP on ESP devices in order to gain some basic understanding if you are new to ESP devices and Arduino.
Sending data with UDP
We will create a client and server application to run on each of the ESP devices. The server will act as a WiFi access point and the client will connect to this access point.
Once a connection has been established it will be possible to send UDP data packets back and forth between the two ESP devices. For this example we will read a digital pin on the client and send the state over UDP to the server.
The server will then operate the onboard LED depending on the state of the pin on the client.
This example is similar to the “button” sketch (see examples > digital > button from the file menu in the Arduino IDE), however we are connecting the button to the LED over WiFi. Awesome!
Server
First we need to create a new sketch in Arduino for the server. Once complete we can go ahead and load this onto the ESP device that we want to function as the server.
Add the libraries
First we need to include the ESP8266WiFi and WiFiUdp libraries. If you have not yet installed the libraries or setup the Arduino IDE for ESP devices, go ahead and check out my tutorial on how to configure the Arduino IDE for ESP devices.
#include <ESP8266WiFi.h> #include <WiFiUdp.h>
Set access point credentials
Next we need to define the WiFi credentials for the access point. Feel free to specify your own credentials here but make a note of them as we will need them when writing the client application.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set AP credentials #define AP_SSID "TheOtherESP" #define AP_PASS "flashmeifyoucan"
Configure UDP
We will specify the IP address of the server as local_ip so that we can use it when writing the client application. It is not essential that you specify the IP address but you will need to ensure that the client is connecting to the server IP address in your own application.
The gateway should match the local IP address and the subnet mask should be left set as specified here. We also need to define a port used for UDP communication, you can change this value if you prefer to use a different port.
We will also create a buffer for received UDP packets called packetBuffer. This is a defined area in memory where we can hold the received packets when they arrive from the client application.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set AP credentials #define AP_SSID "TheOtherESP" #define AP_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress local_IP(192,168,4,1); IPAddress gateway(192,168,4,1); IPAddress subnet(255,255,255,0); #define UDP_PORT 4210 // UDP Buffer char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
Setup LED
As we will be receiving a UDP packet and using the contents of the first byte to set the state of the LED, we must define the physical LED pin as an output.
I am using a pair of Wemos D1 Mini ESP boards which use Arduino pin 2 to control the onboard LED (even though the pin is labelled as D4). You should change this to suit your device if you are using a different board.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set AP credentials #define AP_SSID "TheOtherESP" #define AP_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress local_IP(192,168,4,1); IPAddress gateway(192,168,4,1); IPAddress subnet(255,255,255,0); #define UDP_PORT 4210 // UDP Buffer char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; void setup() { // Setup LED pin pinMode(2, OUTPUT);
Setup serial port
Next we will setup the serial port in order to receive information in the serial console. This is not essential for this project but it can be useful for debugging.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set AP credentials #define AP_SSID "TheOtherESP" #define AP_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress local_IP(192,168,4,1); IPAddress gateway(192,168,4,1); IPAddress subnet(255,255,255,0); #define UDP_PORT 4210 // UDP Buffer char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; void setup() { // Setup LED pin pinMode(2, OUTPUT); // Setup serial port Serial.begin(115200); Serial.println();
Begin access point
Now we can begin the access point using the setup that we have defined. For more information on this code see my tutorial on how to configure the Arduino IDE for ESP devices.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set AP credentials #define AP_SSID "TheOtherESP" #define AP_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress local_IP(192,168,4,1); IPAddress gateway(192,168,4,1); IPAddress subnet(255,255,255,0); #define UDP_PORT 4210 // UDP Buffer char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; void setup() { // Setup LED pin pinMode(2, OUTPUT); // Setup serial port Serial.begin(115200); Serial.println(); // Begin Access Point Serial.println("Starting access point..."); WiFi.softAPConfig(local_IP, gateway, subnet); WiFi.softAP(AP_SSID, AP_PASS); Serial.println(WiFi.localIP());
Begin listening to UDP port
We also need to begin listening to the specified UDP port. The serial console commands are simply for debugging, so that we can see the device has successfully started listening to the port.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set AP credentials #define AP_SSID "TheOtherESP" #define AP_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress local_IP(192,168,4,1); IPAddress gateway(192,168,4,1); IPAddress subnet(255,255,255,0); #define UDP_PORT 4210 // UDP Buffer char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; void setup() { // Setup LED pin pinMode(2, OUTPUT); // Setup serial port Serial.begin(115200); Serial.println(); // Begin Access Point Serial.println("Starting access point..."); WiFi.softAPConfig(local_IP, gateway, subnet); WiFi.softAP(AP_SSID, AP_PASS); Serial.println(WiFi.localIP()); // Begin listening to UDP port UDP.begin(UDP_PORT); Serial.print("Listening on UDP port "); Serial.println(UDP_PORT);
Handle receive packet
The last thing we need to do is handle a packet received from the client application. The packet is read and placed in the packetBuffer.
The client application will put the button state into the first byte of the buffer, therefore we can set the state of the LED based upon the first byte of the buffer, packetBuffer[0].
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set AP credentials #define AP_SSID "TheOtherESP" #define AP_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress local_IP(192,168,4,1); IPAddress gateway(192,168,4,1); IPAddress subnet(255,255,255,0); #define UDP_PORT 4210 // UDP Buffer char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; void setup() { // Setup LED pin pinMode(2, OUTPUT); // Setup serial port Serial.begin(115200); Serial.println(); // Begin Access Point Serial.println("Starting access point..."); WiFi.softAPConfig(local_IP, gateway, subnet); WiFi.softAP(AP_SSID, AP_PASS); Serial.println(WiFi.localIP()); // Begin listening to UDP port UDP.begin(UDP_PORT); Serial.print("Listening on UDP port "); Serial.println(UDP_PORT); } void loop() { // Receive packet UDP.parsePacket(); UDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); if (packetBuffer[0]){ digitalWrite(2, HIGH); } else { digitalWrite(2, LOW); } }
Client
Now we have completed the server application, we can create a client application for a second ESP board. Go ahead and create a new sketch for the client application.
Add the libraries
First we need to include the ESP8266WiFi and WiFiUdp libraries. If you have not yet installed the libraries or setup the Arduino IDE for ESP devices, go ahead and check out my tutorial on how to configure the Arduino IDE for ESP devices.
#include <ESP8266WiFi.h> #include <WiFiUdp.h>
Set WiFi credentials
Next we need to set the WiFi network credentials. As we are connecting directly to the access point setup in our server application, we need to specify the same SSID and password that we used for the server.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set WiFi credentials #define WIFI_SSID "TheOtherESP" #define WIFI_PASS "flashmeifyoucan"
Configure UDP
We will specify the remote_IP address as the same address that we gave to the server, as this is where we wish to send our packets of data. We also need to specify the same port.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set WiFi credentials #define WIFI_SSID "TheOtherESP" #define WIFI_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress remote_IP(192,168,4,1); #define UDP_PORT 4210
Setup input pin
As we will be connecting a button to this ESP device to control the LED on the other ESP device, we need to define the pin connected to the button as an input pin. I am using pin 2 for the button but you can choose any pin you like.
If you don’t have a button handy you can just connect a wire between the pin and GND. When the pin is connected to GND the state of the pin will be low and with the wire removed the state of the pin will be high.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set WiFi credentials #define WIFI_SSID "TheOtherESP" #define WIFI_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress remote_IP(192,168,4,1); #define UDP_PORT 4210 void setup() { // Setup IO pinMode(2, INPUT);
Setup serial port
Next we will setup the serial port in order to receive information in the serial console. This is not essential for this project but it can be useful for debugging.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set WiFi credentials #define WIFI_SSID "TheOtherESP" #define WIFI_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress remote_IP(192,168,4,1); #define UDP_PORT 4210 void setup() { // Setup IO pinMode(2, INPUT); // Setup serial port Serial.begin(115200); Serial.println();
Connect to WiFi
We will connect to the ESP device running the server application using the basic WiFi connection code. If you want a more detailed explanation on how this works, go check out check out the WiFi section of this tutorial.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set WiFi credentials #define WIFI_SSID "TheOtherESP" #define WIFI_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress remote_IP(192,168,4,1); #define UDP_PORT 4210 void setup() { // Setup IO pinMode(2, INPUT); // Setup serial port Serial.begin(115200); Serial.println(); // Begin WiFi WiFi.begin(WIFI_SSID, WIFI_PASS); WiFi.mode(WIFI_STA); // Connecting to WiFi... Serial.print("Connecting to "); Serial.print(WIFI_SSID); // Loop continuously while WiFi is not connected while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print("."); } // Connected to WiFi Serial.println(); Serial.print("Connected! IP address: "); Serial.println(WiFi.localIP());
Open UDP port
We also need to open the specified UDP port to make a connection with the server. The serial console commands are simply for debugging, so that we can see the device has successfully opened the port.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set WiFi credentials #define WIFI_SSID "TheOtherESP" #define WIFI_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress remote_IP(192,168,4,1); #define UDP_PORT 4210 void setup() { // Setup IO pinMode(2, INPUT); // Setup serial port Serial.begin(115200); Serial.println(); // Begin WiFi WiFi.begin(WIFI_SSID, WIFI_PASS); WiFi.mode(WIFI_STA); // Connecting to WiFi... Serial.print("Connecting to "); Serial.print(WIFI_SSID); // Loop continuously while WiFi is not connected while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print("."); } // Connected to WiFi Serial.println(); Serial.print("Connected! IP address: "); Serial.println(WiFi.localIP()); // Begin UDP port UDP.begin(UDP_PORT); Serial.print("Opening UDP port "); Serial.println(UDP_PORT);
Read button
The first thing we need to do in our continuous loop is read the button connected to pin 2 and place the value into a variable.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set WiFi credentials #define WIFI_SSID "TheOtherESP" #define WIFI_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress remote_IP(192,168,4,1); #define UDP_PORT 4210 void setup() { // Setup IO pinMode(2, INPUT); // Setup serial port Serial.begin(115200); Serial.println(); // Begin WiFi WiFi.begin(WIFI_SSID, WIFI_PASS); WiFi.mode(WIFI_STA); // Connecting to WiFi... Serial.print("Connecting to "); Serial.print(WIFI_SSID); // Loop continuously while WiFi is not connected while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print("."); } // Connected to WiFi Serial.println(); Serial.print("Connected! IP address: "); Serial.println(WiFi.localIP()); // Begin UDP port UDP.begin(UDP_PORT); Serial.print("Opening UDP port "); Serial.println(UDP_PORT); } void loop() { // Read button char buttonState = digitalRead(2);
Send packet
Finally we can send the state of the button to the server. First we must begin a packet and specify the destination IP address and port. Then we can write our buttonState to the outgoing packet buffer before ending the packet.
We will also include a short delay so that the packets to not fire too quickly. A more sophisticated version of this code would only transmit a packet when the button changes state, however I wanted to keep this example simple.
#include <ESP8266WiFi.h> #include <WiFiUdp.h> // Set WiFi credentials #define WIFI_SSID "TheOtherESP" #define WIFI_PASS "flashmeifyoucan" // UDP WiFiUDP UDP; IPAddress remote_IP(192,168,4,1); #define UDP_PORT 4210 void setup() { // Setup IO pinMode(2, INPUT); // Setup serial port Serial.begin(115200); Serial.println(); // Begin WiFi WiFi.begin(WIFI_SSID, WIFI_PASS); WiFi.mode(WIFI_STA); // Connecting to WiFi... Serial.print("Connecting to "); Serial.print(WIFI_SSID); // Loop continuously while WiFi is not connected while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print("."); } // Connected to WiFi Serial.println(); Serial.print("Connected! IP address: "); Serial.println(WiFi.localIP()); // Begin UDP port UDP.begin(UDP_PORT); Serial.print("Opening UDP port "); Serial.println(UDP_PORT); } void loop() { // Read button char buttonState = digitalRead(2); // Send Packet UDP.beginPacket(remote_IP, UDP_PORT); UDP.write(buttonState); UDP.endPacket(); delay(100); }
Conclusion
In this article we have looked at both the client and server application required for getting two ESP devices to communicate using the Arduino core.
Although this is a simple example it would be easy to expand on the functionality.
Why not go ahead and check out some of my other tutorials for awesome ESP devices next, such as how to build a super-tiny web server!
Dear,
Congratulations on your excellent work and contribution. Your post was very didactic and will help us a lot.
I ask if you have any post with server and client with LoRa radio? If not, you could tell me where I can get it.
I am developing a work to receive signal from a DS18B20 temperature sensor installed at 1000m distance of my house. That’s why I need to use LoRa radio.
Thank you.
Carlos Mota