ESP-NOW(ESP8266), Slave is restarting while executing "Adafruit_SSD1306 " lines

Hi,

I am a newbie, working on a project to send a sensor data from Master to slave using two ESP8266 boards with ESP-NOW protocol. I succeeded in sending the data and displaying on serial monitor using the code shared by ESP- NOW protocol working - YouTube.

Now I am trying to include "Adafruit_SSD1306" 128x32 display to show the status of my master on slave device. Both master and slave codes are running fine without any errors, but while receiving the data on slave, the device is getting restarted and I found that the ESP8266 is restarting while executing the "SSD130" display command lines written in the function "SenderStatus()".

I could run the device by removing following lines (for example) from the function

if(atoi(value)==500)
{
Serial.println("Status 1 Ready");
/* display.clearDisplay (); // clear display
display.setCursor(10,13);
display.setTextSize(1);
display.setTextColor (WHITE);
display.print ("Status 1 Ready");
display.display ();//
delay(2000);
*/
}

And i tried to add the "SSD1306 allocation" commands again in the function just before "clear display" command, but no luck. How can I fix this to display the status on slave device using SSD1306.

Master:

#include <ESP8266WiFi.h>
#include<Wire.h>
extern "C" {
    #include <espnow.h>
}
// this is the MAC Address of the slave which receives the data
uint8_t mac[] = {0xDA, 0xBC, 0xC2, 0x11, 0x11, 0x11};
#define WIFI_CHANNEL 4


// must match the slave struct
struct __attribute__((packed)) 
DataStruct {
char text[15];
};

DataStruct Data;


//=======================================================================================

void setup() {
    Wire.begin(4,5);
    Serial.begin(115200);
    WiFi.mode(WIFI_STA); // Station mode for esp-now controller
    WiFi.disconnect();
    Serial.printf("This mac: %s, ", WiFi.macAddress().c_str());
    Serial.printf("slave mac: %02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    Serial.printf(", channel: %i\n", WIFI_CHANNEL);
    if (esp_now_init() != 0) 
    {
    Serial.println("*** ESP_Now initialization failed");
    }
    esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
    esp_now_add_peer(mac, ESP_NOW_ROLE_SLAVE, WIFI_CHANNEL, NULL, 0);
    strcpy(Data.text,"");
delay(2000);
 strcpy(Data.text,"500"); //status 1
 sendData();
delay(2000);
 strcpy(Data.text,"600"); //status 2
 sendData();
delay(2000); 
 strcpy(Data.text,"700"); //status 3
 sendData();
delay(2000); 
     strcpy(Data.text,"800"); //status 4
 sendData();
delay(2000); 

Serial.println("Setup finished");
}

//=======================================================================================

void loop() {
 ReadSensor();
    sendData();
}

//============================================================================================
void ReadSensor()
{
  char S_text[10];
  double sensor=380.21; // dummy sensor value
  dtostrf(sensor, 3, 2, S_text);
  strcpy(Data.text,S_text);
}

void sendData() 
   {
        uint8_t bs[sizeof(Data)];
        memcpy(bs, &Data, sizeof(Data));
        esp_now_send(NULL, bs, sizeof(Data));
        Serial.println(Data.text);
   }

Slave:

#include <ESP8266WiFi.h>

extern "C" {
    #include <espnow.h>
     #include <user_interface.h>
}
uint8_t mac[] = {0xDA, 0xBC, 0xC2, 0x11, 0x11, 0x11};

//==============Display=============
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET    -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void initVariant() {
  WiFi.mode(WIFI_AP);
  wifi_set_macaddr(SOFTAP_IF, &mac[0]);
}

//==============

#define WIFI_CHANNEL 4

// must match the controller struct
struct __attribute__((packed)) 
DataStruct {
    char text[15];
};

DataStruct myData;
int8_t flag=0;
//==================================================================================

void setup() {
    Serial.begin(115200); Serial.println();
    Serial.println("Starting....");
    Serial.print("AP mac: "); Serial.println(WiFi.softAPmacAddress());
    Serial.print("STA mac: "); Serial.println(WiFi.macAddress());

//display
  Wire.begin(4,5); 
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  
  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  delay(2000); // Pause for 2 seconds

   
  display.clearDisplay (); // clear display
  display.setCursor(20,13);
  display.setTextSize(1);
  display.setTextColor (WHITE);
  display.print ("Starting....");
  display.display ();//
  delay(2000);
  
 display.clearDisplay (); // clear display
 display.setCursor (12,8); // position the cursor
 display.setTextSize (2); // medium size font
 display.setTextColor (WHITE); // white is not default !
 display.print ("Hello");
  display.display ();//
  delay(2000);
  
  //ESP Initialize
    if (esp_now_init()!=0) {
        Serial.println("*** ESP_Now init failed");
        while(true) {};
    }

    esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
    esp_now_register_recv_cb(receiveCallBackFunction);
   Serial.println("End of setup - waiting for messages");
}

//=======================================================================================

void loop() {

}

//=======================================================================================

void receiveCallBackFunction(uint8_t *senderMac, uint8_t *incomingData, uint8_t len) {
    memcpy(&myData, incomingData, sizeof(myData));
   if(flag<=3)
    {
     SenderStatus();
    }
   Serial.println(myData.text);
}

void SenderStatus()
{
    
    char value[15];
    strcpy(value,myData.text);
    if(atoi(value)==500)
    {
      Serial.println("Status 1 Ready");
      display.clearDisplay (); // clear display  (restarting while executing these line)
      display.setCursor(10,13);
      display.setTextSize(1);
      display.setTextColor (WHITE);
      display.print ("Status 1 Ready");
      display.display ();//
      delay(2000);
    }
    else if(atoi(value)==600)
    {
      Serial.println("Status 2 Ready");
      display.clearDisplay (); // clear display
      display.setCursor(18,13);
      display.setTextSize(1);
      display.setTextColor (WHITE);
      display.print ("Status 2 Ready");
      display.display ();//
      delay(2000);
    }
    else if(atoi(value)==700)
    {   
      Serial.println("Status 3 Ready");
      display.clearDisplay (); // clear display
      display.setCursor(18,13);
      display.setTextSize(1);
      display.setTextColor (WHITE);
      display.print ("Status 3 Ready");
      display.display ();//
      delay(2000); 
    }
    else if(atoi(value)==800)
    {   
      Serial.println("Status 4 Ready"); 
      display.clearDisplay (); // clear display
      display.setCursor(18,13);
      display.setTextSize(1);
      display.setTextColor (WHITE);
      display.print ("Status 4 Ready");
      display.display ();//
      delay(2000);
  
      Serial.println("Receiving Data");
      display.clearDisplay (); // clear display
      display.setCursor(18,13);
      display.setTextSize(1);
      display.setTextColor (WHITE);
      display.print ("Receiving Data");
      display.display ();// 
    }
    flag++;
}

Could you please help me on this. Please

strcpy(value,myData.text)Are you certain myData.text is actually a string, with a terminator?

TheMemberFormerlyKnownAsAWOL:
strcpy(value,myData.text)Are you certain myData.text is actually a string, with a terminator?

Hi,

Which is a C-string with a null terminator. I have tried following check to print the actual values

char value[15];
int y=atoi(myData.text);
Serial.println(y);
strcpy(value,myData.text);
int x=atoi(value);
Serial.println(x);
if(x==500)
Serial.println("Status 1 Ready");

this gives x, y values same and printed "Status 1 Ready" as well when myData.text is "500".

I am having an issue, working out out with Adafruit, with a BME680 sensor and the library, fro Adafruit, throwing errors. You might try using an older version of the display driver to see if Adafruit has a working library or use another 1306 library like U8G2.

If you open an issue with Adafruit about their library giving faults, you should provide all the core dump and back trace info that you can, including info from the ESP Exception Decoder, [ur]https://github.com/me-no-dev/EspExceptionDecoder[/url]. Adafruit will dink around till they can reproduce the error and finally assign someone to fix the issue, this process takes about a month. Depending on how busy the programmer is, it should take about 3 or 4 months for Adafruit to resolve the library issue or you can use the U8G2 library.

Hi All,

Finally i resolved the issue, the problem was stack overflow (RAM) while printing on screen since "Adafruit" library uses more ram space, nearly 1 to 1.5KB while printing. My code has a CHAR array as global variable which uses more RAM while running the code and ESP8266 was restarting while trying to print on screen using "Adafruit" library. So I replaced it with a U8g2 library which uses very less RAM space and can clear the memory by "clearBuffer()" command.

Thank you all for your help :slight_smile: