espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.61k stars 7.41k forks source link

Guru Meditation Error: Core 0 panic'ed (Load access fault). Exception was unhandled. (W/ ESP32-C3) #8527

Closed abhi-sachdeva closed 1 year ago

abhi-sachdeva commented 1 year ago

Board

ESP32-C3-DevKit-M1

Device Description

The dev kit is on a breadboard with 2 push buttons connected to pins 2 & 3. The breadboard also has a green, red, and blue led connected to pins 5, 6, & 7 respectively. The button attached to pin 3 is used to control the red and green led and wake up the esp32-c3 from deep sleep. The other button attached to pin 2 is used to initiate ble server and advertise itself. While this process is being undergone, a blue led illuminates. The blue led turns off after a successful connection has established (which also puts the esp32-c3 into deep sleep).

Hardware Configuration

Resistors in series with the leds (220ohm) and a pull down resistor for both buttons (10kohm)

Version

latest master (checkout manually)

IDE Name

Arduino IDE

Operating System

Windows 10

Flash frequency

80Mhz

PSRAM enabled

yes

Upload speed

921600

Description

Getting an error as follows: Guru Meditation Error: Core 0 panic'ed (Load access fault). Exception was unhandled.

The reason this occured is because I tried to implement a function: void pairing() This function simply uses a button to: if HIGH --> Blue LED turns on and starts BLE code if LOW --> Blue LED stays off and no BLE code is ran The function utilizes a variable called buttonState2 and sets it = digitalRead(buttonPin2);

The expected behavior is that pressing the button would turn on the LED and start scanning and connection via BLE. Once connected, I implemented a callback such that the LED turns off once a successful connection has been made and the esp32-c3 goes to deep sleep. The callback has been created, not implemented yet as I am trying to fix the issue with the button first.

Sketch

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <Wire.h>

const int buttonPin = 3;  // # for button pin for States
const int buttonPin2 = 2; // # for button pin for BLE
const int ledPin =  5;   // # for the Green LED pin
const int ledPin2 = 6;   // # for the Red LED pin
const int ledPin3 = 7;    // # for the Blue LED pin

// variables will change:
int buttonState = 0;     
int lastButtonState = 0;
int buttonState2 = 0;
int lastButtonState2 = 0;  
int ledState = 0;
RTC_DATA_ATTR int counter = 0; 

#define SERVICE_UUID        "f0e279fc-a979-4ffd-924c-59ced5392948"
#define CHARACTERISTIC_UUID "7f98738e-382d-43d9-b256-3cf8bd3120b7"

BLEServer *pServer;
BLEService *pService;
BLECharacteristic *pCharacteristic;

bool deviceConnected = false;

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      digitalWrite(ledPin3, LOW);  // Turn off LED
      esp_deep_sleep_start();  // Enter deep sleep mode
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("Disconnected!");
      Serial.println("Advertising...");
      pServer->startAdvertising();
    }
};

class MyCallbacks: public BLECharacteristicCallbacks
{
  void onWrite(BLECharacteristic *pCharacteristic)
  {
    std::string value = pCharacteristic->getValue();

    if (value.length() > 0)
    {
      Serial.println("*********");
      Serial.print("New value: ");
      for (int i = 0; i < value.length(); i++)
      {
        Serial.print(value[i]);
      }

      Serial.println();
      Serial.println("*********");
    }
  }
};

void setupBLEServer(void) {

  Serial.println("Starting BLE Server!");
  BLEDevice::init("Pirouette-IoT-Device");
  pServer = BLEDevice::createServer();

  pService = pServer->createService(SERVICE_UUID);

  pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic->setCallbacks(new MyCallbacks());

  pCharacteristic->setValue("device_state_0_stored");
  pService->start();
  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void pairing(){
  buttonState2 = digitalRead(buttonPin2);
  if(buttonState2 == HIGH){
    digitalWrite(ledPin3, HIGH);
    setupBLEServer();
  }
  else {
    digitalWrite(ledPin3, LOW);
  }
}

void setup() {
  Serial.begin(115200);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT_PULLUP);

  //BLE Server Setup with button2
  //setupBLEServer();
  pairing();
}

void loop(){

  // read the state of the BLE pushbutton
  buttonState2 = digitalRead(buttonPin2);
  if (lastButtonState2 == HIGH && buttonState2 == LOW) {
    Serial.println("The button is pressed");
    digitalWrite(ledPin3, HIGH);

    pCharacteristic->setValue("device_state_1_ready"); //add code for device 1 state ready once buttonPin1 is pushed/released
    pCharacteristic->notify();

  } else if (lastButtonState2 == LOW && buttonState2 == HIGH) {
    Serial.println("The button is released");
    digitalWrite(ledPin3, LOW);
  }

  lastButtonState2 = buttonState2;

  // read the state of the internal pushbutton:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      counter++;
      Serial.print("Number of button pushes:  ");
      Serial.println(counter);
      // if the current state is HIGH then the button went from off to on:
      ledState = !ledState;
    }
    if(counter == 2){
        buttonState = lastButtonState;
    }
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // sets the LED to the button's state
  if(counter == 1){
    digitalWrite(ledPin, ledState);
  }

  if(counter == 3){
    digitalWrite(ledPin2, HIGH);
    digitalWrite(ledPin, LOW);
  }
  else if (counter >= 4){
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin2, LOW);
  }

  delay(50);
  }

Debug Message

3fca08d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fca08f0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xbaad5678 0x00000160 0xabba1234 0x00000154
3fca0910: 0x3fca07f0 0x00002533 0x3fc9481c 0x3fc9481c 0x3fca0910 0x3fc94814 0x00000018 0x81ee58d9
3fca0930: 0x86e97086 0x3fca0910 0x00000000 0x00000001 0x3fc9e900 0x706f6f6c 0x6b736154 0x7d87c100
3fca0950: 0x002725d8 0x00000000 0x3fca08f0 0x00000001 0x00000000 0x00000000 0x00000000 0x00000000
3fca0970: 0x3fc9a854 0x3fc9a8bc 0x3fc9a924 0x00000000 0x00000000 0x00000001 0x00000000 0x00000000
3fca0990: 0x00000000 0x4209e118 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca09b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca09d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca09f0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca0a10: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca0a30: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca0a50: 0x00000000 0x00000000 0x00000000 0x00000000 0xea000000 0xbaad5678 0x00000060 0xabba1234
3fca0a70: 0x00000054 0x00000000 0x3fca0a74 0x00000000 0x00000000 0x00000000 0x3fca0a8c 0xffffffff
3fca0a90: 0x3fca0a8c 0x3fca0a8c 0x00000000 0x3fca0aa0 0xffffffff 0x3fca0aa0 0x3fca0aa0 0x00000001
3fca0ab0: 0x00000001 0x00000000 0x6d00ffff 0x00000000 0xb33fffff 0x00000000 0xbaad5678 0x00000110
3fca0ad0: 0xabba1234 0x00000104 0x00000000 0x00000014 0x3fca1178 0x00000000 0x00000000 0x00000000
3fca0af0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca0b10: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca0b30: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca0b50: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca0b70: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000101 0x00000000
3fca0b90: 0x00000000 0x0000000a 0x3fca1140 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fca0bb0: 0x00000000 0x00000000 0x00000000 0x3fca0bec 0x3fca0d40 0x00000000 0x3fca0fb0 0x3fca0f4c
3fca0bd0: 0x3fca10dc 0x3fca1078 0x3fca1014 0xbaad5678 0x00000150 0xabba1234 0x00000144 0x3fca0c40
3fca0bf0: 0x3fca0c40 0x3fca0d30 0x3fca0d24 0x00000000 0x3fca0c04 0xffffffff 0x3fca0c04 0x3fca0c04
3fca0c10: 0x00000000 0x3fca0c18 0xffffffff 0x3fca0c18 0x3fca0c18 0x00000000 0x00000014 0x0000000c

ELF file SHA256: d9c97c912b1f8644

Rebooting...
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xc (SPI_FAST_FLASH_BOOT)
Saved PC:0x4038200a
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x438
load:0x403cc710,len:0x918
load:0x403ce710,len:0x25f4
entry 0x403cc710

Other Steps to Reproduce

I tried using/initializing a different variable in the void pairing() function and that did not fix the issue as well. My understanding of this is that the variable is in an invalid memory location/cant be read.

I have checked existing issues, online documentation and the Troubleshooting Guide

SuGlider commented 1 year ago

@abhi-sachdeva - Load Access Fault usually happens when trying to read content of a NULL pointer. https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/fatal-errors.html#instruction-access-fault-load-access-fault-store-access-fault

SuGlider commented 1 year ago

It seems that BLE is not initiated and loop() is running in parallel. I suggest to only use pCharacteristic-> if it is not NULL, like in this:


// ======>>>> Always initialize pointer with NULL
BLEServer *pServer = NULL;
BLEService *pService = NULL;
BLECharacteristic *pCharacteristic = NULL;

void loop(){

  // read the state of the BLE pushbutton
  buttonState2 = digitalRead(buttonPin2);
  if (lastButtonState2 == HIGH && buttonState2 == LOW) {
    Serial.println("The button is pressed");
    digitalWrite(ledPin3, HIGH);

    // =======>>>> Make sure the pointer is not NULL before using it
    if (pCharacteristic != NULL) {
      pCharacteristic->setValue("device_state_1_ready"); //add code for device 1 state ready once buttonPin1 is pushed/released
      pCharacteristic->notify();
    }
    // =======>>>> Make sure the pointer is not NULL before using it

  } else if (lastButtonState2 == LOW && buttonState2 == HIGH) {
    Serial.println("The button is released");
    digitalWrite(ledPin3, LOW);
  }

  lastButtonState2 = buttonState2;
 // ... rest of the loop() code ...
abhi-sachdeva commented 1 year ago

It seems that BLE is not initiated and loop() is running in parallel. I suggest to only use pCharacteristic-> if it is not NULL, like in this:

// ======>>>> Always initialize pointer with NULL
BLEServer *pServer = NULL;
BLEService *pService = NULL;
BLECharacteristic *pCharacteristic = NULL;

void loop(){

  // read the state of the BLE pushbutton
  buttonState2 = digitalRead(buttonPin2);
  if (lastButtonState2 == HIGH && buttonState2 == LOW) {
    Serial.println("The button is pressed");
    digitalWrite(ledPin3, HIGH);

    // =======>>>> Make sure the pointer is not NULL before using it
    if (pCharacteristic != NULL) {
      pCharacteristic->setValue("device_state_1_ready"); //add code for device 1 state ready once buttonPin1 is pushed/released
      pCharacteristic->notify();
    }
    // =======>>>> Make sure the pointer is not NULL before using it

  } else if (lastButtonState2 == LOW && buttonState2 == HIGH) {
    Serial.println("The button is released");
    digitalWrite(ledPin3, LOW);
  }

  lastButtonState2 = buttonState2;
 // ... rest of the loop() code ...

Thank you! It works great and as expected!