Getting Started with ESP-NOW (ESP8266 NodeMCU with Arduino IDE)

In this article, we’ll show you how you can use ESP-NOW to exchange data between ESP8266 NodeMCU boards programmed with Arduino IDE. ESP-NOW is a connectionless communication protocol developed by Espressif that features short packet transmission and can be used with ESP8266 and ESP32 boards.

Getting Started with ESP-NOW ESP8266 NodeMCU with Arduino IDE

We have other tutorials about ESP-NOW with the ESP8266:

Arduino IDE

We’ll program the ESP8266 NodeMCU board using Arduino IDE, so before proceeding with this tutorial you should have the ESP8266 add-on installed in your Arduino IDE. Follow the next guide:

Note: we have a similar guide for the ESP32: Getting Started with ESP-NOW (ESP32 with Arduino IDE).

Introducing ESP-NOW

The following video shows an introduction to ESP-NOW. This video was recorded for the ESP32, but most concepts also apply to the ESP8266 NodeMCU board.

Stating Espressif website, ESP-NOW is a “protocol developed by Espressif, which enables multiple devices to communicate with one another without using Wi-Fi. The protocol is similar to the low-power 2.4GHz wireless connectivity (…) . The pairing between devices is needed prior to their communication. After the pairing is done, the connection is safe and peer-to-peer, with no handshake being required.”

ESP-NOW - ESP32 Logo

This means that after pairing a device with each other, the connection is persistent. In other words, if suddenly one of your boards loses power or resets, when it restarts, it will automatically connect to its peer to continue the communication.

ESP-NOW supports the following features:

  • Encrypted and unencrypted unicast communication;
  • Mixed encrypted and unencrypted peer devices;
  • Up to 250-byte payload can be carried;
  • Sending callback function that can be set to inform the application layer of
    transmission success or failure.

ESP-NOW technology also has the following limitations:

  • Limited encrypted peers. 10 encrypted peers at the most are supported in Station mode; 6 at the most in SoftAP or SoftAP + Station mode;
  • Multiple unencrypted peers are supported, however, their total number should be less than 20, including encrypted peers;
  • Payload is limited to 250 bytes.

In simple words, ESP-NOW is a fast communication protocol that can be used to exchange small messages (up to 250 bytes) between ESP8266 boards.

ESP-NOW is very versatile and you can have one-way or two-way communication in different setups.

ESP-NOW One-Way Communication

For example, in one-way communication, you can have scenarios like this:

  • One ESP8266 board sending data to another ESP8266 board
ESP8266 ESP-NOW One-way Communication

This configuration is very easy to implement and it is great to send data from one board to the other like sensor readings or ON and OFF commands to control GPIOs.

  • A “master” ESP8266 sending data to multiple ESP8266 “slaves”

One ESP8266 board sending the same or different commands to different ESP8266 boards. This configuration is ideal to build something like a remote control. You can have several ESP8266 boards around the house that are controlled by one main ESP8266 board.

ESP-NOW master ESP8266 sending data to multiple ESP8266 slaves
  • One ESP8266 “slave” receiving data from multiple “masters”

This configuration is ideal if you want to collect data from several sensors nodes into one ESP8266 board. This can be configured as a web server to display data from all the other boards, for example.

ESP-NOW one ESP32 slave receiving data from multiple masters

Note: in the ESP-NOW documentation there isn’t such thing as “sender/master” and “receiver/slave”. Every board can be a sender or receiver. However, to keep things clear we’ll use the terms “sender” and “receiver” or “master” and “slave”.

ESP-NOW Two-Way Communication

With ESP-NOW, each board can be a sender and a receiver at the same time. So, you can establish a two-way communication between boards.

For example, you can have two boards communicating with each other.

ESP8266 ESP-NOW Two-way Communication

You can add more boards to this configuration and have something that looks like a network (all ESP8266 boards communicate with each other).

ESP-NOW two-way communication between multiple ESP8266 boards

In summary, ESP-NOW is ideal to build a network in which you can have several ESP8266 boards exchanging data with each other.

ESP8266: Getting Board MAC Address

To communicate via ESP-NOW, you need to know the MAC Address of the ESP8266 receiver. That’s how you know to which device you’ll send the information to.

Each ESP8266 has a unique MAC Address and that’s how we identify each board to send data to it using ESP-NOW (learn how to Get and Change the ESP8266 MAC Address).

To get your board’s MAC Address, upload the following code.

/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/get-change-esp32-esp8266-mac-address-arduino/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.  
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <ESP8266WiFi.h>

void setup(){
  Serial.begin(115200);
  Serial.println();
  Serial.print("ESP Board MAC Address:  ");
  Serial.println(WiFi.macAddress());
}
 
void loop(){

}

View raw code

After uploading the code, open the Serial Monitor at a baud rate of 115200 and press the ESP8266 RESET button. The MAC address should be printed as follows:

ESP-NOW ESP32 Getting Board MAC Address

Save your board MAC address because you’ll need it to send data to the right board via ESP-NOW.

ESP-NOW One-way Point to Point Communication with ESP8266

To get you started with ESP-NOW wireless communication, we’ll build a simple project that shows how to send a message from one ESP8266 to another. One ESP8266 will act as a “sender” and the other ESP8266 will be the “receiver”.

ESP8266 ESP-NOW One-way Communication Example with Arduino IDE

We’ll send a structure that contains a variable of type char, int, float, String and boolean. Then, you can modify the structure to send whichever variable types are suitable for your project (like sensor readings, or boolean variables to turn something on or off).

For better understanding we’ll call “sender” to ESP8266 #1 and “receiver” to ESP8266 #2.

Here’s what we should include in the sender sketch:

  1. Initialize ESP-NOW;
  2. Register a callback function upon sending data – the OnDataSent function will be executed when a message is sent. This can tell us if the message was successfully delivered or not;
  3. Add a peer device (the receiver). For this, you need to know the the receiver MAC address;
  4. Send a message to the peer device.

On the receiver side, the sketch should include:

  1. Initialize ESP-NOW;
  2. Register for a receive callback function (OnDataRecv). This is a function that will be executed when a message is received.
  3. Inside that callback function save the message into a variable to execute any task with that information.

ESP-NOW works with callback functions that are called when a device receives a message or when a message is sent (you get if the message was successfully delivered or if it failed).

ESP-NOW Useful Functions

Here’s a summary of most essential ESP-NOW functions:

Function Name and Description
esp_now_init() Initializes ESP-NOW. You must initialize Wi-Fi before initializing ESP-NOW. Returns 0, if succeed.
esp_now_set_self_role(role) the role can be: ESP_NOW_ROLE_IDLE = 0,
ESP_NOW_ROLE_CONTROLLER, ESP_NOW_ROLE_SLAVE, ESP_NOW_ROLE_COMBO, ESP_NOW_ROLE_MAX
esp_now_add_peer(uint8 mac_addr, uint8 role, uint8 channel, uint8 key, uint8 key_len) Call this function to pair a device.
esp_now_send(uint8 mac_address, uint8 data, int len) Send data with ESP-NOW.
esp_now_register_send_cb() Register a callback function that is triggered upon sending data. When a message is sent, a function is called – this function returns whether the delivery was successful or not.
esp_now_register_recv_cb() Register a callback function that is triggered upon receiving data. When data is received via ESP-NOW, a function is called.

For more information about these functions:

ESP8266 NodeMCU Sender Sketch (ESP-NOW)

Here’s the code for the ESP8266 NodeMCU Sender board. Copy the code to your Arduino IDE, but don’t upload it yet. You need to make a few modifications to make it work for you.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp8266-nodemcu-arduino-ide/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <ESP8266WiFi.h>
#include <espnow.h>

// REPLACE WITH RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
  char a[32];
  int b;
  float c;
  String d;
  bool e;
} struct_message;

// Create a struct_message called myData
struct_message myData;

unsigned long lastTime = 0;  
unsigned long timerDelay = 2000;  // send readings timer

// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  Serial.print("Last Packet Send Status: ");
  if (sendStatus == 0){
    Serial.println("Delivery success");
  }
  else{
    Serial.println("Delivery fail");
  }
}
 
void setup() {
  // Init Serial Monitor
  Serial.begin(115200);
 
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
  esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
 
void loop() {
  if ((millis() - lastTime) > timerDelay) {
    // Set values to send
    strcpy(myData.a, "THIS IS A CHAR");
    myData.b = random(1,20);
    myData.c = 1.2;
    myData.d = "Hello";
    myData.e = false;

    // Send message via ESP-NOW
    esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

    lastTime = millis();
  }
}

View raw code

How the code works

First, include the ESP8266WiFi.h and espnow.h libraries.

#include <ESP8266WiFi.h>
#include <espnow.h>

In the next line, you should insert the ESP8266 receiver MAC address.

uint8_t broadcastAddress[] = {0x5C, 0xCF, 0x7F, 0x99, 0x9A, 0xEA};

In our case, the receiver MAC address is: 5C:CF:7F:99:9A:EA, but you need to replace that variable with your own MAC address.

Then, create a structure that contains the type of data we want to send. We called this structure struct_message and it contains 5 different variable types. You can change this to send whatever variable types you want.

typedef struct struct_message {
  char a[32];
  int b;
  float c;
  String d;
  bool e;
} struct_message;

Create a new variable of type struct_message that is called myData that will store the variables values.

struct_message myData;

Next, define the OnDataSent() function. This is a callback function that will be executed when a message is sent. In this case, this message simply prints if the message was successfully sent or not.

void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  Serial.print("Last Packet Send Status: ");
  if (sendStatus == 0){
    Serial.println("Delivery success");
  }
  else{
    Serial.println("Delivery fail");
  }
}

In the setup(), initialize the serial monitor for debugging purposes:

Serial.begin(115200);

Set the device as a Wi-Fi station:

WiFi.mode(WIFI_STA);

Initialize ESP-NOW:

if (esp_now_init() != 0) {
  Serial.println("Error initializing ESP-NOW");
  return;
}

Set the ESP8266 role:

esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);

It accepts the following roles: ESP_NOW_ROLE_CONTROLLER, ESP_NOW_ROLE_SLAVE, ESP_NOW_ROLE_COMBO, ESP_NOW_ROLE_MAX.

After successfully initializing ESP-NOW, register the callback function that will be called when a message is sent. In this case, we register for the OnDataSent() function created previously.

esp_now_register_send_cb(OnDataSent);

Then, pair with another ESP-NOW device to send data:

esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);

The esp_now_add_peer accepts the following arguments, in this order: mac address, role, wi-fi channel, key, and key length.

In the loop(), we’ll send a message via ESP-NOW every 2 seconds (you can change this delay time on the timerDelay variable).

First, we set the variables values as follows:

strcpy(myData.a, "THIS IS A CHAR");
myData.b = random(1,20);
myData.c = 1.2;
myData.d = "Hello";
myData.e = false;

Remember that myData is a structure. Here we assign the values we want to send inside the structure. For example, the first line assigns a char, the second line assigns a random Int number, a Float, a String and a Boolean variable.

We create this kind of structure to show you how to send the most common variable types. You can change the structure to send any other type of data.

Finally, send the message as follows:

esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

The loop() is executed every 2000 milliseconds (2 seconds).

if ((millis() - lastTime) > timerDelay) {
  // Set values to send
  strcpy(myData.a, "THIS IS A CHAR");
  myData.b = random(1,20);
  myData.c = 1.2;
  myData.d = "Hello";
  myData.e = false;

  // Send message via ESP-NOW
  esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

  lastTime = millis();
}

ESP8266 NodeMCU Receiver Sketch (ESP-NOW)

Upload the following code to your ESP8266 NodeMCU receiver board.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp8266-nodemcu-arduino-ide/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <ESP8266WiFi.h>
#include <espnow.h>

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
    char a[32];
    int b;
    float c;
    String d;
    bool e;
} struct_message;

// Create a struct_message called myData
struct_message myData;

// Callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("Char: ");
  Serial.println(myData.a);
  Serial.print("Int: ");
  Serial.println(myData.b);
  Serial.print("Float: ");
  Serial.println(myData.c);
  Serial.print("String: ");
  Serial.println(myData.d);
  Serial.print("Bool: ");
  Serial.println(myData.e);
  Serial.println();
}
 
void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);
  
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  
  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {
  
}

View raw code

How the code works

Similarly to the sender, start by including the libraries:

#include <esp_now.h>
#include <WiFi.h>

Create a structure to receive the data. This structure should be the same defined in the sender sketch.

typedef struct struct_message {
  char a[32];
  int b;
  float c;
  String d;
  bool e;
} struct_message;

Create a struct_message variable called myData.

struct_message myData;

Create a callback function that will be called when the ESP8266 receives the data via ESP-NOW. The function is called onDataRecv() and should accept several parameters as follows:

void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {

We copy the content of the incomingData data variable into the myData variable.

memcpy(&myData, incomingData, sizeof(myData));

Now, the myData structure contains several variables inside with the values sent by the sender ESP8266. To access variable a, for example, we just need to call myData.a.

In this example, we simply print the received data, but in a practical application you can print the data on a display, for example.

  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("Char: ");
  Serial.println(myData.a);
  Serial.print("Int: ");
  Serial.println(myData.b);
  Serial.print("Float: ");
  Serial.println(myData.c);
  Serial.print("String: ");
  Serial.println(myData.d);
  Serial.print("Bool: ");
  Serial.println(myData.e);
  Serial.println();
}

In the setup(), intialize Serial communication for debugging purposes.

Serial.begin(115200);

Set the device as a Wi-Fi Station.

WiFi.mode(WIFI_STA);

Initialize ESP-NOW:

if (esp_now_init() != ESP_OK) {
  Serial.println("Error initializing ESP-NOW");
  return;
}

Set the ESP8266 role:

esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);

Register for a callback function that will be called when data is received. In this case, we register for the OnDataRecv() function that was created previously.

esp_now_register_recv_cb(OnDataRecv);

Testing ESP-NOW Communication

Upload the sender sketch to one board and the receiver sketch to the other board. Don’t forget to insert the receiver MAC address on the sender sketch.

Now, open two Arduino IDE windows. One for the receiver, and another for the sender. Open the Serial Monitor for each board. It should be a different COM port for each board.

This is what you should get on the sender side.

Testing ESP-NOW Communication ESP8266 with Arduino IDE Sender

And this is what you should get on the receiver side. Note that the Int variable changes between each reading received (because we set it to a random number in the sender side).

Testing ESP-NOW Communication ESP32 with Arduino IDE Receiver

We tested the communication range between the two boards, and we are able to get a stable communication up to 140 meters (approximately 459 feet) in open field. In this experiment both ESP8266 on-board antennas were pointing to each other.

ESP-NOW communication range test ESP8266 NodeMCU boards

Wrapping Up

In this tutorial you’ve learned how to use ESP-NOW with the ESP8266 NodeMCU board. Now, you can combine the sender and receiver sketch so that you have a two-way communication (each board acting as a server and sender at the same time). You can also use more boards to have a communication between multiple boards.

ESP8266 and ESP32 boards can communicate with each other using ESP-NOW communication protocol. You just need to upload the proper sketches to each board. To learn how to use ESP-NOW with the ESP32, you can read our ESP-NOW getting started guide for the ESP32.

We hope you’ve found this tutorial useful. To learn more about the ESP8266 board, make sure you take a look at our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

237 thoughts on “Getting Started with ESP-NOW (ESP8266 NodeMCU with Arduino IDE)”

      • Hi Sara,
        I am using esp now for a school project. I am posting the code below and the result when I run the sender and receiver. It receives the message but does not activate the LEDs. Can someone help in this please. Thanks
        Receiver code:
        “”””””
        #include <BufferedInput.h>
        #include <BufferedOutput.h>
        #include <loopTimer.h>
        #include<ESP8266WiFi.h>
        #include<espnow.h>
        #include <PinFlasher.h>
        #include <SafeString.h>
        #include <SafeStringReader.h>
        #include <SafeStringStream.h>
        #include <SerialComs.h>
        #include <SafeString.h>
        struct attribute((packed)) dataPacket {
        char a[32];
        };
        const byte maxRcvdBytes = 10;

        // personal naming-convention suffix _SS indicates a S)afe-S)tring
        createSafeString(newCommand_SS, (maxRcvdBytes) ); //+1 for the terminating zero
        createSafeString(Command_SS, (maxRcvdBytes) );

        const byte Red = 12;
        const byte Green = 14;
        const byte Blue = 16;

        typedef struct struct_message {

        String d;

        } struct_message;

        // Create a struct_message called myData
        struct_message myData;

        const char endChar = 0x0D; // carriage return is hex-value 0D and is used as the terminating byte

        int idx = 0;
        char rcvdChar;
        void dataReceived(uint8_t *senderMac, uint8_t *data, uint8_t dataLength) {
        char macStr[18];
        dataPacket packet;

        snprintf(macStr, sizeof(macStr), “%02x:%02x:%02x:%02x:%02x:%02x”, senderMac[0], senderMac[1], senderMac[2], senderMac[3], senderMac[4], senderMac[5]);
        memcpy(&myData, data, sizeof(myData)); // copy redeived data into myData and printit
        Serial.println();
        Serial.print(“Received data from: “);
        Serial.println(macStr);
        Serial.print(“data: “);
        Serial.println(myData.d);

        memcpy(&packet, data, sizeof(packet));

        // Serial.print(“sensor1: “);

        }

        void setup() {
        pinMode(12, OUTPUT);
        pinMode(14, OUTPUT);
        pinMode(16, OUTPUT);

        Command_SS = “off”;
        newCommand_SS = “”;
        Serial.begin(115200);
        Serial.println();
        Serial.println();
        Serial.println();
        Serial.print(“Initializing…”);

        Serial.print(“My MAC address is: “);
        Serial.println(WiFi.macAddress());

        WiFi.mode(WIFI_STA);
        if (esp_now_init() != 0) {
        Serial.println(“ESP-NOW initialization failed”);
        return;
        }

        esp_now_register_recv_cb(dataReceived); // this function will get called once all data is sent

        Serial.println(“Initialized.”);
        }

        void readFromSerial() {
        while (Serial.available() > 0) {
        String rcvdChar =Serial.readStringUntil(‘\n’);
        // for debuging purposes uncomment these lines
        //to see each received character in the serial monitor

        Serial.print("reveived #");
        Serial.print(rcvdChar);
        Serial.println("#");

        /*
        {
        if ( (String rcvdChar == endChar) ) { // End of input or max Command_SS-length reached

        Command_SS = newCommand_SS;
        newCommand_SS = " ";
        }
        Serial.print("Command_SS received: ");
        Serial.println(Command_SS);

        idx = 0;
        }
        else {
        newCommand_SS += rcvdChar; // add new received char to SafeString
        idx++;
        }*/

        }
        }

        void setLights() {

        if (Command_SS == “dog”)
        {
        digitalWrite(14, HIGH);
        delay(1000);
        digitalWrite(14, LOW);
        delay(500);
        digitalWrite(16, HIGH);
        delay(1000);
        digitalWrite(16, LOW);
        delay (2000);
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);
        delay(1000);
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);
        exit(0);
        }
        if (Command_SS == “cat”)
        {
        digitalWrite(16, HIGH);
        delay(1000);
        digitalWrite(16, LOW);
        delay(500);
        digitalWrite(14, HIGH);
        delay(1000);
        digitalWrite(14, LOW);
        delay (2000);
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);
        delay(1000);
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);
        exit(0);
        }
        if (Command_SS == “goat”)
        {
        digitalWrite(14, HIGH);
        delay(1000);
        digitalWrite(14, LOW);
        delay(500);
        digitalWrite(14, HIGH);
        delay(1000);
        digitalWrite(14, LOW);
        delay (2000);
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);
        delay(1000);
        digitalWrite(16, HIGH);
        delay(500);
        digitalWrite(16, LOW);
        delay(500);
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);
        delay(1000);
        exit(0);
        }

        }

        void loop() {
        readFromSerial();
        setLights();
        }

        “””””

        Results:

        from sender

        Last Packet Send Status: Delivery fail
        Last Packet Send Status: Delivery success
        Last Packet Send Status: Delivery fail
        Last Packet Send Status: Delivery success

        from receiver

        16:00:31.811 ->
        16:00:31.811 -> Received data from: c8:c9:a3:69:7c:a6
        16:00:31.811 -> data: dog
        16:00:31.811 ->
        16:00:47.582 ->
        16:00:47.582 -> Received data from: c8:c9:a3:69:7c:a6
        16:00:47.582 -> data: cat
        16:00:47.582 ->

        Reply
  1. Thanks for your great tutorial!

    I have a question though. I have created a network of ESP8266 devices that communicate with each other using ESP-NOW where all devices send “broadcast” packets to all other devices and there is no need to know or determine the MAC address of each device. The master-slave relationship is determined in real time by the software and software-set addresses sent within the payload.

    In this scenario where only broadcast packets are used, what is the maximum number of devices that can communicate with each other? Is it 20? Or is there no limit?

    Reply
    • Hi.
      In the datasheet, they say:
      “Limited encrypted peers. 10 encrypted peers at the most are supported in Station mode; 6 at the most in SoftAP or SoftAP + Station mode;
      Multiple unencrypted peers are supported, however, their total number should be less than 20, including encrypted peers;”
      But, I’ve never tested so many peers at the same time, so I can’t tell if it works well.
      Regards,
      Sara

      Reply
  2. Author mention that “both ESP8266 on-board antennas were pointing to each other”
    but,
    Can we have a picture about how should be oriented in horizontal and vertical plan to achieve max distance propagation?
    ie:
    L [esp1] L [esp2]
    [esp1]_| L [esp2]
    other orientation one esp rotated at 90degree ? or 180degree ?
    other?

    I could not draw here without a picture.. that is why I need that extra information

    Reply
    • Hi.
      We did not use external antennas.
      We just made sure that the front part of the on-board antenna was facing the front part of the other on-board antenna.
      Regards,
      Sara

      Reply
  3. The stability of ESP8266 does not seem to be as high as that of ESP32. Frequent sending and receiving fails. I don’t know where the problem lies. Can you help me?

    Reply
    • If you are using the command delay() in your code. This can cause the send /receive to fail. Delay() makes the microcontroller 100% busy and lefts 0,0% calculation-power for other things (like receiving a ESP-NOW-Datapacket).

      You have to use the command millis() and the non-blocking timer-technique instead
      best regards

      Stefan

      Reply
  4. Thanks a lot for this. I’m doing a project with both ESP32 and ESP8266 (so I can use the really small ESP12 module). Your article pointed out that there are differences between some of the functions for the two modules. For example, ESP32 has no Role function. I might have missed that.

    Reply
  5. In reference to my first comment today, I found you can not mix the ESPs. I tried an ESP8266 as the controller, and an ESP32 as the slave. It almost worked. It successfully completes a transaction, sometimes, but would fail many more times than it succeeded. I tried other channel assignments, lengthening the time between sending data, and varying the distance. Nothing worked. I did not try swapping the ESPs (controller for slave). Replacing the ESP8266 with an ESP32 produced a very reliable solution.

    Reply
  6. Hello . First of all, thank you for your beautiful and many work. The ESP8266 Now reciever sketch continued to give error messages. I then added an empty “Void loop () {}” to the sketch. Now it works as it should.
    Kind regards, Bert.

    Reply
  7. I have tried espnow as a study and it works well so far. But I cannot manage multiple transmitters to 1 receiver. I can’t figure it out and therefore ask you if you have a short example. Or where I can find that. I learn very slowly due to a handicap but I enjoy it very much. thanks for your work

    Reply
    • Bert, That should be simple by having both send sketches practically similar, by declaring the same MAC address of the receiving ESP.

      That means that if you would copy your sens sketch and put it unchanged in another ESP, you would have multiple transmitters to 1 receiver

      Reply
    • Hi Bert.
      You just need to upload the same code to the senders.
      Then, the receiver will get the message from all the senders.
      You may want to send a slightly different message identifying which board sent each message, or you can just get the senders’ MAC address.
      We’ll be publishing multiple transmitter to 1 receiver soon. So, stay tuned.
      Regards,
      Sara 😀

      Reply
        • the transmission with ESP-NOW is ALWAYS based on the mac-adress. So if one sender should send to multiple receivers you do a send-command for each MAC-adress. That’s all. Or you use the send to EVERY device with MAC-adress FF:FF:FF:FF:FF the broadcasting mac-adress
          best regards

          Stefan

          Reply
      • Hello Sara

        Have you made progress on that type of configuration ?
        Do you know if a tutorial is on the way for this ?

        Regards

        Nicolas

        Reply
        • Sorry for bothering. I come from Vietnam. I’m a non-professional, I spent 3 weeks just linking 3 esp8266. Specifically: Esp0 will send data to esp1 and esp2, and esp0 will receive data from that 2 esp. The problem only occurs when esp0 receives data, it only receives the return signal from one of the two, not both as intended. Can someone help me with any examples. Ex: esp1-esp0 & esp0-esp2 whose connections are bidirectional. Thank you very much

          Reply
          • What i believe it is happen in your case, is that you get TWO replies in the same time.
            While CPU is busy to get first reply, it will ignore the other, so you do not get both.
            Look for Stefan Ludwig posts here, which developed a special interrupt routine, and it might help you.

  8. Hello there!
    I believe there is a typo in the ESP MAC address, of the receiver:
    “In our case, the receiver MAC address is: 5C:CF:7F:99:9A:EA1, but you need to replace that variable with your own MAC address.”
    Cheers from Argentina!

    Reply
  9. Hi I added the Mac address from my receiving ESP8266 (84:F3:EB:EE:0E:EB) to the Sender sketch and uploaded both to an individual Wemos D1 Mini.
    When I run them it doesn’t seem to work 🙁
    I also added a few lines right after the Serial.begin for debugging.
    This is wat I get for the receiver:

    Sketch: ESP8266_NodeMCU_Receiver_Sketch__ESP-NOW_.ino
    16:59:51.884 -> Uploaded: Mar 4 2020
    16:59:51.884 -> ESP8266 Board MAC Address: 84:F3:EB:EE:0E:EB

    And the sender:

    Sketch: ESP8266_NodeMCU_Sender_Sketch__ESP-NOW_.ino
    17:01:03.953 -> Uploaded: Mar 4 2020
    17:01:03.953 -> ESP8266 Board MAC Address: EC:FA:BC:4C:7C:9A
    17:01:03.988 -> Last Packet Send Status: Delivery fail
    17:01:05.973 -> Last Packet Send Status: Delivery fail
    17:01:07.989 -> Last Packet Send Status: Delivery fail

    Any ideas? I’m using Arduino IDE 1.8.10 and downgraded my ESP firmware version from 2.6.3 to 2.5.2 to match yours..

    Reply
    • Hi.
      I’m sorry you’re having that issue.
      Do you have more information?
      It is very difficult to find out what might be wrong with just this information.
      Can you use this MAC address and see what you get? 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
      Regards,
      Sara

      Reply
  10. Hey. I’m playing with Espnow. On the reciever side I tried to display the received information on an OLED display. This in the sketch instead of the serial edition. But then a lot goes wrong.
    My intention is to be able to use the reciever rather than separately (portable) from a PC / laptop. Are you already working on this option? I will continue, but I don’t think I can get it right.
    Greetings from the Old Dutch man (Bert).

    Reply
  11. I say sorry. I have completely overlooked this ESp32 explanation because I am still working with the ESP8266. But I now understand how to do it and start working with it. Thanks . Greetings Bert (now even older haha)

    Reply
      • Hi Sara
        I’m having trouble with that. All is ok when I compile for ESP32, but as I switch to ANY ESP8266 configuration the library is not found. I have the IDE properly set up for 8266, and also ESP8266 properly installed among boards – exactly as explained in your page “installing ESP8266 in Arduino IDE”. So for some reasons in my case the esp_now.h library was NOT installed automatically… any idea? or — any URL where i could download it from?
        I have a few exsting application where I need to stick to ESP8266 since a configuration change to ESP32 would be complicated, so your help would be much appreciated.
        Thank you, congratulation for your work, and greetings from Italy
        Michele

        Reply
        • Hi.
          With the ESP8266, you use the espnow.h library not esp_now.h (for ESP32).
          So, that may be the issue.
          The code for ESP32 won’t work on the ESP8266.
          You need to follow the tutorials that are specific for the ESP8266.
          Regards,
          Sara

          Reply
  12. Great project ! Works very well.
    I love the fact that I don’t need my LAN (client/server situation). Thank you and keep up the great work.

    Reply
  13. Hello
    I have a question :
    As seen in this tutorial, is it possible to implement this configuration :
    “One ESP8266 “slave” receiving data from multiple “masters” ” ? How to do that ?

    Regards
    Nicolas

    Reply
  14. Hello Rui,

    I tried your code but get unreliable results.
    only every five sendings the sender reports sending was successful.

    I have also tested another code where a ESP32 acts as the “master” and an ESP8266 as “slave”. In this code both send and recive and this works very reliable. So is there still a problem with the espnow-library or do other modes than both in WIFI_STA work more reliable.

    Could this be a problem of the WLAN-channel?

    best regards

    Stefan

    Reply
  15. Thanks for the turorial, i have a problem with communication between the nodemcu, i only get a stable communication up to 1 meter or 1.5 meters. Is there any way to increase the distance? I already tried to put them face to face, but it did not work.

    Reply
    • Hi.
      I don’t know why you’re getting such a low communication range :\ There’s must be something causing that.
      We get much more distance without any effort.
      Maybe you can try with ESP32 boards??
      Regards,
      Sara

      Reply
      • Hi Marek, Sara and Rui,
        I have spent a great deal of time trying to diagnose unreliable communication on the ESP8266 using a variation of this ESP Now send and receive sketch.
        Adding the WiFi.disconnect(); gives me 100% delivery success.
        THANK YOU!!
        I can now move on to the next step in my Controller project using ESP Now.
        This communication method is awesome!
        Bob D

        Reply
      • Thanks Marek!

        I was getting a lot of callback “Delivery Failed” error messages from the Sender NodeMCU. Roughly 80% of the callback message deliveries were failing, even with the Sender and Receiver NodeMCUs only a metre apart.

        In the setup() code for each of the Sender and Receiver NodeMCUs I added “WiFi.disconnect;” as you suggested, and now 100% of messages are delivered successfully!

        Reply
  16. Thanks for sharing this article and the one based on ESP32. I am successfully using ESP-NOW between the 8266 and esp32. My project has allowed me to set up telemetry between one board with a GPS module attached and the other a display configured as a course deviation indicator modelled on an aircraft display. I’ve yet to test range but will install the GPS on an RC aircraft when we are all allowed to go back flying.

    Reply
  17. Hello Sara,
    This tutorial is great but is missing something which i do not know how to implement.
    I have a microcontroller with a packet of 175 bytes connected to RX pin of the first ESP.
    On the second ESP, on the TX pin i have a second microcontroller connected on the RX pin.
    What i want to do is transfer the message from ESP to microcontroller and vice versa.
    Roughly said , use the ESP and ESP-NOW protocol as a transceiver.
    How i can do that ?
    I need probably 2-3 lines of code to do that :

    Write data received by ESP2 to TX pin.
    Read from RX pin of ESP2 and send data using ESP-NOW to ESP1.

    Thank you.

    Reply
    • Hi Ion,

      you should AVOID the variabletype String. Strings eat up all memory over time and cause your prgram to fail in strange ways that are very hard to track down.
      Use instead an array of char or the library PString.

      It is a bit more than 3 lines of code. The solution also depends on if you can REALLY wait for the serial bytes to be finished or if you can’t wait. Is it ALWAYS exactly 175 bytes?

      as pseudo-code it looks like this

      char MyRxStr[176]

      MyRxStr = Serial.Readln();
      esp_now_send(mac_addr, MyRxStr, sizeof(MyRxStr));

      void on_data_recv(const uint8_t *mac_addr, const uint8_t *incomingData, int len)
      {
      memcpy(&ESP_Data_Received, incomingData, sizeof(ESP_Data_Received)); //xxy

      the “code” above os just a quick & dirty copy and paste of some bigger code that I’m using

      best regards

      Stefan

      Reply
      • Thank you Stefan,
        To be more clear it is.
        I have an LCD display and a microprocessor which shows some data from different sensors.
        The microprocessor does not have RTC, but the display has one with a battery.
        Scenario 1: Every minute i want to send from LCD the date/time to microprocessor.
        Scenario 2: Based on time, microprocessor send to LCD value of the sensors.On the LCD side i have an other microprocessor which receive data from ESP and drive the LCD, or receive the date time from LCD and send it to ESP.
        I can setup the length of number of bytes to be always the same , regardless transmission or reception.
        Up to now, i have an UART cable.
        I want to cut the cable and keep the LCD on my desk and the microprocessor somewhere on an other room.
        I can use an RFM95-98, but i prefer to use an ESP module.
        Any suggestion where to go and read ?
        Thank you
        Ion

        Reply
        • hm still not completely clear to me:
          What I have understand so far:
          there are three or four microcontrollers involved
          in short “µC1-non-ESP”, “µC2-ESP”, “µC3-ESP”

          µC1-non-ESP connected to LCD and connected to µC2-ESP via serial

          µC3-ESP connected to a sensor

          µC3-ESP sends sensor-data via ESP-NOW to µC2-ESP

          µC2-ESP forwards sensor-data to µC1-non-ESP through serial-wire connection

          µC1-non-ESP shows sensor-data on the LCD.

          But I’m not sure if I understand right.
          All these microcontrollers have names like “Arduino-Uno”, Arduino-nano” or whatever. Could you give a description of all the microcontrollers involved using their names and adding what is connected to them?

          What kind of LCD is it? What is the exact name and type of the NON-ESP-microcontroller which is connected to the LCD?

          If it is Arduino-like” you might could porting the code that is running in the non-ESP-µC to an ESP8266 or ESP32. This would eliminate the non-ESP-µC.

          best regards

          Stefan

          Reply
          • Hello Stefan,
            I do not want to make your day a nightmare with my problems.
            In short.
            1.The first Microcontroller Pic18F46K22 collect through IIC temperature and humidity from Si7006-A20 , I2C HUMIDITY AND TEMPERATURE SENSOR, from Silicon Labs.
            2.Based on data collected, Pic18F46K22, make a log to see if the temperature is in the set range, or they are deviations.
            It use the second UART and send data collected , when user connect the PIC to a PC. Once or twice a day.
            3.The time of day is divided on 4 zones, which asks the PIC to know the Real Time.
            For example from 6am to 10am is Zone 1 and temperature is requested to be 23C.
            On the other zones they are another temperatures set. On the PCB it is not a RTC.
            4.Now, the Pic, send data collected to an intelligent display , NEXTION. The display shows Temperature, Humidity, Real Time , Zone of the day and Temperature SET. Nextion has a RTC.
            5. Nextion send the RTC to PIC, and eventually changes on the zones setting (set temperature)
            Up to know it is a UART cable (RX,TX) connecting the both.
            Pic <======> Nextion
            I want to cut the cable and use ONE ESP8266 on each side.
            Pic <===> ESP1 <===> ESP2 <===> Nextion
            As i state before, I do not want to use wireless transceivers, I trust more ESP communication.
            I can make a standard fix length string , and process from it on each side, just data I need.
            The connection of PIC with PC and communication it is not the scope of my project. It is already solved and works well.

  18. In short, what i understand from the article, ESP-NOW can transport UP to 250 bytes
    between a pair of ESP.
    What i want is just to SEND OUT the “250” bytes received on ESP2 from ESP1, through TX pin to a PIC microcontroller, and READ on RX pin of ESP2 “250” bytes to be sent to the ESP1.
    PIC1 – TX pin ====> RX pin ESP1 ====> ESP-NOW ====> ESP2===>TX pin ESP2 ====>RX pin PIC2. And vice versa.
    On the PIC it is an easy task. I write to the UART port , or use interrupt to read from UART port.

    Reply
  19. Hi Ion,

    it would have become a “nightmare” with non-detailed information.
    Now I understand the whole situation. I made some first experiments with two ESP8266 using ESP-NOW. But the transmission was unreliable. I got a lot of errors from the ESP-NOW-library that transmission failed. I haven’t analysed yet if it was unreliable code written by me or if the ESP8266-ESP-NOW-library is unreliable itself.

    When I used one ESP32-modul paired with an ESP8266 it was reliable. Though I did not do intensitive testing.

    OK.
    On my own project next step is to code a two-way-communication via ESP-NOW.
    My personal experience is: For really new things write small test-code that does just that one new thing. It will take some days to get this up and running as I haven’t so much time per day to write code. Lot’s of other things also to do. If I have a substantial and somehow tested piece of code I can post it here.

    In the meantime I recommend doing it the same way. Write a testcode that does only send and receive your 175 bytes back and forth via ESP-NOW printing the content on the serial monitor.

    best regards

    Stefan

    Reply
    • Hello Stefan
      Sorry for late reply, but i had bug in a program which kept me up for the last 36 hours.
      It is finished now.
      When i said 175 bytes was a generic number. I will count the real maximum number and make a test code like that.
      I will also try to divide the string on few smaller one.
      I believe the longest one is DATE like
      2020 04 25 13 55 F F F
      32 30 32 30 30 34 32 35 31 33 35 35 0F 0F 0F
      Looks like 15, sent at power UP. From there the CPU will keep track about time and date through some timers. I can repeat this command at midnight to correct for eventual variations on the CPU. The rest of the day, is not too much. Maybe once or twice a day if i want to change the set temperature to a temporary new value.
      I can say and will test with 30 bytes in total.
      The 175 was in my mind as a number in general as they said we can send 250 bytes, and i was thinking at a different project.
      But 30 for now will be OK.
      I will let you know when i did it and the results.
      Best regards
      Ion

      Reply
  20. Hi Ion,

    this comment-function does not allow attaching files and it is eliminating spaces. How about changing to a real Arduino-Forum where code can be formatted as code and files can be attached? When I tested two-way-communication with ESP-NOW I used code that used delay() in the main-loop. Using delay can be such a DELAY when writing code. The delay was causing the unreliability of transmitting the data. I got a lot of messages send failed. As soon as I replaced the delay-commands with a non-blocking-timer that uses millis() the sending back and forth of both units worked very good.

    @Rui and Sara: I’m somehow sorry that this discussion leaves the RNT-website. But I want to go on with attaching code and posting code that is well formatted as code.

    best regards

    Stefan

    Reply
    • Hello Stefan,
      Please give me a link of a forum and i will register and be there, and start looking for the topic until i find the one.
      Thank you very much for all the help.
      Ion

      Reply
    • Hello Stefan,
      As i was born somewhere in Europe, for me english is still like Amazonian forest.
      Lot’s to discover, which mean, i did not get the meaning of “Hion”. You can explain it to me.
      I will go tomorrow morning, or late tonight to look at the code.
      My daughter in law, which is pregnant on the 7 month, is in the hospital now for some kidney problems/stones.
      So the drill is: I stay home with my other two lovely granddaughters during the day, while my son, spend time in the hospital with his wife.
      Thank you for all your effort.
      Ion

      Reply
  21. Hello Ion,

    “Hion” was just a little playing with letters instead of writing “Hi Ion”
    Hi similar meant as “Hello”
    I put “Hi” and “Ion” together to Hion. That’s all. ;-))
    OK if you have any questions just ask them in the Arduino-Thread

    https://forum.arduino.cc/index.php?topic=680265.0
    I enjoy helping this way very much.

    best regards and best wishes to your daughter

    Stefan

    Reply
  22. Hi Sara,
    I will try to have more than one sender with i.e DHT22 in different places and a receiver with an oled sisplay.
    Now I try with only one sender but I have a problem, while the receiver in serial monitor show the correct data, in the oled display the name of the place corresponding to myData.a
    is reproduced but Temp corresonding to myData,c and Umid. corresponding to myData.b are 0.00 and o or nan.

    I made this variation of the code:
    void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
    memcpy(&myData, incomingData, sizeof(myData));
    Serial.print(“Bytes received: “);
    Serial.println(len);
    Serial.print(“Char: “);
    Serial.println(myData.a);
    display.clearDisplay();
    display.setTextSize(1);
    display.setCursor(0, 0);
    // Display static text
    display.print(myData.a);

    //display.print(myData.a);
    Serial.print(“Umid: “);
    Serial.println(myData.b);

    Serial.print(“Temp: “);
    Serial.println(myData.c);
    display.setTextSize(2);
    display.setCursor(0, 16);
    // Display static text
    display.print(“T: “);
    display.print(myData.c);
    display.println(“*C”);

    Serial.print(“String: “);
    Serial.println(myData.d);

    Serial.print(“Bool: “);
    Serial.println(myData.e);
    Serial.println();
    }
    in the setup
    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128×64
    Serial.println(F(“SSD1306 allocation failed”));
    for(;;);
    }
    delay(2000);
    display.clearDisplay();

    display.setTextSize(1);
    display.setTextColor(WHITE);

    // Display static text
    display.setCursor(0, 0);
    // Display static text
    display.println(myData.a);
    display.setTextSize(2);
    // Display static text
    display.setCursor(0, 16);
    display.print(“T: “);
    display.print(myData.c);
    display.println(” C”);

    display.setCursor(0, 36);
    // Display static text
    display.print(“U: “);
    display.print(myData.b);
    display.println(” %”);

    in the loop
    display.clearDisplay();
    display.setTextSize(2);
    // Display static text
    display.setCursor(0, 16);
    display.print(“T: “);
    display.print(myData.c);
    display.println(” *C”);
    display.setCursor(0, 36);
    // Display static text
    display.print(“U: “);
    display.print(myData.b);
    display.println(” %”);

    Practically I repeat three times the same code, if cancel one group I don’t see anything.

    What is wrong.

    Renzo Giurini

    Reply
  23. Hi Sara & Rui,

    Thanks for this very clear and straight forward introduction to ESP-NOW, I had a couple of OTA flashed ESP-01’s communicating this afternoon! Now I really need to explore having the sender on battery power and waking up, sending and then going to sleep, something to keep me entertained on the morrow.

    The satellite picture of your range test made me feel a bit sad, as my wife and I should have been in Foz visiting my sister and husband this Easter (they live up towards the Contemporary Art Gallery …) but our flights obviously got cancelled and we had to stay in Nottingham …

    I hope this finds you both safe and well, I really do owe the pair of you some drinks as RNT has always been one of my ports of call for ESP stuff!! I’ll check if you are around when we manage to rearrange our trip!

    Thanks again

    Pete

    ps like Stefan I worked out quite early in tests that I really had to avoid any blocking code!!!

    Reply
  24. I am sure I read here somewhere but cant find it again how to make the ESP32 code work with ESP8266?

    I have a number of ESP8266 (Node MCU) chips that I want to use with some 1wire temperature chips to log temperature around the house and garden. I could log them and just collect the kit later but thought it would be enhance my learning to pass the data to and from devices.

    I thought that way I could set some up with battery power and also use the ESP8266 to feedback battery conditions of the devices outside, I could mess with Deep Sleep but as at least one will be connected to a motorcycle in the shed to monitor its 12v batter condition I want to just use them to create a warning flash (or message) on the devices indoors

    anybody does this ring any bells? can you run ESPNow on ESP8266’s with multi connected nodes?

    Cheers CLive

    Reply
      • If youtake ESP32-code and try to transfer it to ESP8266 there several things to look at:
        first include espnow.h instead of esp_now.h (no underline in the filename

        Don’t use delay() on ESP8266. Delay blocks the one core of the ESP8266 completely so that even ESP-NOW-messages can’t be sent or received

        use non-blocking-timers instead
        when used in Stationmode use the command WiFi.disconnect() to make ESP-NOW work

        @Rui & Sara: can you examine which mode works best on ESP8266?
        I guess mutliple conditions must be fullfilled to make ESP-NOW work in pairing with the ESP8266 connected to a router at the same time

        Some constants and some data-types that are defined in esp_now.h (which is for ESP32) are simply NOT defined in the espnow.h (ESP8266) so porting the code requieres a lot of adapting. I think it is better to use code that was originally written for ESP8266.

        best regards

        Stefan

        Reply
        • Thanks Sara ,

          Stefan is correct I have tried (unsuccessfully) to replace code and got very tangled extremely quickly. In principle it sounds easy but as a nubby its far from that. I am not beaten just inexperienced so it may be sometime before I learn enough to get there but thats the point isn’t it?

          Thanks for the help so far I guess what I need it time and to experiment and get some of the routines of actually getting data under my belt and come back to the data transfer later

          Cheers Clive

          Reply
          • Brilliant

            I have started editing your ‘Sender and Receiver’ code to pass 1wire data from one to another and will let you know how I get on.

            But I’m also going to have a look at this code to , maybe tomorrow as its a little late here now in the UK

            Thank you

          • Hello Stefan,
            I cannot compile the code from Arduino Forum.
            Here is the error:
            Arduino: 1.8.12 (Windows 7), Board: “NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled, All SSL ciphers (most compatible), 4M (no SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 115200”

            ESP_NOW_Bidirectional:4:37: fatal error: nonBlocking_Timer_class.h: No such file or directory

            #include <nonBlocking_Timer_class.h>

            ^

            compilation terminated.

            exit status 1
            nonBlocking_Timer_class.h: No such file or directory

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

            And i have a picture which shows me that :nonBlocking_Timer_class.h: No such file or directory

            Any help ?
            Thank you
            Ion

  25. Hi Ion,

    my comment was too short. The democode for send/receive data both ways with ESPNOW on ESP8266-boards makes use of the non-blocking timers.

    This means you have to download the files of nonBlocking_Timer_class
    These files are posted in this thread

    https://forum.arduino.cc/index.php?topic=680251.0

    And in this thread is explained WHERE to store these files on your harddisk.
    I insist on using the nonblocking timers because using the command delay() makes the datatransmission unreliable. You can’t predict WHEN a SEND-NOW-message rushes in. So the receiving board has to be ready all the time and can’t be totally busy through the command delay(). Delay is used to pause code-execution but in a way that this “pausing” means “processor count up to 1000 billions as fast as you can”. This counting up needs all the calculating-power the processor has. There is NO calclulating-power left to receive ESP-NOW-messages.

    best regards

    Stefan

    Reply
    • Thank you Stefan.
      It compile with no errors.
      On the original try, i just read one line in 5 , so i miss the essential of storing the h and cpp files.
      Now everything is in place and both of your files, compile correctly with no errors.
      Thank you very much.
      Ion.

      Reply
    • Hello Stefan,
      Your “nonBlocking_Timer_class” here, looks like a timer+counter i can set on my “Interrupt routine” on my regulars programs for PIC processors.
      At startup i set an interrupt timer for a defined period of time(let’s say 10ms.)
      Because this timer is inside of the interrupt routine, executed every scan, and at overflow of the 10 ms. it increment a “non_blocking_timer” like you say, arbitrary set at 300- a counter.
      At start, the counter was 0 and i had a boolean flag = ON. If for example the counter is set 300, this will keep the flag ON for 3 seconds. At time up, 3 seconds, the flag turn OFF.
      I have the same issue on the programing regular processors with the Delay command or While command. Your idea is brilliant.

      Reply
  26. I had totally forgotten to update ESP8266 with Boards manager. Now I made an update from 2.4.1 to 2.7.1. I still don’t get this working. How to get a working version?

    Reply
    • Hi Pertti,
      what exactly do you mean with “How to get a working version?”
      The code on this subsite IS working. Working for Sara and Rui and I can confirm that the code is working. So YOU have to describe in DETAIL what is happening if you upload this code given above if you try to make it work.
      It might be that you have setup the wrong MAC-adress, it might be that you get a compiler-error.
      As long as you just say “not working” the only tip we can give is “try to get it working”
      Which of course does not help. We can help you much better if you describe in DETAIL what is happening if you uploaded the code to your ESP8266-module.
      best regards

      Stefan

      Reply
      • Hi Stefan,
        Thanks for the answer. My problem was not the ESP8266 add-on in Boards manager. ESP-NOW with the newest version seems to work now. Now the program loading to ESP-12 seems to work so that the program does not start when it is loaded. I have to unplug USB cable and plug again to make it start. That confused me, and I don’t like it. Is there a solution to this?

        Pertti

        Reply
      • Hi Sara,
        I like ESP-NOW and this tutorial. I am currently struggling with the reliability. Sometimes I have a 7 to 10 “Delivery success” and after that “Delivery fail”. Sometimes the transmitter seems to stop totally transmitting. I wanted to add LED blinking on both sides, but now it seems to be still far away. It is written in Espressif site that no time consuming should be added to the callback functions.

        Reply
          • in my eyes introducing newbees to the command delay() is a BIG mistake. delay() makes the microcontroller count up as fast as she can needing 100% calculation-power. So there is now calculation-power left for anything else like receiving a ESP-NOW-message. You have to write your code completely WITHOUT delay() to make it ESP-NOW work reliably.
            Espessially for receiving ESP-NOW-messages because the receiver can NOT predict when the message will rush in.

          • Hi,
            I have this finally working reliably. I started from the original codes of this tutorial with the attitude that they have to be correct. My problem was in HW. The GP Power Bank that I used on the other end stopped giving power after some time. I guess it is not meant for this kind of projects, and waits some answers from the connected device to continue giving power. I almost lost my nerves before finding this out. I changed to an older power bank that just gives power without questions. I made the LED blinking on receiver side using millis(). But I don’t know if is really better than delay() in this case. I guess it is better only inside loops where there is also something else to do than counting time.

  27. Hi Sandra and Rui,
    Just tried ESP-NOW on 2 Node Mcu’s 8266 worked great! To check out distances for my location, I set up a flag variable in the sender’s callback function and in the main loop I flash a led according to the state of the callback. (Flashing a led with the code in the callback function is a no no, yes I afterward read the previous comments concerning the blocking delay !) . So to test the distance leaving the receiver part with the PC in the house , I go outdoors with the sender on battery , the flashing led tells me that all is still communicating well. No flash means out of range. With the antennas facing each other, the test was very successfull for me. I also modified the code to receive DHT humidity and temperature. Thank you for the great tutorial, as this will greatly simplify my project .

    Reply
    • Hi Ross.
      You don’t need to install anything.
      The espnow library comes installed by default when you install the ESP8266 boards.
      Make sure you have an ESP8266 selected in your boards menu before compiling or uploading the code.
      Regards,
      Sara

      Reply
    • I want to add something. The manufacturer of the ESP-chips ESP8266 and ESP32 provides DIFFERENT ESP-librariies fpr ESP8266 and ESP32. These libraries are INcompatible. porting exampel-code between ESP8266 and ESP32 is a BIG hassle. You better write code from scratch or search for an example that is written for the right hardware than modifying it.

      This means if you work with an ESP32 search for code written for ESP32 and use #include <esp_now.h>

      If you work with ESP8266 search for code that is written for ESP8266.
      use #include <espnow.h>

      Can you see the difference? Filename with or without underline
      best regards

      Stefan

      Reply
  28. Hi Sara, Great work with this manual, it’s very interesting. Just a question, it’s possible have in one ESP8266 communication with ESP-NOW (with other boards) and this board could be connect to a Router AP in the same time. The idea is have communication with all boards with ESP-NOW but have the possibility to connect to internet to monitoring all information that you have created with your ESP-NOW network.

    It’s possible share both communication in ESP8266.

    Thanks

    Regards

    Reply
    • Hi Alberto,

      somewhere I have read that ESP-NOW and WiFi in parallel only works if you setup ESP-NOW to use the same WiFi-Channel than the WiFi-network you want the ESP8266-module to connect with is using. I haven’t tested this myself yet. When using ESP-NOW there is a command WiFi.disconnect. This makes perfect sense to the restriction described above. When WiFi is DISconnected ESP-NOW can use another channel and it will work because the module is DISconnected from the AP.

      best regards Stefan

      Reply
  29. @Pertti Ritala:

    You seem to have not (yet) understand how ESP-NOW works.
    If you want to have reliable RECEIVING you MUST avoid delay().
    A receiving unit can NEVER predict WHEN a ESP-NOW-message rushes in.
    The sender maybe tries to send it three times within one second. If your receiving unit is busy with delay()ing in right that second where the sender is sending. The sending MUST fail.
    The receiving of ESP-NOW-messages happens in the backround and therefore the processor needs some calculation-time. delay() absorbs ALL calculation-time. And this is the reason why delay() makes RECEIVING unreliable.

    best regards Stefan

    Reply
    • Hi Stefan,

      That is good know. My receiver code is similar than in this tutorial, nothing done inside the loop. Inside the receivers callback function I blink a sender related LED using millis(). In the sender I do everything inside setup with delay(100); and ESP.deepSleep(2*1000000); in the end. Everything works now, and I am ready to join a ESP-NOW fan club.

      Reply
  30. Hi,

    Does somebody know how much current some ESP8266 module takes during sending? And is the sending always with full power? I have a battery powered sender now working. There is no need of LED blinking as I have earlier discussed. Serial.println() handles that. Even Serial.begin() blinks the on-board LED.

    Reply
  31. Hello.
    The receiver does not work. I uploaded the sketch correctly, the receiver only sends via uart boot and then nothing. What am I doing wrong?

    Reply
  32. In a one to many configuration, can the “one” be connected to a wi-fi network? Can the one be used to collect data from the many, and periodically pass it along via wi-fi to a controller? Would the “one” need to close the ESP-NOW connection, open a wi-fi connection, pass the data, close the wi-fi connection, and reconnect to the ESP-NOW network? Or, can the wi-fi connection exist with the ESP-NOW connection active?

    Reply
  33. Thank you. This will get me started. I don’t need the web server, just wi-fi to connect to Home Assistant. The idea is to use esp-now to create a network of ESP-32s that will function even if Home Assistant crashes.

    Jim

    Reply
    • Hi.
      You don’t need to install the library.
      It is “installed” by default when you install the ESP8266 or ESP32 boards.
      Regards,
      Sara

      Reply
  34. Thanks for the perfect lesson about starting ESP-NOW
    Following your steps to communicate between two esp6266 boards
    i tried to upload the scetch for the receiver in the aruino ide
    As newbee it took many hours to solve several compiler errors, learned a lot.
    Now the program compiles perfect but doesn’t upload giving the error
    A fatal error occurred: Timed out waiting for packet header
    I searched on internet put an extra cap (- nto enable), tried other harware boards ,no result
    Other sketches on the boards i use are uploading fine so i don’t think its hardware.
    Please please can you help me how solve the problem ?

    Thks Wouter

    Reply
    • Hi.
      You can try pressing the RST button several times before trying to upload a new code and press the FLASH/BOOT button when you start seeing a lot of dots on the debugging window.
      Also, make sure you have an ESP8266 selected in Tools > Board.
      What’s the ESP8266 model you’re using?
      Regards,
      Sara

      Reply
  35. Hello
    Great article thanks
    Still having problems error A fatal error occurred: Timed out waiting for packet header

    Checked a lot on internet, can’t find the right solution

    Please would you be so kind to help me ??

    Reply
  36. just some more info
    Used several esp12e modules and all uploading and working fine with other sketches
    Your example here above ESP8266 NodeMCU Sender Sketch (ESP-NOW)
    gives the upload error

    wouter

    Reply
  37. hello Sara

    Really thanks for the quick help.
    I’m using Geekcreit® NodeMcu Lua WIFI Internet Things Development Board…
    and
    ESP8266-12E ESP-12E (replace ESP-12) module NodeMcu Node mcu Lua wifi V3
    and….. i used the wrong board.
    now using NodeMcu 0.9 (ESP12 Module ) and everythings uploads fine,
    so problem solved many many thanks
    wouter

    Reply
  38. Hi Sara,
    A very good article again.
    I learn a lot of with you
    Can you please tell me if we can use ESP-Now Protocol between 2 ESP-01, And between one ESP01 and one ESP-32 ?
    is the power consuption lower with ESP-NOW protocol or WIFI protocol ?
    Thank you

    Reply
  39. I want many to many communication between esp32 boards through Bluetooth low energy, without router in between. And i want when one of the esp32 board come in the range of ble of another esp32, the buzzer should run. Can you provide me the code for this function.

    Reply
    • Hi.
      You need to insert your network credentials in the ssid and password variables.
      Those are the credentials you need to type when you want to access internet in your computer or smartphone at home.
      Many times the credentials are written under the router.
      Regards,
      Sara

      Reply
  40. Hello
    Thank you very much for the good information

    I have a question
    MAC address
    Is this the sender’s address?
    Or is it the recipient’s address?

    I think I have to put in the address of 8266 to be received. Is it correct?

    (Isn’t it necessary to have both the sending and receiving addresses to protect against external attacks??)

    And I just want to make #2D1 low when #1D1 low
    Should I use the Int command?

    Reply
  41. Hello Sara,
    I am running the second code machine to machine (master to slave ) from the sender side I have put the mac address on the receiving side but it’s not working. On the serial monitor, it’s showing the delivery package failed . Help me out.

    Reply
    • Hi.
      Make sure that both boards are powered.
      Double-check the MAC address of the receiver board.
      For a first test, make sure the boards are relatively close to each other.
      Regards,
      Sara

      Reply
      • there are a lot of possible error-sources.
        Post your code. Using function delay() on the receiver-side is the most often reason fpr failed receiving. delay() must be avoided totally. If the CPU is executing a delay receiving is NOT possible. As you can’t predict WHEN a receive rushes in
        the receiver has to be ready to receive all the time.
        So you have to use timing based on the millis() function.

        @Sara and Rui:
        You should improve your example-code to NOT use delay().

        Talking about master and slave in relation to ESP-NOW is complete nonsense. up to 20 ESP-boards can build a “peer-group” where each board can send and receive to any member any time. All that has to be done is specifying the RECEIVERS mac-adress inside the SENDERS code. So double-check that the SENDER has to right mac-adress of the RECEIVER
        best regards Stefan

        Reply
  42. Trying to use VS Code. ESP-NOW is not recognized, is there a library to install? Header file not found, etc. Couldn’t find it on PlatformIO library search.

    You have a marvelous site here for ESP development. Thanks.

    Dave

    Reply
    • Hi.
      You don’t need to install anything.
      As long as you select an ESP8266 board, and add the #include <Arduino.h> line to your code, it should compile just fine.
      I’ve just tested it and it is working fine for me.
      Regards,
      Sara

      Reply
  43. i do copy all exactly but the result are different on string. it keep give me strange character. i use 2 wemos d1 mini module on same breadboard with properly power supply

    Reply
  44. Intriguing article Sara. Has my attention and I am sure to try it as soon as I can. But a question first, for I would need external wifi access as well: web page, NTPclient, Alexa (UDP) and websockets as well at times. Aside from an I2C wiring, is it possible to attach an ESP8266-01 device to an ESP8266 nodeMCU (E-12 V1)? Any suggestions?

    Great project, thanks.
    Greg

    Reply
    • Hi Greg.
      What do you mean by “attach”?
      Do you want to connect an ESP-01 with an ESP8266 (physically)?
      You need to use the serial pins and establish a serial connection.
      Regards,
      Sara

      Reply
      • Well… yes, if it sounds do’able.
        I need an internet connection as well as your ESP intranet, esp-now. I have never used an ESP8266-01 but thought it sounded feasible and sufficient.
        So I thought that I’d ask you, the “definitive source” on SEP-Now.

        Thanks for you fast reply and information,
        Greg

        Reply
  45. Hello,
    I have tested this code and it has worked just as you have shown. Great job 🙂

    But I have been working on a project recently involving a switch to wirelessly send a HIGH or LOW signal to an ESP32-CAM to take a picture. I am currently stuck because I am still trying to understand how ESP-NOW works. If someone could please assist me by giving an example using ESP-NOW to wirelessly switch a light on and off with a physical switch I believe that it would lead me on the right path.

    It would be much help,
    Spencer

    Reply
  46. Hi there, this is a superb tutorial to find after spending days trying to figure out how to make ESPs communicate with low latency, so thanks so much for writing this!

    One note: the instructions on the mac address format was a little confusing. It’s worth noting you need to prefix each part of the address with 0x like so:

    Example:
    41:9E:38:21:BF:8D —> {0x41, 0x9E, 0x38, 0x21, 0xBF, 8D}

    Reply
  47. Hi Sara,
    thank you for such useful tutorial.
    I have problem compiling this sketch!
    all settings are same as you taught but the error “Error compiling for board NodeMCU 1.0 (ESP-12E Module).
    ” is driving we crazy.
    how can i fix it?

    Reply
      • thank you for quick reply Sara.
        i just updated the board installation but the error keeps going.
        the last line of error is :

        collect2.exe: error: ld returned 1 exit status
        exit status 1
        Error compiling for board NodeMCU 1.0 (ESP-12E Module).

        Reply
  48. Hi,
    Thank you for all of your excellent tutorials. They are very beneficial in developing an understanding of the ESP8266 and ESP32.
    But I am having a problem compiling sketches which include the “espnow.h” file with 8266 boards. The error is that it cannot find the “espnow.h” file. There is no problem with ESP32 boards.
    This is Arduino 1.8.13 with the ESP8266 and ESP by Community installed. You state in one of the tutorials that this file is downloaded with the Board.
    Thank you for any help.

    Reply
    • Hi.
      You don’t need to install anything besides installing the ESP8266 add-on.
      Make sure you have the ESP8266 add-on updated and that you have an ESP8266 board selected in Tools > Board.
      Regards,
      Sara

      Reply
  49. Hi,
    First I want to thank you for so many really helpful totorials.
    Then I have a question on the above ESP-NOW examples. There is no place in the code to enter the wifi credentials, how can wifi establish communication without ssid and password ?

    Regards
    Ray

    Reply
  50. Hi and thank you for the great article.

    I have the ESP8266 (ESP-01) receiving messages from another devices and writing the value out via the serial port from within the OnDataRecv CB function. All good.

    In the below main loop, I continually toggle the LED. The issue is that the LED is only toggled when messages are received. If I stop the transmitter, the main loop is not being executed.
    Why?

    void loop() {
    digitalWrite(LED_BUILTIN, LOW); // Turn the LED on
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
    delay(500);
    }

    Reply
  51. Hi

    I want to know when the OnDataSent function will be called, after calling the esp_now_send function, or after another esp receives the information sent by this esp?

    thank you very much!

    Reply
  52. Hi! Thank you for this tutorial and hello from Russia.

    please tell me, is it possible to add peer and enter mac addresses directly from the program? can I enter the mac address from the serial port in “loop” and it is used for communication via esp now? or is it possible to do this only in the “setup” when i programming esp?

    ps i mean // Register peer
    esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);

    Reply
    • Hi.
      Yes, I think you can do that.
      But, you have to add the peer only after entering the MAC address on the Serial port, not in the setup().
      Regards,
      Sara

      Reply
  53. Hello all.
    This was all working fine until i upgraded to esp8266 version 3 in the Arduino IDE. now the same code is no longer working. I change back to the older version 2.something, and it works again.
    Has anyone else had this issue?

    Reply
    • Seems this command has changed wifi_set_macaddr(STATION_IF, &newMACAddress[0]);
      on the receiver side.
      I am looking in the “breaking changes section” at the moment, on the espressif site.

      Reply
        • Hi Sara,
          After much testing…..
          The issue turned out to be, on the side where we are sending the data to. The receiver, or slave unit. Part of the setup routine is the change the MAC address to One where we can define the mac address. Prior to the core upgrade to version 3.xx
          We define the mac address before the wifi.begin(). After version 3, we now have to define the new mac address after the wifi.begin();
          Wifi.disable();
          Then we add the new MAC here.
          I am on my phone, so my reply is not that great.
          Even with the error, it still compiled with no errors, however, the sender could never connect, as it was looking for a hard coded mac and not the software defined MAC.
          I have noticed, this finding may affect some of your other example, where you define the new MAC address.
          Regards

          Reply
          • Hi.
            Thanks for the detailed response.
            I’ll try to fix the issue in the next few days.
            Regards,
            Sara

  54. Is it possible to modify the code in this tutorial so an ESP8266 acts as a repeater station between two other ESP8266’s using ESP-NOW?

    Reply
  55. Sending ct sensor reading from one esp8266 to another following your sketch. Once data gets to the receiver, how can I use that data for something other than printing it to the serial monitor..
    current sensor readings are using mydata.b.
    I would like to have something like If mydata.b is > 25, digitalWrite ledPin HIGH

    Thank you for providing this example.

    Reply
    • Hi.
      Save the received data in variables and then, use them in the loop() to check for conditions, like the “mydata.b is > 25, digitalWrite ledPin HIGH”.
      Regards,
      Sara

      Reply
  56. I tried an example sending data from a Wemos Mini to an ESP32 DevkitTV1 using it own MAC Address, but I don’t receive anything.
    It is possible?
    Thanks
    Renzo

    Reply
  57. Hi Sara,
    I have just started to look at esp-now and am having a problem finding esp_now.h on my computer.
    I have removed and reinstalled the ide and installed the esp32 and esp8266 boards and a heap of other esp boards but the ide still can not seem to locate a library containing esp_now.h
    I must be missing something.
    Could you please point me in the rite direction?
    Kind regards,
    Eric.

    Reply
    • Hi.
      Make sure you have the right board selected for the code you’re using.
      Additionally, the ESP32 uses esp_now.h library and the ESP8266 uses espnow.h. These libraries are different. And the ESP32 codes are not compatible with the ESP8266.
      Regards,
      Sara

      Reply
  58. Hi sara
    How do I program a nodemcu esp 8266(master/slave) so that it receives value from one nodemcu esp 8266 (master)and then sends it to another nodemcu esp 8266(slave) using ESP-NOW

    Reply
  59. Hi Sarah,How i do program ESP-NOW One way (many to many) between three 3 nodemcu esp 8266,could you send me tutorial of this please

    Reply
  60. Hello Sara,
    Can you “daisy chain” boards together? Like can you have a master board (1) send a command to slave board (4) but the command would “relay” through slave board (2) and (3) to get to slave board (4). I want to make WS2812B lights for the tops of a row of fence posts and be able to send the color patterns “down the line”.
    Thanks for your response.

    Reply
    • Hi.
      Yes, that is possible.
      You just need to program each board to receive the messages from a certain board and then specify to which board it will send the message.
      Regards,
      Sara

      Reply
  61. Hi there Sara
    Right now, the program is such that pressing the button once turns on LED and pressing it again turns off
    Could you please tell me what changes should I make in the program so that the LED I connect to the output pin turns on only for the time I press the button. As soon as I release the button, the LED turn off. (Like a momentary switch)

    Reply
    • Hello Sankar,
      If i understand correctly from your code, you have a PIR outside the house with a ESP8266 and power in a box to detect and send message.
      Would you mind sharing your schematic too?
      Do you have power by battery or wires ?
      How long the battery last ?
      Can you develop the receiver to send a text message to an email ?
      This email will be great in case i am not home.
      It will help me to control my camera or my alarm.
      Thank you
      Ion.

      Reply
  62. This may sound obvious but I just wasted 3 hours troubleshooting this mistake (and I am not a noob – I should know better!). When using these example programs, if your ESPs have ever been used before it is important to set Erase Flash to “All Flash Contents” in the Arduino IDE Tools Menu when uploading the first time.

    I did not do that. I had Erase Flash set to “Sketch Only”. Something must have been lurking in memory from whatever I last used these ESPs for. The symptom was that 99% of all transmissions fail but every so often, just to add confussion, one will succeed. Erasing all flash contents solved the problem immediately. Live / Learn.

    Reply
  63. I have a project using ESPNOW, one sender (ESP01) to one receiver (NodeMCU). The send just outputs “1” to show it is powered up and communicating. I want to be able to detect on the NODMCU when the ESP01 is powered up (signal received) and when it is not (no signal received).

    I have tried to use information from the void OnDataRecv function but I am picking up incorrect signls from the ESP01 is there a really simple way of acheiveing this.

    Thanks

    Chris

    Reply
  64. Hi, i used the above skteches for a long time and they as they should do. Absolut imazing.
    By now, i had to change the code for a new receiver and his output. I use always ESP32.
    Every time i get an compilation Error, although on used sketches, which i can’t solve!
    Error code:
    D:\Daten\prog\Module\Modul_06_ESP32_Rcv_202230124\Modul_06_ESP32_Rcv_202230124.ino: In function ‘void OnDataRecv(const uint8_t*, const uint8_t*, int)’:
    D:\Daten\prog\Module\Modul_06_ESP32_Rcv_202230124\Modul_06_ESP32_Rcv_202230124.ino:55:47: error: ‘void* memcpy(void*, const void*, size_t)’
    writing to an object of type ‘struct_message’ {aka ‘struct struct_message’} with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Werror=class-memaccess]
    memcpy(&myData, incomingData, sizeof(myData));
    ^
    D:\Daten\prog\Module\Modul_06_ESP32_Rcv_202230124\Modul_06_ESP32_Rcv_202230124.ino:23:16: note: ‘struct_message’ {aka ‘struct struct_message’} declared here
    typedef struct struct_message {
    ^~~~~~~~~~~~~~
    cc1plus.exe: some warnings being treated as errors

    exit status 1

    Compilation error: ‘void* memcpy(void*, const void*, size_t)’ writing to an object of type ‘struct_message’ {aka ‘struct struct_message’}
    with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Werror=class-memaccess]

    May be, you now an answer to help me?
    with kindly regards
    walter

    Reply
    • Hi.
      Maybe you need to downgrade your ESP32 installation to an older version to be compatible with older codes?…
      I’m not sure…
      But you can try downgrading in Tools > Board > Boards Manager, search for ESP32, and downgrade to a previous version. Then, try it out again.
      Regards,
      Sara

      Reply
    • Hey, ran into the same problem. No idea what causes it or where to find documentation other than this, but by trial an error I found out that changing the OnDataRecv() function from what is provided in the tutorial to void OnDataRecv(uint8_t *mac_addr, uint8_t *data, uint8_t data_len) solves it. Im no expert C++ magician so no idea what was wrong, but it worked for me.

      Best of luck
      Viktor

      Reply
  65. Hi Sara. I really appreciate you for this wonderful tutorial.
    I have a problem if you could help.
    I have a single point loadcell and I want to send my loadcell data from one esp board to another. when I get data via TTL it works properly but when i want to send these data wireless and with the codes that you share it has so much noise and in some cases these data arent the same as data I received in serial monitor

    Reply
  66. Hello Sara,
    Excellent your work. I’ve been trying to keep up.
    I need some code indication for using esp8862 – espnow, master slave, unidirectional, where 3 buttons on the master trigger 3 ledes on the slave.
    Simple thing for beginner.
    Thank you very much if it’s possible, okay?
    Thank you, health!

    Reply
  67. Hi,
    When I upload your code for a one way communication I get “delivery success”.
    However, when I update the MAC address I get delivery failure.
    I worked through the addresses and found that if the first block is 0xbc, then it fails. If i change to 0xbd it works fine. Any ideas?

    Reply
  68. My project required a temporary Wi-Fi connection to set the time in a RTC. I then needed to use ESP-NOW to send/receive temperature data.

    I have had trouble getting ESPNOW working after I connected to Wi-Fi.

    I have now successfully used both Wi-Fi, and ESPNOW, between two ESP8266’s.

    Simply add:

    wifi_set_channel(6);

    to the last line of void setup(), on both the receiver and transmitter. I just picked a random channel. Before I added this line communication was VERY unreliable.

    From the Espressif documentation: “Can Wi-Fi be used with ESP-NOW at the same time? Yes, but it should be noted that the channel of ESP-NOW must be the same as that of the connected AP.”

    Reply
  69. I can’t find any information about using httpupdate with esp-now sender. Is it so obvious that nobody thinks it needs to be explained?
    I have esp-now working well with mqtt, but my senders are a bit inaccessible. All of the senders are turned off until motion turns them on so OTA won’t work.

    Reply
  70. Hi, I have just tested the connection between two esp8266 with Esp-now but the distance just only 12 meters, longer than 12 meters the connection is lost.The sender is esp8266 12-e. The receiver is esp8266 12-e Node MCU kit. Maybe the sender and receiver should be the same. Thank for your reply

    Reply
  71. I try your example with a Wemos Mini as transmitter and a DOIT-ESP8266 as receiver.
    With your example sketch the range is up to 20 meters also with an intermediate wall.
    But if I change the values with that of a BME280 putting four struct values to float the range is limited to 2 or 3 meters and it needs 2 or 3 sending cycles to update values in receiver.
    Anyone experienced and solved that?
    Thanks
    Renzo

    Reply
  72. Thanks a lot for this tutorial on ESP8266. You have save a lot of time and energy trying to figure out the working between ESP32 vs ESP8266.

    Thanks again.

    Reply
  73. Has anyone tried this recently? Some time ago, I was getting fast speed. with the latest arduino/esp etc is something broken? i have just tried 30 esp8266 chips from different suppliers and seem to be getting 10 fails in transmission to one success. Something has been broken. I have tried the old IDE and the new IDE ie version 1.8.18 and version 2.xx.xx

    Reply
    • After days of testing. Turns out a brand name commercial home automation power controller had gone faulty and was blocking channel one. Was sending a carrier wave. All is working again.

      Reply
  74. Hi Its very Good Examples for WIFI Networking.
    I Want to Know, Its Possible, to Disable Receive data when its transmit data to Other Module ?

    Reply
  75. Hi, i have try your project on 3 types esp8266 board,
    they are nodemcu 8266 (in your example), wemos D1 R2 & Wemos D1 Mini.
    but for 3 types of board i have some problem, if the slaves range > 1 meter it will fail to send.
    in your tutorial wrote the range up tp 140m, but mine can’t.
    FYI, i have 3pcs of each types, and already change each board type which the broadcaster and receiver and still have same result.
    what is i’m wrong? my code is the same as yours.
    when i’m googling, i found : esp32.com/viewtopic.php?t=33291
    // Set Long Range Mode
    esp_wifi_set_protocol( WIFI_IF_STA , WIFI_PROTOCOL_LR);
    but its only for esp32? cant implement into esp8266?
    please advice…

    Reply
    • Hi.
      I’m not sure, but I think it’s a problem with the Wemos D1 mini boards.
      Many of our readers complain about ESP-NOW when using those boards.
      Regards,
      Sara

      Reply
  76. Hello, can you help me? Esp two now. adruino 2560 conversion 74HC4050__3V => (mosi.miso.reset,slk,cs,int) EPS TWO NOW ==> signal <== EPS TWO NOW => (mosi.miso.reset,slk,cs,int) => LCD RA8875. cable connected works LCD but I want ESP TWO NOW without cable.

    Reply
  77. Hello,
    Thank you for another excellent tutorial, they are really helpful. I have ESP-NOW working but I haven’t found any recent code for getting RSSI to work. There are older examples from 3 or 4 years ago but I found that Espresif has updated their code/files to allow the extraction of RSSI. Do you have any examples of how to get RSSI using ESP-NOW? Thank you so much for any assistance you may offer. I am using a transmitter, receiver and WiFi link, all ESP8266. regards, Paul

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.