esp_now receiver stops receiving data

Hi everyone

I have a problem with an esp_now 2 way communication project. Basically the project works like this:

I have a 2 WeMos Lolin32 microprocessor boards.

On the first one a trigger system/button was built and on the second one an accelerometer was attached. What happens is the moment the trigger is pressed by someone a command is send from the the first ESP32 to the second ESP32 to start taking readings from the the accelerometer. The second accelerometer then takes readings from the accelerometer and stores the readings on the the inbuilt memory of the ESP32. The reason I store it on the ESP32 itself is because I take readings extremely fast, about every 1 ms. This is not a problem since I made sure that the accelerometer I use can sample at this rate. Also, I store the data in an array and only for a short amount of time. I made sure that ESP32 can handle that amount of storage. Now after all readings have been stored in the array, I send the readings back to the first ESP32. Now for some some reason the first ESP32 stops receiving data. I check the serial monitor of the second ESP32 and I get this message:

E (43576) wifi: esf_buf: t=3 l=52 max:32, alloc:32 no eb, TXQ_BLOCK=0
32
E (44576) wifi: esf_buf: t=3 l=52 max:32, alloc:32 no eb, TXQ_BLOCK=0
33
E (45576) wifi: esf_buf: t=3 l=52 max:32, alloc:32 no eb, TXQ_BLOCK=0
34
E (46576) wifi: esf_buf: t=3 l=52 max:32, alloc:32 no eb, TXQ_BLOCK=4000
35
E (47576) wifi: esf_buf: t=3 l=52 max:32, alloc:32 no eb, TXQ_BLOCK=0
36
E (48576) wifi: esf_buf: t=3 l=52 max:32, alloc:32 no eb, TXQ_BLOCK=0
37
E (49576) wifi: esf_buf: t=3 l=52 max:32, alloc:32 no eb, TXQ_BLOCK=0
38
E (50576) wifi: esf_buf: t=3 l=52 max:32, alloc:32 no eb, TXQ_BLOCK=0
39

It gives this message every time after 31 readings. I am not sure what it means or how to correct such a problem.

Included are both the codes for the first ESP32 and the second ESP32. Please help me.

Please note that the trigger system works the same as the button example that is one of the example in the Arduino pc program. All communications are through esp_now.

First ESP32 (trigger system);

#include <WiFi.h>

#include <esp_now.h>

const int led_pin=5;
const int button_pin=16;

bool trigger=true;

unsigned long receive_sampling_time;
int16_t receive_acceleration_x_axis;
int16_t receive_acceleration_y_axis;
int16_t receive_acceleration_z_axis;

int trigger_count=1;

typedef struct struct_message {
  unsigned long sampling_time;
  int16_t acceleration_x_axis;
  int16_t acceleration_y_axis;
  int16_t acceleration_z_axis;
} struct_message;

struct_message receive_readings;

uint8_t broadcastAddress[]={ 0x24, 0x6F, 0x28, 0x16, 0xD3, 0xB4};

void setup() {
  Serial.begin(115200);
 
  WiFi.mode(WIFI_STA);

  if (esp_now_init()!=ESP_OK) {
    Serial.println("Esp-now failed");
    return;
  } else {
    Serial.println("Esp-now initialized");
  }

  esp_now_register_recv_cb(OnDataRecv);
  
  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("Peer failed");
    return;
  } else {
    Serial.println("Peer initialized");
  }

  pinMode(led_pin,OUTPUT);
  digitalWrite(led_pin,HIGH);
  
  pinMode(button_pin,INPUT);
}

void loop() {
  if (digitalRead(button_pin)==LOW) {
    esp_err_t result=esp_now_send(broadcastAddress,(uint8_t *) &trigger,sizeof(trigger));

    digitalWrite(led_pin,LOW);
    
    Serial.print("Tigger: ");
    Serial.println(trigger_count);
    
    trigger_count+=1;

    delay(5000);
    digitalWrite(led_pin,HIGH);
  }
}

void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&receive_readings, incomingData, sizeof(receive_readings));
  
  receive_sampling_time=receive_readings.sampling_time;
  receive_acceleration_x_axis=receive_readings.acceleration_x_axis;
  receive_acceleration_y_axis=receive_readings.acceleration_y_axis;
  receive_acceleration_z_axis=receive_readings.acceleration_z_axis;

  Serial.print(receive_sampling_time);Serial.print(" ");
  Serial.print(receive_acceleration_x_axis);Serial.print(" ");
  Serial.print(receive_acceleration_y_axis);Serial.print(" ");
  Serial.println(receive_acceleration_z_axis);
}

Second ESP32 (accelerometer attached)

#include <SPI.h>
#include <WiFi.h>

#include <esp_now.h>

#include "SparkFun_LIS331.h"

const int led_pin=5;

bool trigger;
String array_state;

String send_test_value="Testing123";
String send_readings_status="Finished";

int16_t send_acceleration_x_axis;
int16_t send_acceleration_y_axis;
int16_t send_acceleration_z_axis;

unsigned long start_time=0;
unsigned long send_sampling_time=0;
unsigned long next_sampling_time=0;
unsigned long sampling_resolution=1000;

float accelerometer_data[4][50];

typedef struct struct_message {
  unsigned long sampling_time;
  int16_t acceleration_x_axis;
  int16_t acceleration_y_axis;
  int16_t acceleration_z_axis;
} struct_message;

struct_message send_readings;

LIS331 lis;

uint8_t broadcastAddress[]={0x24, 0x6F, 0x28, 0x16, 0xD8, 0x6C};

void setup() {
  Serial.begin(115200);
  
  WiFi.mode(WIFI_STA);

  if (esp_now_init()!=ESP_OK) {
    Serial.println("Esp-now failed");
    return;
  } else {
    Serial.println("Esp-now initialized");
  }

  esp_now_register_recv_cb(OnDataRecv);

  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("Peer failed");
    return;
  } else {
    Serial.println("Peer initialized");
  }
  
  pinMode(led_pin,OUTPUT);
  digitalWrite(led_pin,HIGH);

  pinMode(16,OUTPUT);
  pinMode(23,OUTPUT);
  pinMode(19,INPUT);
  pinMode(18,OUTPUT);

  SPI.begin();
  
  lis.setSPICSPin(16);
  lis.begin(LIS331::USE_SPI);
  
  lis.setPowerMode(LIS331::NORMAL);
  lis.setODR(LIS331::DR_1000HZ);
  lis.setFullScale(LIS331::LOW_RANGE);

  lis.readAxes(send_acceleration_x_axis,send_acceleration_y_axis,send_acceleration_z_axis);

  esp_err_t result=esp_now_send(broadcastAddress, (uint8_t *) &send_test_value,sizeof(send_test_value));

  if (result!=ESP_OK) {
    Serial.println("Sending failed");
    return;
  } else {
    Serial.println("Sending success");
  }
}

void loop() {
  
}

void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&trigger,incomingData,sizeof(trigger));
  
  if (trigger==1) {
    int index=0;
    start_time=micros();
    send_sampling_time=0;
    digitalWrite(led_pin,LOW);
    lis.readAxes(send_acceleration_x_axis,send_acceleration_y_axis,send_acceleration_z_axis);
    while (send_sampling_time<=49000) {
      accelerometer_data[0][index]=send_sampling_time;
      accelerometer_data[1][index]=send_acceleration_x_axis;
      accelerometer_data[2][index]=send_acceleration_y_axis;
      accelerometer_data[3][index]=send_acceleration_z_axis;
    
      index++;

      next_sampling_time=send_sampling_time+sampling_resolution;
      while(send_sampling_time<next_sampling_time) {
        send_sampling_time=micros()-start_time;
      }
      lis.readAxes(send_acceleration_x_axis,send_acceleration_y_axis,send_acceleration_z_axis);
    }
    trigger==0;
  }
    
  if (digitalRead(led_pin)==LOW) {
    for (int index=0;index<=49;index++) {
      send_readings.sampling_time=accelerometer_data[0][index];
      send_readings.acceleration_x_axis=accelerometer_data[1][index];
      send_readings.acceleration_y_axis=accelerometer_data[2][index];
      send_readings.acceleration_z_axis=accelerometer_data[3][index];
      esp_err_t result=esp_now_send(broadcastAddress, (uint8_t *) &send_readings, sizeof(send_readings));
      Serial.println(index);
      delay(1000);
    }
    digitalWrite(led_pin,HIGH);
  }
}

The ESP_NOW-protocol includes an inbuild handshaking. Inbuild means you don't have to take care of it it is happening "under the hood". You should write and then register the other call-back-function too.

It is the OnSent-function. You have to write code for the "OnSent"-function and then register it.
OnSent will deliver if the last sending was successful or did fail and you even can determine what was the reason for failing.

I guess you should wait for the OnSent-callback-function to be executed and evaluate if the sending was succesfull or not.
And only if it was successful going on sending the next message.

best regards Stefan