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.

// Complete Instructions to Get and Change ESP MAC Address: https://RandomNerdTutorials.com/get-change-esp32-esp8266-mac-address-arduino/

#include <ESP8266WiFi.h>

void setup(){
  Serial.begin(115200);
  Serial.println();
  Serial.print("ESP8266 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_rcv_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 program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

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

  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
    • Hi Fernando.
      Thank you for your comment.
      Unfortunately, we don’t have the time or resources to build our courses in Spanish.
      Regards,
      Sara

      Reply
    • Google Chrome (and probably other browsers) have the ability to translate web pages for you. Often a pop-up dialogue box will appear offering to do the translation.

      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
  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
  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
  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

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.