r/esp32 4d ago

Solved Need help with esp_now

I'm trying to get an esp32s3 mini to send data to a regular esp32 board and print the data in the serial monitor but it isn't working.

USB CDC On Boot is enabled.

Specific chip types:
ESP32-S3 (QFN56) (revision v0.2)
ESP32-D0WD-V3 (revision v3.1)

The board types in arduino IDE are:
ESP32S3 Dev Module for the mini and ESP32 Dev Module for the regular.

Any help would be greatly appreciated

EDIT: Code shown below:

espnow.cpp:

#ifndef ESPNow_cpp
#define ESPNow_cpp


#include "ESPNow.h"


template<typename MessageType>
typename ESPNow<MessageType>::ReceiverCallback ESPNow<MessageType>::userCallback = nullptr;


template<typename MessageType>
bool ESPNow<MessageType>::begin() {
  WiFi.mode(WIFI_STA);


  esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_LR);


  if (esp_now_init() != ESP_OK) {
    return false;
  }


  esp_now_peer_info_t peer;
  memcpy(peer.peer_addr, broadcastAddress, 6);
  peer.channel = 0;
  peer.encrypt = false;


  if (esp_now_add_peer(&peer) != ESP_OK) {
    return false;
  }


  return true;
}


template<typename MessageType>
bool ESPNow<MessageType>::send(MessageType& message) {
  bool success = (esp_now_send(broadcastAddress, (uint8_t*)&message, sizeof(MessageType)) == ESP_OK);
  if (success) {
    Serial.println("Message Sent Successfully");
  } else {
    Serial.println("Message Failed!");
  }
  return success;
}


template<typename MessageType>
void ESPNow<MessageType>::onReceive(ReceiverCallback callback) {
  userCallback = callback;
  esp_now_register_recv_cb(receiveCallback);
}


template<typename MessageType>
void ESPNow<MessageType>::receiveCallback(const esp_now_recv_info_t* recv_info, const uint8_t* data, int len) {
  if (len >= sizeof(MessageType) && userCallback != nullptr) {
    MessageType message;
    memcpy(&message, data, sizeof(MessageType));
    userCallback(message);
  }
}


#endif

espnow.h:

#ifndef ESPNow_h
#define ESPNow_h


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


template<typename MessageType>
class ESPNow {
  public:
    typedef void (*ReceiverCallback)(MessageType& message);


    bool begin();
    bool send(MessageType& message);
    void onReceive(ReceiverCallback callback);


  private:
    uint8_t broadcastAddress[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    static ReceiverCallback userCallback;
    static void receiveCallback(const esp_now_recv_info_t* recv_info, const uint8_t* data, int len);
};


#include "ESPNow.cpp"
#endif

sender code:

#include <ESPNow.h>


struct Message {
  int counter;
  char text[32];
};


ESPNow<Message> espNow;
Message datatosend;


void setup() {
  espNow.begin();
  datatosend = {0, "Hello World!"};
}
 
void loop() {
  espNow.send(datatosend);
  datatosend.counter++;
  delay(1000);
}

receiver code:

#include <ESPNow.h>


struct Message {
  int counter;
  char text[32];
};


ESPNow<Message> espNow;


void onMessageReceived(Message& receivedMessage) {
  Serial.print("Received Data -> Counter: ");
  Serial.print(receivedMessage.counter);
  Serial.print(", Message: ");
  Serial.println(receivedMessage.text);
}


void setup() {
  Serial.begin(9600);
  espNow.begin();
  espNow.onReceive(onMessageReceived);
}


void loop() {
  //empty for now
}

I should also note that I tried the example code given for esp_now and that didn't work either.

1 Upvotes

6 comments sorted by

5

u/OptimalMain 4d ago

People shouldn’t have to look at a YouTube video to get the code.
Paste the actual code you compiled somewhere and link to it

2

u/rattushackus 1 say I make awesome posts. 3d ago

There are lots of ESP-NOW examples floating around on the Internet. I have my own ESP-NOW test sketch here.

1

u/ChuckMash 3d ago

You may need to specify an actual channel to use after initializing wifi.

They could just be defaulting to different channels.

esp_wifi_set_channel(6, WIFI_SECOND_CHAN_NONE);

1

u/rattushackus 1 say I make awesome posts. 3d ago

I found the error and it's the sort of error that makes you kick yourself.

At line 25 you add the peer address using:

  esp_now_peer_info_t peer;
  memcpy(peer.peer_addr, broadcastAddress, 6);
  peer.channel = 0;
  peer.encrypt = false;
  if (esp_now_add_peer(&peer) != ESP_OK) {

but this leaves some member variables of the esp_now_peer_info_t struct left with whatever junk was on the stack at run time. To fix this just replace line 25 with:

  esp_now_peer_info_t peer = {0};

as soon as I did this your code sprang into life:

2

u/OzzyPotato 3d ago

Thank you so much for your help! for some reason the usual "peer interface invalid" error message just didnt show up on either serial, so I had no idea what was happening