Implementing ESP-NOW Protocol between two ESP8266 modules

Overview

I am currently working to implement ESP-NOW Protocol between two ESP8266 Modules. One Module acts as Master and it sends a message (say "Hello") and the other module, which is the slave, received the message and displays it on the serial monitor in Arduino IDE.
Now I am attempting to save the Received Data, on the Slave Module, to a MySQL Database using a PHP script.
I tried making changes in the code accordingly but facing some issues


Code for Master Device

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

//Slave MAC addresses

uint8_t slaveMac[] = { 0x40, 0x91, 0x51, 0x55, 0xA2, 0x51 };

// Structure to hold the data
typedef struct {
  char message[50];
} MyData;

MyData dataToSend;

const char *ssid = "Arya_Krish";
const char *password = "$Disco427";

void onDataReceived(uint8_t *mac, uint8_t *data, uint8_t len) {
  // Copy received data to our data structure
  memcpy(&dataToSend, data, sizeof(dataToSend));

  // Null-terminate the message to print it
  dataToSend.message[len] = '\0';

  // Print received data
  Serial.print("Received from ");
  for (int i = 0; i < 6; i++) {
    Serial.print(mac[i], HEX);
    if (i < 5) {
      Serial.print(":");
    }
  }
  Serial.print(" - Message: ");
  Serial.println(dataToSend.message);
}

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

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

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

  // Register callback function to handle received data
  esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
  esp_now_register_recv_cb(onDataReceived);

  // Add the Slave to peer list
  esp_now_add_peer(slaveMac, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);

  Serial.println("Master module initialized");
}

void loop() {
  // Send data to the Slave
  snprintf(dataToSend.message, sizeof(dataToSend.message), "Hello");
  esp_now_send(slaveMac, (uint8_t *)&dataToSend, sizeof(dataToSend));
  Serial.println("Message Sent");

  // Wait for 2 seconds before sending the next message
  delay(2000);
}

Code for Slave Device

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

// Structure to hold the data
typedef struct {
  char message[50];
} MyData;

MyData receivedData;

// WiFi credentials
const char *ssid = "wifi_ssid";
const char *password = "wifi_password";

// MySQL server details
const char *serverAddress = "192.168.1.10";
const int serverPort = 8080;
const char *phpScript = "/espNow/server.php";

const String url = "http://" + String(serverAddress) + ":" + String(serverPort) + String(phpScript);

void onDataReceived(uint8_t *mac, uint8_t *data, uint8_t len) {
  // Copy received data to our data structure
  memcpy(&receivedData, data, sizeof(receivedData));

  // Null-terminate the message to print it
  receivedData.message[len] = '\0';

  // Print received data
  Serial.print("Received from ");
  for (int i = 0; i < 6; i++) {
    Serial.print(mac[i], HEX);
    if (i < 5) {
      Serial.print(":");
    }
  }
  Serial.print(" - Message: ");
  Serial.println(receivedData.message);

  sendDataToMySQL();
}

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

  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

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

  // Register callback function to handle received data
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
  esp_now_register_recv_cb(onDataReceived);

  Serial.println("Slave module initialized");
}

void loop() {
  // Your code here (if needed)
  delay(1500);
}

void sendDataToMySQL() {
  if (WiFi.status() == WL_CONNECTED) {
    WiFiClient client;
    HTTPClient http;

    char dataBuffer[50];
    strncpy(dataBuffer, receivedData.message, sizeof(dataBuffer));

    http.begin(client, url);
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");

    int httpResCode = http.POST(dataBuffer);

    Serial.print("HTTP Response Code: ");
    Serial.println(httpResCode);

    http.end();
  }
}

When I run the Slave code, and try to send a POST request using httpClient, I get an exception(9) error and the module crashes. I tried to find solutions for it but I couldn't.
I'll share the Serial Monitor output Below

Connecting to WiFi...
Connecting to WiFi...
Connected to WiFi
Slave module initialized
Received from C8:C9:A3:52:F3:68 - Message: Hello

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (9):
epc1=0x401058bc epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000003 depc=0x00000000

>>>stack>>>

ctx: sys
sp: 3fffea80 end: 3fffffb0 offset: 0150
3fffebd0:  40105aed 002d1c6b 3ffee72c 00000000  
3fffebe0:  3ffee190 3ffee72c 000000fa 40214034  
3fffebf0:  00000000 001544e7 40204da4 00001388  
3fffec00:  3ffee72c 0000118b 00001388 00001388
..........

As you are connecting both ESP8266s to the WiFi anyway you can use UDP or TCP for sending data.

ESP-NOW is intended to be used of you have no WiFi-router

There is a plugin tool for the arduino_IDE called exception-decoder
Which you can install.

You load exact that code that is running in your slave into the arduino ide compile it
and after compiling start the exception-decoder and paste the information from the serial monitor into the exception-decoder and the exception-decoder will guide you to that lines of code that caused the exception

best regards Stefan

Have you read this

The Problem is basically occuring when I run a POST request using HttpClient
If I comment out the Request line and just print the message in Serial monitor, Everything works perfectly fine.
The line in the Slave Module code where I execute int httpResCode = http.POST(data); is the one which is causing problem.

You mean this function

void sendDataToMySQL() {
  if (WiFi.status() == WL_CONNECTED) {
    WiFiClient client;
    HTTPClient http;

    char dataBuffer[50];
    strncpy(dataBuffer, receivedData.message, sizeof(dataBuffer));

    http.begin(client, url);
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");

    int httpResCode = http.POST(dataBuffer);

    Serial.print("HTTP Response Code: ");
    Serial.println(httpResCode);

    http.end();
  }

Have you checked if dataBuffer is valid?

Never used client post before.
Did you write this code based on a working code?
If yes did you modify this working code in small steps towards the code like above?
and did you test all these small step modifications with the working code?

best regards Stefan

Hello Stefan,
I did check the dataBuffer and it is valid. I tried debugging the code by printing out the message value in serial monitor. Everything is working perfectly fine until I execute the POST method using HTTPClient. And I did not use client post before

This sentence in itself says "I solve the problem myself"

what did you do in detail to check if the buffer is valid???

I took the slave-device code that you posted in post # 1
for convenience 1 to 1 posted here again

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

// Structure to hold the data
typedef struct {
  char message[50];
} MyData;

MyData receivedData;

// WiFi credentials
const char *ssid = "wifi_ssid";
const char *password = "wifi_password";

// MySQL server details
const char *serverAddress = "192.168.1.10";
const int serverPort = 8080;
const char *phpScript = "/espNow/server.php";

const String url = "http://" + String(serverAddress) + ":" + String(serverPort) + String(phpScript);

void onDataReceived(uint8_t *mac, uint8_t *data, uint8_t len) {
  // Copy received data to our data structure
  memcpy(&receivedData, data, sizeof(receivedData));

  // Null-terminate the message to print it
  receivedData.message[len] = '\0';

  // Print received data
  Serial.print("Received from ");
  for (int i = 0; i < 6; i++) {
    Serial.print(mac[i], HEX);
    if (i < 5) {
      Serial.print(":");
    }
  }
  Serial.print(" - Message: ");
  Serial.println(receivedData.message);

  sendDataToMySQL();
}

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

  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

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

  // Register callback function to handle received data
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
  esp_now_register_recv_cb(onDataReceived);

  Serial.println("Slave module initialized");
}

void loop() {
  // Your code here (if needed)
  delay(1500);
}

void sendDataToMySQL() {
  if (WiFi.status() == WL_CONNECTED) {
    WiFiClient client;
    HTTPClient http;

    char dataBuffer[50];
    strncpy(dataBuffer, receivedData.message, sizeof(dataBuffer));

    http.begin(client, url);
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");

    int httpResCode = http.POST(dataBuffer);

    Serial.print("HTTP Response Code: ");
    Serial.println(httpResCode);

    http.end();
  }
}

compiled this code and used the exception decoder
with your posted serial output

Exception (9):
epc1=0x401058bc epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000003 depc=0x00000000

>>>stack>>>

ctx: sys
sp: 3fffea80 end: 3fffffb0 offset: 0150
3fffebd0:  40105aed 002d1c6b 3ffee72c 00000000  
3fffebe0:  3ffee190 3ffee72c 000000fa 40214034  
3fffebf0:  00000000 001544e7 40204da4 00001388  
3fffec00:  3ffee72c 0000118b 00001388 00001388Paste your stack trace here

this is what the exception-decoder is pointing to

Exception 9: LoadStoreAlignmentCause: Load or store to an unaligned address
PC: 0x401058bc
EXCVADDR: 0x00000003

Decoding stack results
0x40214034: sys_timeout_LWIP2 at core/timeouts.c line 304
0x40204da4: __esp_delay(unsigned long) at C:\Arduino-Pure-Portable\arduino-1.8.19\portable\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 155

exception (9) Load or store to an unaligned address

it is ery likely that your char-array dataBuffer is not valid
My first guessing is no zero-terminating at the end of the c_string

best regards Stefan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.