{"id":96216,"date":"2020-04-24T13:58:04","date_gmt":"2020-04-24T13:58:04","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=96216"},"modified":"2024-06-11T16:54:20","modified_gmt":"2024-06-11T16:54:20","slug":"esp-now-many-to-one-esp32","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp-now-many-to-one-esp32\/","title":{"rendered":"ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one)"},"content":{"rendered":"\n<p>This tutorial shows how to set up an ESP32 board to receive data from multiple ESP32 boards via ESP-NOW communication protocol (many-to-one configuration). This configuration is ideal if you want to collect data from several sensors nodes into one ESP32 board. The boards will be programmed using Arduino IDE.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-ESP32-Receive-Data-Multiple-Boards-Many-to-One-Arduino-IDE.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP-NOW with ESP32: Receive Data from Multiple Boards many-to-one\" class=\"wp-image-96304\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-ESP32-Receive-Data-Multiple-Boards-Many-to-One-Arduino-IDE.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-ESP32-Receive-Data-Multiple-Boards-Many-to-One-Arduino-IDE.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-ESP32-Receive-Data-Multiple-Boards-Many-to-One-Arduino-IDE.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-ESP32-Receive-Data-Multiple-Boards-Many-to-One-Arduino-IDE.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>We have other guides related with ESP-NOW that you might be interested in:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-esp32-arduino-ide\/\">Getting Started with ESP-NOW (ESP32 with Arduino IDE)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-two-way-communication-esp32\/\">ESP-NOW Two-Way Communication Between ESP32 Boards<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-one-to-many-esp32-esp8266\/\">ESP-NOW with ESP32: Send Data to Multiple Boards (one-to-many)<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>This tutorial shows how to setup an ESP32 board to receive data from multiple ESP32 boards via ESP-NOW communication protocol (many-to-one configuration) as shown in the following figure.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"649\" height=\"375\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP_NOW_one_slave_multiple_masters.png?resize=649%2C375&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP-NOW with ESP32 Receive Data from Multiple Boards (many-to-one) Project Overview\" class=\"wp-image-93052\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP_NOW_one_slave_multiple_masters.png?w=649&amp;quality=100&amp;strip=all&amp;ssl=1 649w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP_NOW_one_slave_multiple_masters.png?resize=300%2C173&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 649px) 100vw, 649px\" \/><\/figure><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>One ESP32 board acts as a receiver\/slave;<\/li>\n\n\n\n<li>Multiple ESP32 boards act as senders\/masters. We&#8217;ve tested this example with 5 ESP32 sender boards and it worked fine. You should be able to add more boards to your setup;<\/li>\n\n\n\n<li>The sender board receives an acknowledge message indicating if the message was successfully delivered or not;<\/li>\n\n\n\n<li>The ESP32 receiver board receives the messages from all senders and identifies which board sent the message;<\/li>\n\n\n\n<li>As an example, we\u2019ll exchange random values between the boards. You should modify this example to send commands or sensor readings (<a href=\"https:\/\/randomnerdtutorials.com\/esp-now-two-way-communication-esp32\/\">exchange sensor readings using ESP-NOW<\/a>).<\/li>\n<\/ul>\n\n\n\n<p class=\"rntbox rntclblue\"><strong>Note: <\/strong> in the ESP-NOW documentation there isn\u2019t such thing as \u201csender\/master\u201d and \u201creceiver\/slave\u201d. Every board can be a sender or receiver. However, to keep things clear we\u2019ll use the terms \u201csender\u201d and \u201creceiver\u201d or \u201cmaster\u201d and \u201cslave\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>We\u2019ll program the ESP32 boards using Arduino IDE, so before proceeding with this tutorial, make sure you have these boards installed in your Arduino IDE.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing ESP32 Board in Arduino IDE (Windows, Mac OS X, and Linux)<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Parts Required<\/h2>\n\n\n\n<p>To follow this tutorial, you need multiple ESP32 boards. All ESP32 models should work. We&#8217;ve experimented with different models of ESP32 boards and all worked well (<a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\">ESP32 DOIT board<\/a>, <a href=\"https:\/\/randomnerdtutorials.com\/ttgo-t-journal-esp32-camera-getting-started\/\">TTGO T-Journal<\/a>, <a href=\"https:\/\/randomnerdtutorials.com\/esp32-built-in-oled-ssd1306\/\">ESP32 with OLED board<\/a> and <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-video-streaming-face-recognition-arduino-ide\/\">ESP32-CAM<\/a>).<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32<\/a>\u00a0(read\u00a0<a href=\"https:\/\/makeradvisor.com\/esp32-development-boards-review-comparison\/\" target=\"_blank\" rel=\"noreferrer noopener\">Best ESP32 development boards<\/a>)<\/li>\n<\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting the Receiver Board MAC Address<\/h2>\n\n\n\n<p>To send messages via ESP-NOW, you need to know the receiver board\u2019s <a href=\"https:\/\/randomnerdtutorials.com\/get-change-esp32-esp8266-mac-address-arduino\/\">MAC address<\/a>. Each board has a unique MAC address (learn how to <a href=\"https:\/\/randomnerdtutorials.com\/get-change-esp32-esp8266-mac-address-arduino\/\">Get and Change the ESP32 MAC Address<\/a>).<\/p>\n\n\n\n<p>Upload the following code to your ESP32 receiver board to get is MAC address.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n  Complete project details at https:\/\/RandomNerdTutorials.com\/get-change-esp32-esp8266-mac-address-arduino\/\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.  \n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n*\/\n#ifdef ESP32\n  #include &lt;WiFi.h&gt;\n  #include &lt;esp_wifi.h&gt;\n#else\n  #include &lt;ESP8266WiFi.h&gt;\n#endif\n\nvoid setup(){\n  Serial.begin(115200);\n\n  Serial.print(&quot;ESP Board MAC Address: &quot;);\n  #ifdef ESP32\n    WiFi.mode(WIFI_STA);\n    WiFi.STA.begin();\n    uint8_t baseMac[6];\n    esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);\n    if (ret == ESP_OK) {\n      Serial.printf(&quot;%02x:%02x:%02x:%02x:%02x:%02x\\n&quot;,\n                    baseMac[0], baseMac[1], baseMac[2],\n                    baseMac[3], baseMac[4], baseMac[5]);\n    } else {\n      Serial.println(&quot;Failed to read MAC address&quot;);\n    }\n  #else\n    Serial.println(WiFi.macAddress());\n  #endif\n}\n \nvoid loop(){\n\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP\/ESP_Get_MAC_Address.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>After uploading the code, press the RST\/EN button, and the MAC address should be displayed on the Serial Monitor. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"601\" height=\"445\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP32-MAC-Address-Serial-Monitor.png?resize=601%2C445&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 board MAC Address with Arduino IDE Serial Monitor\" class=\"wp-image-96297\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP32-MAC-Address-Serial-Monitor.png?w=601&amp;quality=100&amp;strip=all&amp;ssl=1 601w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP32-MAC-Address-Serial-Monitor.png?resize=300%2C222&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 601px) 100vw, 601px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">ESP32 Sender Code (ESP-NOW)<\/h2>\n\n\n\n<p>The receiver can identify each sender by its unique MAC address. However, dealing with different MAC addresses on the Receiver side to identify which board sent which message can be tricky. <\/p>\n\n\n\n<p>So, to make things easier, we&#8217;ll identify each board with a unique number (<span class=\"rnthl rntliteral\">id<\/span>) that starts at 1. If you have three boards, one will have ID number 1, the other number 2, and finally number 3. The ID will be sent to the receiver alongside the other variables. <\/p>\n\n\n\n<p>As an example, we&#8217;ll exchange a structure that contains the board <span class=\"rnthl rntliteral\">id<\/span> number and two random numbers <span class=\"rnthl rntliteral\">x<\/span> and <span class=\"rnthl rntliteral\">y<\/span> as shown in the figure below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"928\" height=\"704\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-Receive-Data-Structures-from-multiple-boards.jpg?resize=928%2C704&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP-NOW with ESP32 Receive Data from Multiple Boards (many-to-one) Sample Data\" class=\"wp-image-96300\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-Receive-Data-Structures-from-multiple-boards.jpg?w=928&amp;quality=100&amp;strip=all&amp;ssl=1 928w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-Receive-Data-Structures-from-multiple-boards.jpg?resize=300%2C228&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-Receive-Data-Structures-from-multiple-boards.jpg?resize=768%2C583&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 928px) 100vw, 928px\" \/><\/figure><\/div>\n\n\n<p>Upload the following code to each of your sender boards. Don&#8217;t forget to increment the <span class=\"rnthl rntliteral\">id<\/span> number for each sender board.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*********\n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n  Complete project details at https:\/\/RandomNerdTutorials.com\/esp-now-many-to-one-esp32\/\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n*********\/\n#include &lt;esp_now.h&gt;\n#include &lt;WiFi.h&gt;\n\n\/\/ REPLACE WITH THE RECEIVER'S MAC Address\nuint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\n\n\/\/ Structure example to send data\n\/\/ Must match the receiver structure\ntypedef struct struct_message {\n    int id; \/\/ must be unique for each sender board\n    int x;\n    int y;\n} struct_message;\n\n\/\/ Create a struct_message called myData\nstruct_message myData;\n\n\/\/ Create peer interface\nesp_now_peer_info_t peerInfo;\n\n\/\/ callback when data is sent\nvoid OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {\n  Serial.print(&quot;\\r\\nLast Packet Send Status:\\t&quot;);\n  Serial.println(status == ESP_NOW_SEND_SUCCESS ? &quot;Delivery Success&quot; : &quot;Delivery Fail&quot;);\n}\n \nvoid setup() {\n  \/\/ Init Serial Monitor\n  Serial.begin(115200);\n\n  \/\/ Set device as a Wi-Fi Station\n  WiFi.mode(WIFI_STA);\n\n  \/\/ Init ESP-NOW\n  if (esp_now_init() != ESP_OK) {\n    Serial.println(&quot;Error initializing ESP-NOW&quot;);\n    return;\n  }\n\n  \/\/ Once ESPNow is successfully Init, we will register for Send CB to\n  \/\/ get the status of Trasnmitted packet\n  esp_now_register_send_cb(OnDataSent);\n  \n  \/\/ Register peer\n  memcpy(peerInfo.peer_addr, broadcastAddress, 6);\n  peerInfo.channel = 0;  \n  peerInfo.encrypt = false;\n  \n  \/\/ Add peer        \n  if (esp_now_add_peer(&amp;peerInfo) != ESP_OK){\n    Serial.println(&quot;Failed to add peer&quot;);\n    return;\n  }\n}\n \nvoid loop() {\n  \/\/ Set values to send\n  myData.id = 1;\n  myData.x = random(0,50);\n  myData.y = random(0,50);\n\n  \/\/ Send message via ESP-NOW\n  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &amp;myData, sizeof(myData));\n   \n  if (result == ESP_OK) {\n    Serial.println(&quot;Sent with success&quot;);\n  }\n  else {\n    Serial.println(&quot;Error sending the data&quot;);\n  }\n  delay(10000);\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP\/ESP_NOW\/ESP_NOW_Sender_Multiple_Boards.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>Include the <span class=\"rnthl rntliteral\">WiFi<\/span> and <span class=\"rnthl rntliteral\">esp_now<\/span> libraries.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;esp_now.h&gt;\n#include &lt;WiFi.h&gt;<\/code><\/pre>\n\n\n\n<p>Insert the receiver&#8217;s MAC address on the following line.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>uint8_t broadcastAddress&#091;] = {0x30, 0xAE, 0xA4, 0x15, 0xC7, 0xFC};<\/code><\/pre>\n\n\n\n<p>Then, create a structure that contains the data we want to send. We called this structure&nbsp;<span class=\"rnthl rntliteral\">struct_message<\/span>&nbsp;and it contains three integer variables: the board <span class=\"rnthl rntliteral\">id<\/span>, <span class=\"rnthl rntliteral\">x<\/span> and <span class=\"rnthl rntliteral\">y<\/span>. You can change this to send whatever variable types you want (but don&#8217;t forget to change that on the receiver side too).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>typedef struct struct_message {\n  int id; \/\/ must be unique for each sender board\n  int x;\n  int y;\n} struct_message;<\/code><\/pre>\n\n\n\n<p>Create a new variable of type <span class=\"rnthl rntliteral\">struct_message<\/span> that is called <span class=\"rnthl rntliteral\">myData<\/span> that will store the variables&#8217; values.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>struct_message myData;<\/code><\/pre>\n\n\n\n<p>Create a variable of type <span class=\"rnthl rntliteral\">esp_now_peer_info_t<\/span> to store information about the peer.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>esp_now_peer_info_t peerInfo;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">OnDataSent() callback function<\/h4>\n\n\n\n<p>Next, define the <span class=\"rnthl rntliteral\">OnDataSent()<\/span> function. This is a callback function that will be executed when a message is sent. In this case, this function prints if the message was successfully delivered or not.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {\n  Serial.print(\"\\r\\nLast Packet Send Status:\\t\");\n  Serial.println(status == ESP_NOW_SEND_SUCCESS ? \"Delivery Success\" : \"Delivery Fail\");\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">setup()<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, initialize the serial monitor for debugging purposes:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.begin(115200);<\/code><\/pre>\n\n\n\n<p>Set the device as a Wi-Fi station:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>WiFi.mode(WIFI_STA);<\/code><\/pre>\n\n\n\n<p>Initialize ESP-NOW:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (esp_now_init() != ESP_OK) {\n  Serial.println(\"Error initializing ESP-NOW\");\n  return;\n}<\/code><\/pre>\n\n\n\n<p>After successfully initializing ESP-NOW, register the callback function that will be called when a message is sent. In this case, register for the <span class=\"rnthl rntliteral\">OnDataSent()<\/span> function created previously.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>esp_now_register_send_cb(OnDataSent);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Add peer device<\/h3>\n\n\n\n<p>To send data to another board (the receiver), you need to pair it as a peer. The following lines register and add a new peer.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>memcpy(peerInfo.peer_addr, broadcastAddress, 6);\npeerInfo.channel = 0;\npeerInfo.encrypt = false;\n\n\/\/ Add peer\nif (esp_now_add_peer(&amp;peerInfo) != ESP_OK){\n  Serial.println(\"Failed to add peer\");\n  return;\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">loop()<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, we&#8217;ll send a message via ESP-NOW every 10 seconds (you can change this delay time).<\/p>\n\n\n\n<p>Assign a value to each variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>myData.id = 1;\nmyData.x = random(0,50);\nmyData.y = random(0,50);<\/code><\/pre>\n\n\n\n<p><strong>Don&#8217;t forget to change the id for each sender board.<\/strong><\/p>\n\n\n\n<p>Remember that <span class=\"rnthl rntliteral\">myData<\/span> is a structure. Here assign the values that you want to send inside the structure. In this case, we&#8217;re just sending the <span class=\"rnthl rntliteral\">id<\/span> and random values <span class=\"rnthl rntliteral\">x<\/span> and <span class=\"rnthl rntliteral\">y<\/span>. In a practical application these should be replaced with commands or sensor readings, for example.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Send ESP-NOW message<\/h4>\n\n\n\n<p>Finally, send the message via ESP-NOW.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Send message via ESP-NOW\nesp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &amp;myData, sizeof(myData));\n \nif (result == ESP_OK) {\n  Serial.println(\"Sent with success\");\n}\nelse {\n  Serial.println(\"Error sending the data\");\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">ESP32 Receiver Code (ESP-NOW)<\/h2>\n\n\n\n<p>Upload the following code to your ESP32 receiver board. The code is prepared to receive data from three different boards. You can easily modify the code to receive data from a different number of boards.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*********\n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n  Complete project details at https:\/\/RandomNerdTutorials.com\/esp-now-many-to-one-esp32\/\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.  \n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n*********\/\n#include &lt;esp_now.h&gt;\n#include &lt;WiFi.h&gt;\n\n\/\/ Structure example to receive data\n\/\/ Must match the sender structure\ntypedef struct struct_message {\n  int id;\n  int x;\n  int y;\n}struct_message;\n\n\/\/ Create a struct_message called myData\nstruct_message myData;\n\n\/\/ Create a structure to hold the readings from each board\nstruct_message board1;\nstruct_message board2;\nstruct_message board3;\n\n\/\/ Create an array with all the structures\nstruct_message boardsStruct[3] = {board1, board2, board3};\n\n\/\/ callback function that will be executed when data is received\nvoid OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {\n  char macStr[18];\n  Serial.print(&quot;Packet received from: &quot;);\n  snprintf(macStr, sizeof(macStr), &quot;%02x:%02x:%02x:%02x:%02x:%02x&quot;,\n           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);\n  Serial.println(macStr);\n  memcpy(&amp;myData, incomingData, sizeof(myData));\n  Serial.printf(&quot;Board ID %u: %u bytes\\n&quot;, myData.id, len);\n  \/\/ Update the structures with the new incoming data\n  boardsStruct[myData.id-1].x = myData.x;\n  boardsStruct[myData.id-1].y = myData.y;\n  Serial.printf(&quot;x value: %d \\n&quot;, boardsStruct[myData.id-1].x);\n  Serial.printf(&quot;y value: %d \\n&quot;, boardsStruct[myData.id-1].y);\n  Serial.println();\n}\n \nvoid setup() {\n  \/\/Initialize Serial Monitor\n  Serial.begin(115200);\n  \n  \/\/Set device as a Wi-Fi Station\n  WiFi.mode(WIFI_STA);\n\n  \/\/Init ESP-NOW\n  if (esp_now_init() != ESP_OK) {\n    Serial.println(&quot;Error initializing ESP-NOW&quot;);\n    return;\n  }\n  \n  \/\/ Once ESPNow is successfully Init, we will register for recv CB to\n  \/\/ get recv packer info\n  esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));\n}\n \nvoid loop() {\n  \/\/ Acess the variables for each board\n  \/*int board1X = boardsStruct[0].x;\n  int board1Y = boardsStruct[0].y;\n  int board2X = boardsStruct[1].x;\n  int board2Y = boardsStruct[1].y;\n  int board3X = boardsStruct[2].x;\n  int board3Y = boardsStruct[2].y;*\/\n\n  delay(10000);  \n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP\/ESP_NOW\/ESP_NOW_Receiver_Multiple_Boards.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>Similarly to the sender, start by including the libraries:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;esp_now.h&gt;\n#include &lt;WiFi.h&gt;<\/code><\/pre>\n\n\n\n<p>Create a structure to receive the data. This structure should be the same defined in the sender sketch.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>typedef struct struct_message {\n  int id;\n  int x;\n  int y;\n} struct_message;<\/code><\/pre>\n\n\n\n<p>Create a&nbsp;<span class=\"rnthl rntliteral\">struct_message<\/span>&nbsp;variable called&nbsp;<span class=\"rnthl rntliteral\">myData<\/span> that will hold the data received.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>struct_message myData;<\/code><\/pre>\n\n\n\n<p>Then, create a <span class=\"rnthl rntliteral\">struct_message<\/span> variable for each board, so that we can assign the received data to the corresponding board. Here we&#8217;re creating structures for three sender boards. If you have more sender boards, you need to create more structures.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>struct_message board1;\nstruct_message board2;\nstruct_message board3;<\/code><\/pre>\n\n\n\n<p>Create an array that contains all the board structures. If you&#8217;re using a different number of boards you need to change that.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>struct_message boardsStruct&#091;3] = {board1, board2, board3};<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">onDataRecv()<\/h3>\n\n\n\n<p>Create a callback function that is called when the ESP32 receives the data via ESP-NOW. The function is called <span class=\"rnthl rntliteral\">onDataRecv()<\/span> and should accept several parameters as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {<\/code><\/pre>\n\n\n\n<p>Get the board MAC address:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>char macStr&#091;18];\nSerial.print(\"Packet received from: \");\nsnprintf(macStr, sizeof(macStr), \"%02x:%02x:%02x:%02x:%02x:%02x\",\n         mac_addr&#091;0], mac_addr&#091;1], mac_addr&#091;2], mac_addr&#091;3], mac_addr&#091;4], mac_addr&#091;5]);\nSerial.println(macStr);<\/code><\/pre>\n\n\n\n<p>Copy the content of the <span class=\"rnthl rntliteral\">incomingData<\/span> data variable into the <span class=\"rnthl rntliteral\">myData<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>memcpy(&amp;myData, incomingData, sizeof(myData));<\/code><\/pre>\n\n\n\n<p>Now, the&nbsp;<span class=\"rnthl rntliteral\">myData<\/span>&nbsp;structure contains several variables with the values sent by one of the ESP32 senders. We can identify which board send the packet by its ID: <span class=\"rnthl rntliteral\">myData.id<\/span>.<\/p>\n\n\n\n<p>This way, we can assign the values received to the corresponding boards on the <span class=\"rnthl rntliteral\">boardsStruct<\/span> array:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>boardsStruct&#091;myData.id-1].x = myData.x;\nboardsStruct&#091;myData.id-1].y = myData.y;<\/code><\/pre>\n\n\n\n<p>For example, imagine you receive a packet from board with id 2. The value of <span class=\"rnthl rntliteral\">myData.id<\/span>, is 2.<\/p>\n\n\n\n<p>So, you want to update the values of the <span class=\"rnthl rntliteral\">board2<\/span> structure. The <span class=\"rnthl rntliteral\">board2<\/span> structure is the element with index 1 on the <span class=\"rnthl rntliteral\">boardsStruct<\/span> array. That&#8217;s why we subtract 1, because arrays in C have 0 indexing. It may help if you take a look at the following image.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"722\" height=\"271\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-Receive-Data-Multiple-Boards-Array-Structures.png?resize=722%2C271&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-96307\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-Receive-Data-Multiple-Boards-Array-Structures.png?w=722&amp;quality=100&amp;strip=all&amp;ssl=1 722w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-Receive-Data-Multiple-Boards-Array-Structures.png?resize=300%2C113&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">setup()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, initialize the Serial Monitor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.begin(115200);<\/code><\/pre>\n\n\n\n<p>Set the device as a Wi-Fi Station.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>WiFi.mode(WIFI_STA);<\/code><\/pre>\n\n\n\n<p>Initialize ESP-NOW:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (esp_now_init() != ESP_OK) {\n  Serial.println(\"Error initializing ESP-NOW\");\n  return;\n}<\/code><\/pre>\n\n\n\n<p>Register for a callback function that will be called when data is received. In this case, we register for the <span class=\"rnthl rntliteral\">OnDataRecv()<\/span> function that was created previously.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));<\/code><\/pre>\n\n\n\n<p>The following lines commented on the loop exemplify what you need to do if you want to access the variables of each board structure. For example, to access the <span class=\"rnthl rntliteral\">x<\/span> value of <span class=\"rnthl rntliteral\">board1<\/span>:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>int board1X = boardsStruct&#091;0].x;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Demonstration<\/h2>\n\n\n\n<p>Upload the sender code to each of your sender boards. Don&#8217;t forget to give a different ID to each board.<\/p>\n\n\n\n<p>Upload the receiver code to the ESP32 receiver board. Don&#8217;t forget to modify the structure to match the number of sender boards.<\/p>\n\n\n\n<p>On the senders&#8217; Serial Monitor, you should get a &#8220;Delivery Success&#8221; message if the messages are delivered correctly.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"711\" height=\"445\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/Send-data-ESP-NOW-acknowledge-message-serial-monitor.png?resize=711%2C445&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP-NOW Sending Packets Delivery Success ESP32 Serial Monitor\" class=\"wp-image-96309\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/Send-data-ESP-NOW-acknowledge-message-serial-monitor.png?w=711&amp;quality=100&amp;strip=all&amp;ssl=1 711w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/Send-data-ESP-NOW-acknowledge-message-serial-monitor.png?resize=300%2C188&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 711px) 100vw, 711px\" \/><\/figure><\/div>\n\n\n<p>On the receiver board, you should be receiving the packets from all the other boards. In this test, we were receiving data from 5 different boards.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"779\" height=\"463\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/Receive-data-multiple-ESP32-Serial-Monitor.png?resize=779%2C463&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP-NOW Receive Data from Multiple Boards ESP32 Serial Monitor\" class=\"wp-image-96310\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/Receive-data-multiple-ESP32-Serial-Monitor.png?w=779&amp;quality=100&amp;strip=all&amp;ssl=1 779w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/Receive-data-multiple-ESP32-Serial-Monitor.png?resize=300%2C178&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/Receive-data-multiple-ESP32-Serial-Monitor.png?resize=768%2C456&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 779px) 100vw, 779px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you&#8217;ve learned how to set up an ESP32 to receive data from multiple ESP32 boards using ESP-NOW (many-to-one configuration).<\/p>\n\n\n\n<p>As an example, we&#8217;ve exchanged random numbers. In a real application, those can be replaced with actual sensor readings or commands. This is ideal if you want to collect data from several sensor nodes. You can take this project further and create a web server on the receiver board to displays the received messages.<\/p>\n\n\n\n<p>To use Wi-Fi to create a web server and use ESP-NOW simultaneously, you need to set up the ESP32 both as a Wi-Fi station and access point. Additionally, you need to set a different Wi-Fi channel: one for ESP-NOW and the other for the station. You can follow the next tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp-now-wi-fi-web-server\/\">ESP32: ESP-NOW Web Server Sensor Dashboard (ESP-NOW + Wi-Fi)<\/a><\/li>\n<\/ul>\n\n\n\n<p>We have other tutorials related with ESP-NOW that you may like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-esp32-arduino-ide\/\">Getting Started with ESP-NOW (ESP32 with Arduino IDE)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-two-way-communication-esp32\/\">ESP-NOW Two-Way Communication Between ESP32 Boards<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-one-to-many-esp32-esp8266\/\">ESP-NOW with ESP32: Send Data to Multiple Boards (one-to-many)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-esp8266-nodemcu-arduino-ide\/\">Getting Started with ESP-NOW (ESP8266 NodeMCU with Arduino IDE)<\/a><\/li>\n<\/ul>\n\n\n\n<p>Learn more about ESP32 with our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE (eBook + video course)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32\/\">More ESP32 tutorials and projects&#8230;<\/a><\/li>\n<\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to set up an ESP32 board to receive data from multiple ESP32 boards via ESP-NOW communication protocol (many-to-one configuration). This configuration is ideal if you want &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp-now-many-to-one-esp32\/#more-96216\" aria-label=\"Read more about ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":96304,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[281,276,277,299,264],"tags":[],"class_list":["post-96216","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/04\/ESP-NOW-ESP32-Receive-Data-Multiple-Boards-Many-to-One-Arduino-IDE.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/96216","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=96216"}],"version-history":[{"count":6,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/96216\/revisions"}],"predecessor-version":[{"id":158794,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/96216\/revisions\/158794"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/96304"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=96216"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=96216"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=96216"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}