ESP8266 Sending Data Over Wi-Fi to another ESP8266

P1010244-e1524762751881.jpg

A simple guide to sending data from one ESP8266 to another over Wi-Fi using an ad-hoc, device to device network, without using a wifi router.

The ESP8266WebServer library allows you run an ESP8266 as a basic webserver and access point. This can process data received from a remote sensor over Wi-Fi without connecting the devices to a network or router.

For this tutorial I’m using two NodeMCU boards from eBay but you can do this with any ESP8266 based board. To simulate the output from a sensor I’m using a trim pot potentiometer like these from eBay. I’m also using two small OLED screens from AliExpress so you can see the data easily but you don’t need these if you want to see the results in the serial monitor.

As you can see in the video below, when the potentiometer pot is adjusted the value shown on the transmitting module OLED changes to reflect the change in voltage to pin A0. On the receiver, the value on the OLED is updated as the data is received from the transmitter.

If you don’t have the Arduino IDE set up for the ESP8266 range yet you can find a tutorial here – https://robotzero.one/heltec-wifi-kit-8/ under Setting Up the Arduino IDE for the ESP8266 Range.

I’m using these settings in the IDE (Tools menu) ..

NodeMCU IDE Settings

The wiring is identical for both the transmitter and receiver except the transmitting device has the potentiometer connected to the power and analogRead(A0) pins. You might need to connect the A0 pin via a resistor on some boards as they only read up to 1v on this pin.

ESP8266 to ESP8266 Wifi Wiring

ESP8266 to ESP8266 Wi-Fi Wiring Diagram

ESP8266 to ESP8266 Wifi Breadboard

ESP8266 to ESP8266 Wi-Fi Breadboard Layout

If it’s not installed already you will need to install the U8g2 display library (for the OLED) It can be installed using the Arduino IDE library manager – open Sketch > Include Library > Manage Libraries and search for and then install U8g2.

Here’s the sketch for the transmitter. There’s a more verbose version if you want to see the output in the serial monitor or need to debug here.

#include <ESP8266WiFi.h>
#include <U8g2lib.h>

//U8g2 Constructor List - https://github.com/olikraus/u8g2/wiki/u8g2setupcpp#introduction
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 5, /* data=*/ 4);

const char *ssid = "poopssid";
const char *password = "pingu4prez";

const int analogInPin = 0;  // Analog input pin that the potentiometer is attached to
int sensorValue = 0;        // value read from the potentiometer
int outputValue = 0;        // value sent to server

void setup() {
  Serial.begin(115200);
  delay(10);

  // Explicitly set the ESP8266 to be a WiFi-client
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  u8g2.begin();
  u8g2.setFont(u8g2_font_logisoso62_tn);
  u8g2.setFontMode(0);    // enable transparent mode, which is faster
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(A0);
  // map to range. The pot goes from about 3 to 1023. This makes the sent value be between 0 and 999 to fit on the OLED
  outputValue = map(sensorValue, 3, 1023, 0, 999);

  char intToPrint[5];
  itoa(outputValue, intToPrint, 10); //integer to string conversion for OLED library
  u8g2.firstPage();
  u8g2.drawUTF8(0, 64, intToPrint);
  u8g2.nextPage();

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const char * host = "192.168.4.1";
  const int httpPort = 80;

  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request. Something like /data/?sensor_reading=123
  String url = "/data/";
  url += "?sensor_reading=";
  url += intToPrint;

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }

  delay(500);
}

On the server (receiver) the sketch looks like this. Again, if you want a version with serial outputs to see more details you can download that here.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <U8g2lib.h>

//U8g2 Constructor List - https://github.com/olikraus/u8g2/wiki/u8g2setupcpp#introduction
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 5, /* data=*/ 4);

const char *ssid = "poopssid";
const char *password = "pingu4prez";

ESP8266WebServer server(80);

void handleSentVar() {
  if (server.hasArg("sensor_reading")) { // this is the variable sent from the client
    int readingInt = server.arg("sensor_reading").toInt();
    char readingToPrint[5];
    itoa(readingInt, readingToPrint, 10); //integer to string conversion for OLED library
    u8g2.firstPage();
    u8g2.drawUTF8(0, 64, readingToPrint);
    u8g2.nextPage();
    server.send(200, "text/html", "Data received");
  }
}

void setup() {
  delay(1000);

  u8g2.begin();
  u8g2.setFont(u8g2_font_logisoso62_tn);
  u8g2.setFontMode(0);    // enable transparent mode, which is faster

  WiFi.softAP(ssid, password);
  IPAddress myIP = WiFi.softAPIP();

  server.on("/data/", HTTP_GET, handleSentVar); // when the server receives a request with /data/ in the string then run the handleSentVar function
  server.begin();
}

void loop() {
  server.handleClient();
}

Hopefully this tutorial helps you start off in the right direction with using Wi-Fi on these devices. I’ve seen other tutorials that made things a lot more complicated than they need to be.

35 Replies to “ESP8266 Sending Data Over Wi-Fi to another ESP8266”

  1. dave says:

    Thanks for posting this.
    I am trying to have ESP8266 units and send temperatures. one in the basement, one in the attic all to the one near the WiFi router. 2 sending, 1 receiving

    1. WordBot says:

      You’ll need to change the query string sent so the receiving ESP will know which one sent the data. Something like:
      Basement ESP: ?sensor_reading_basement=
      Attic ESP: ?sensor_reading_attic=

      On the receiver you’ll need a smaller font to fit everything on the screen and change the handleSentVar to listen to the two new variables above. This system doesn’t use your WiFi, it runs on its own network.

  2. Mauro says:

    Hi, is it possible to send sensor value from an esp8266 to an esp32 with the same technic ?

    best regards

    1. WordBot says:

      Yep. The data is sent as a GET request like this: /data/?sensor_reading=123 so any web server can parse the information and use it. I’m not sure exactly which libraries you need but the ESP32 has equivalents to the ESP8266WiFi and ESP8266WebServer libraries.

  3. Alexander says:

    Hello! Could you help me a little bit? I just want to send an int value from one esp board to other.
    I’ve connetcted a pontentiometer on the first esp(Wemos D1 mini), and gets a value using map() function. I want to send it to the second board for changing blink interval of LED.
    I tried to change your sketch, but got no luck =(.

    Thank you in advance!

    1. WordBot says:

      Hi there.
      First check the simple blink sketch works:

      void setup() {
      pinMode(BUILTIN_LED, OUTPUT); // initialize onboard LED as output
      }
      void loop() {
      digitalWrite(BUILTIN_LED, HIGH); // turn on LED with voltage HIGH
      delay(1000); // wait one second
      digitalWrite(BUILTIN_LED, LOW); // turn off LED with voltage LOW
      delay(1000); // wait one second
      }

      If that’s OK then something like the following might work. I don’t have the project set up at the moment.

      #include < ESP8266WiFi.h > //(remove spaces – wordpress comment workaround)
      #include < ESP8266WebServer.h >

      const char *ssid = “poopssid”;
      const char *password = “pingu4prez”;

      int varDelay = 1000;
      int ledState = LOW;
      unsigned long previousMillis = 0;

      ESP8266WebServer server(80);

      void handleSentVar() {
      if (server.hasArg(“sensor_reading”)) {
      varDelay = server.arg(“sensor_reading”).toInt();
      server.send(200, “text/html”, “Data received”);
      }
      }

      void setup() {
      delay(1000);
      pinMode(BUILTIN_LED, OUTPUT);
      WiFi.softAP(ssid, password);
      IPAddress myIP = WiFi.softAPIP();
      server.on(“/data/”, HTTP_GET, handleSentVar);
      server.begin();
      }

      void loop() {
      server.handleClient();

      unsigned long currentMillis = millis();
      // if enough millis have elapsed
      if (currentMillis – previousMillis >= varDelay) {
      previousMillis = currentMillis;

      // toggle the LED
      ledState = !ledState;
      digitalWrite(BUILTIN_LED, ledState);
      }
      }

      1. Alexander says:

        Yeah! =) It works. Thank you so much!

  4. kave says:

    hi,
    It`s very useful project
    I need help for my project,
    I want to send data via serial form ESP-12 to ESP-01 , That way one RC522 RFID connect to ESP-12 and read tag card and it should be send tag to the ESP-01 with high speed like your project.
    Thanks so much if you can help me 🙂

    1. WordBot says:

      Hi,
      Do you have the code for the reading the tag? In that code you just need to have it send the data in the same way the transmitter code above sends data to the other ESP.

  5. Ron says:

    Hi,

    Thanks for the example. It saves me a lot of work/time finding out the wheel as I’m a basic electronics engineer and not a TCP/IP/HTML specialist. I’m lazy and have replaced the potmeter for a random generator and the output is written to a serial monitor. All seems to work fine however in my example I have contineously timeouts on client.connect() and client.available(). Any suggestions?

    1. WordBot says:

      Hi,
      At a guess I would say that there are too many connection attempts for the webserver in the ESP8266. Maybe try a delay() command in the loop to slow down the connection attempts? Or if you are feeling brave you could try another webserver: https://github.com/me-no-dev/ESPAsyncWebServer

  6. Tudor says:

    HI,
    I try to do a project in which I have 2 transmitters and one receiver. Each transmitter has a switch and if I press the switch (from a transmitter or the other transmitter) the LED on the receiver should go on. Could you please help me? Thank you.

    1. WordBot says:

      It shouldn’t be too hard. Both transmitters would have the same code that detects the button press and sends this in the URL “?sensor_reading=on”; to the listening receiver. On the receiver you would set the LED high in the handleSentVar() function.

      1. Tudor says:

        Thank you. I am a beginner. Could you please help me with the code? I do not understand exactly which lines should I keep and which not.

        1. WordBot says:

          If you are new to this you should break it down into small parts so you can understand what is happening so you can work with it later. The first thing you need is add a switch to the transmitter. The simplest way (not necessarily the best) is to pull the pin connected to the onboard LED to ground with a your switch (or just connect D4 to GND with a piece of wire).

          Then use the code below to see the change in the serial monitor:

          const int button = 2; // D4/GPIO2 is connected to the internal LED (which is lit when the pin is LOW).
          int pinState= 0;

          void setup() {
          Serial.begin(9600);
          pinMode(button, INPUT);
          }

          void loop() {
          pinState = digitalRead(button);
          if (pinState == LOW) {
          Serial.println(“LED Turned ON”);
          delay(1000);
          }
          else {
          Serial.println(“LED Turned OFF”);
          delay(1000);
          }
          }

        2. WordBot says:

          Then you need to edit the code in the tutorialfor the transmitter so it sends the button state rather than the sensor reading something like this:

          String url = “/data/”;
          url += “?button_state=”;
          url += pinState;

  7. Mitchell says:

    Hi, cool project with great info! I want to output the potentiometer reading via pwm instead of seeing the value on screen. Could you guide me on the coding portion?

    1. WordBot says:

      Do you have the code for the PWM part on the receiver? It shouldn’t be too hard to change the code in the tutorial to update the PWM code rather than the screen.

      1. Mitchell says:

        No I have very basic understanding of programming. I usually troll tutorials such as this looking for code similar to what I need and then try to stitch the bits together 🙁

        1. Mitchell says:

          I have your original code with the oled portions omitted on both mcu

          1. WordBot says:

            I don’t really have time to look at this but if you ask on the forum here – https://www.esp8266.com/ someone will probably help. Tell them how far you’ve got and what you want to achieve.

  8. hassan11 says:

    can you help me i need code to send data between two esp32 , data from sensors in one esp32 to onther

    1. WordBot says:

      The code should be mostly the same. You’ll need to use different libraries for the wifi and wifi server and possibly change the pins for the oleds if you are using them.

  9. Arduino93 says:

    i used this code to transmit the data from esp32 and they connected together but sensorValue still constant at “4095” in both esp32 , what should i do ?

    1. WordBot says:

      Do you have code similar to this on the transmitter so you can see the output from the sensor:

      // read the analog in value:
      sensorValue = analogRead(A0);

      // map to range. The pot goes from about 3 to 1023. This makes the sent value be between 0 and 999 to fit on the OLED
      outputValue = map(sensorValue, 3, 1023, 0, 999);

      // print the results to the Serial Monitor:
      Serial.print(“sensor = “);
      Serial.print(sensorValue);
      Serial.print(“\t output = “);
      Serial.println(outputValue);

  10. Safei says:

    this code is work correctly with me ..
    but i wanna send 5 values from esp instead of 1 value and save values in the other esp , what edits can i do ?
    Thank you in advance

    1. WordBot says:

      So you want to take 5 sensor values and send them together? You can just make 5 variables to hold each one and send it like this.
      url += “?sensor_reading1=”;
      url += intToPrint1;
      url += “?sensor_reading2=”;
      url += intToPrint2;
      etc…

      Or maybe a tidier way is to put them all into one string, send that and process it on the other side. One way of sending strings: https://randomnerdtutorials.com/decoding-and-encoding-json-with-arduino-or-esp8266/

      1. Safei says:

        I already do this but it didn’t receive values in the other esp and it display “Client Timeout !” in serial monitor of transmitter esp …

        Thank u very much for your support .

        1. WordBot says:

          Client timeout is not connecting to your WiFi. Try some of the ESP8266 Wifi examples to get this working. It’s always best to start simple and then add things bit by bit to check as you go. If you are new to this.. it’s much better to do that than try and edit a more complicated script to fit your case.

  11. Dieffy says:

    In your example the oled on the receiver is updating very quickly. I implemented the example code on two of my nodeMCU’s and I get a much slower response time. Did you use a different code for the video? Thanks for the tutorial by the way.

    1. WordBot says:

      It’s the same script. In the tutorial there’s a version with more output on the serial port which might help diagnose. Someone in the comments said theirs worked better with this line:
      WiFi.mode(WIFI_AP);
      added above this line:
      WiFi.softAP(ssid, password);
      in the receiver code but this isn’t in the examples code I developed this from.

  12. drdra says:

    Hey WordBot, thanks for your patience, can you tell me how can I send to multiple receivers?

    1. WordBot says:

      Looking quickly at this. If you take the part // We now create a URI for the request. Something like /data/?sensor_reading=123 and turn it into a function. Then take this part // Use WiFiClient class to create TCP connections and do something like

      const char * host = “192.168.4.1”;
      const int httpPort = 80;
      if (client.connect(host, httpPort)) {
      // new function here
      }

      Once you have that working the same as the existing example you can then make it a loop that loops through the IP addresses you have for the clients.

  13. Jeevan says:

    Hi

    the project you have explained in a crispy and simple way thanks for the new thing which I learned from you.
    But when I am trying to compile your code I am getting an error saying

    WARNING: Spurious .github folder in ‘Adafruit Fingerprint Sensor Library’ library
    WARNING: Spurious .github folder in ‘Adafruit GPS Library’ library
    WARNING: Spurious .github folder in ‘RTClib’ library
    In file included from C:\Users\KERNEL\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0/tools/sdk/lwip2/include/lwip/opt.h:51:0,

    from C:\Users\KERNEL\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0/tools/sdk/lwip2/include/lwip/init.h:40,

    from C:\Users\KERNEL\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/IPAddress.h:27,

    from C:\Users\KERNEL\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:31,

    from C:\Users\KERNEL\Documents\Arduino\NodeMCU_Transmitter\NodeMCU_Transmitter.ino:1:

    C:\Users\KERNEL\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0/tools/sdk/lwip2/include/lwipopts.h:1301:2: error: #error TCP_MSS must be defined

    #error TCP_MSS must be defined

    I am not getting this error what actually its saying. Please help me ,thanks in advance

    1. WordBot says:

      Your installation for the ESP8266 package is bad. How did you set up the esp8266 library? There’s a tutorial on this page for that: https://robotzero.one/heltec-wifi-kit-8/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

scroll to top