Problems with ESP32 NOW

Hi, Im trying to host a server with an esp32, in this server I will show gps data (latitude and longitude) thats obtained from another esp32 thats connected to the gps.

The way I want to communicate these 2 esp32 is through ESP NOW but im having trouble both hosting the server and sending the data, I managed to host the server once with my house wi fi but it hasnt worked since, i also have made it host with my phone hot spot, but the gps data never reaches the other esp, it has said sometimes that data tranfers was a success but that never happened when the server was up

Heres the code for the transmitter

////////TRANSMISOR


#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include <TinyGPS++.h>

// Define the RX and TX pins for Serial 2 (for GPS module)
#define RXD2 16
#define TXD2 17

#define GPS_BAUD 9600

// MAC Address of the receiver
uint8_t broadcastAddress[] = {0x08, 0xd1, 0xf9, 0xee, 0x5e, 0xc0};

// Structure to send data
typedef struct struct_message {
  float latitude;
  float longitude;
} struct_message;

struct_message gpsData;

// Create a TinyGPS++ object
TinyGPSPlus gps;

// Create an instance of the HardwareSerial class for Serial 2 (GPS communication)
HardwareSerial gpsSerial(2);

// ESP-NOW callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("Last Packet Send Status: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
}

void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);

  // Initialize Serial 2 for GPS communication
  gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
  Serial.println("GPS module initialized.");

  // Set ESP32 as Wi-Fi Station
  WiFi.mode(WIFI_STA);

  esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);  // Usa el canal 1

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

  // Register the send callback
  esp_now_register_send_cb(OnDataSent);

  // Add receiver's MAC Address as a peer
  esp_now_peer_info_t peerInfo;
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;

  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }

  Serial.println("ESP-NOW initialized, ready to send GPS data.");
}

void loop() {
  // Read GPS data from the module
  while (gpsSerial.available() > 0) {
    gps.encode(gpsSerial.read());
  }

  // If GPS location is updated, send the data via ESP-NOW
  if (gps.location.isUpdated()) {
    gpsData.latitude = gps.location.lat();
    gpsData.longitude = gps.location.lng();

    Serial.print("Sending LAT: ");
    Serial.print(gpsData.latitude, 6);
    Serial.print(" LONG: ");
    Serial.println(gpsData.longitude, 6);

    // Send the GPS data via ESP-NOW
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &gpsData, sizeof(gpsData));

    if (result == ESP_OK) {
      Serial.println("Sent with success");
    } else {
      Serial.println("Error sending the data");
    }
  }

  delay(2000); // Delay before sending the next packet
}

This is what the serial monitor says

17:04:04.574 -> Sent with success
17:04:04.705 -> Last Packet Send Status: Fail
17:04:06.577 -> Sending LAT: latitude LONG: longitude
17:04:06.577 -> Sent with success
17:04:06.577 -> Last Packet Send Status: Fail
17:04:08.588 -> Sending LAT: latitude LONG: longitude

And the receiver code

////RECEPTOR
#include <esp_now.h>
#include <WiFi.h>
#include <WebServer.h>
#include <esp_wifi.h>

// Set up a web server on port 80
WebServer server(80);

// Structure to receive data
typedef struct struct_message {
  float latitude;
  float longitude;
} struct_message;

// Create a struct_message instance to hold the received data
struct_message receivedData;

// Wi-Fi credentials (replace with your network details)
const char* ssid = "name 2.4GHz";
const char* password = "password";

// Callback when data is received
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
  memcpy(&receivedData, incomingData, sizeof(receivedData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("Latitude: ");
  Serial.println(receivedData.latitude, 6);
  Serial.print("Longitude: ");
  Serial.println(receivedData.longitude, 6);
}

// Web server handler for root page
void handleRoot() {
  String page = "<html><body>";
  page += "<h1>ESP32 GPS Data</h1>";
  page += "<p><strong>Latitude:</strong> " + String(receivedData.latitude, 6) + "</p>";
  page += "<p><strong>Longitude:</strong> " + String(receivedData.longitude, 6) + "</p>";
  page += "</body></html>";
  server.send(200, "text/html", page);
}

void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);

  // Connect to Wi-Fi network
  WiFi.begin(ssid, password);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("Wi-Fi connected.");
  Serial.print("ESP32 IP Address: ");
  Serial.println(WiFi.localIP());  // This will print the IP address

  // Set the ESP32 as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);  // Usa el canal 1


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

  // Register the callback function to receive data
  esp_now_register_recv_cb(OnDataRecv);

  // Start the web server
  server.on("/", handleRoot);
  server.begin();
  Serial.println("Web server started.");
}

void loop() {
  // Handle incoming web requests
  server.handleClient();
}

Heres a photo of the components if it helps

I have tried to see if I can get the connection working without implementing the gps, it didnt work either
Heres the code i tried

///transmitter
/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-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 <esp_now.h>
#include <WiFi.h>

// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xC8, 0xF0, 0x9E, 0x53, 0x05, 0xF8};

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

// Create a struct_message called myData
struct_message myData;

esp_now_peer_info_t peerInfo;

// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("\r\nLast Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "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() != ESP_OK) {
    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_register_send_cb(OnDataSent);
  
  // Register peer
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;
  
  // Add peer        
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
}
 
void loop() {
  // Set values to send
  strcpy(myData.a, "THIS IS A CHAR");
  myData.b = random(1,20);
  myData.c = 1.2;
  myData.d = false;
  
  // Send message via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
   
  if (result == ESP_OK) {
    Serial.println("Sent with success");
  }
  else {
    Serial.println("Error sending the data");
  }
  delay(2000);
}
///receiver
/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-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 <esp_now.h>
#include <WiFi.h>

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

// Create a struct_message called myData
struct_message myData;

// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int 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("Bool: ");
  Serial.println(myData.d);
  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() != ESP_OK) {
    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_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}
 
void loop() {

}
18:26:12.293 -> Last Packet Send Status:	Delivery Fail
18:26:14.275 -> Sent with success
18:26:14.316 -> 
18:26:14.316 -> Last Packet Send Status:	Delivery Fail
18:26:16.260 -> Sent with success
18:26:16.298 -> 
18:26:16.298 -> Last Packet Send Status:	Delivery Fail

The receiver serial monitor was empty

That code comes from the randomnerds and I am 99% sue it works. What board are you using?
Why are there such large time gaps? Almost 2 secs between the first two. OOPS Now I see. Remove that delay.

The code is a combination of 2 of their codes to be more specific (ESP32: ESP-NOW and Wi-Fi Web Server Dashboard (Arduino) | Random Nerd Tutorials and ESP32 with NEO-6M GPS Module (Arduino) | Random Nerd Tutorials), the boards I'm using are a Nodemcu Esp32 Wifi + Bluetooth 4.2 Iot Wroom Esp32s, I'll remove the delay.

One differtence I see is the nerds use a bcast address of al 1's, you have a specific address.
Try the nerds EXACT code.

Sorry, I looked at the basic nerds broadcast. Your code is quite similar except it's not broadcast.
I went back to your OP, why 2 esp32's? just build an esp32 web server and add a couple lines to read a GPS.
3 lines of code for setup, 5 for loop including a delay and a couple prints.

Best to start with examples that are well tested and known to work, and verify proper operation of all the parts, before making any changes.

The second stripped-down example worked for me. ESP-Now requires that everyone is on the same WiFi channel. If you restart, it should revert to channel 1, but you can double-check.

Everyone joining the same WiFi access point is a good way to get them on the same channel without hard-coding that channel. But then for ESP-Now to work reliably, you have to disconnect from the AP. In my test just now, I added to your code

  • sender hard-coded esp_wifi_set_channel(4, WIFI_SECOND_CHAN_NONE)
  • receiver WiFi.begin to AP on channel 4
  • but no disconnect

the OnDataSent reports ESP_NOW_SEND_SUCCESS less than 1 in 3. So you're not going to run a server there either.

If you're going to run a web server on the receiver, and the sender(s) know the IP, you can of course use HTTP to POST data.

To pursue ESP-Now further, try hard-coding some other channel with no/light usage wherever you are.

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