Guru meditation error core 1 panic'ed

Hi Guys,
I am using ESP32, In this I am extracting data from BMS using CAN Bus (MCP2515 Module). data is printing on serial monitor accurately but after few minutes it shows "Guru Meditation Error" and stop reading data from my BMS.
Help me to resolve this error.
Thank You

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg;
// For ESP32 // 
//MCP2515 mcp2515(15);

//for alok sir hardware
MCP2515 mcp2515(5);

//For Arduino NANO // 
//MCP2515 mcp2515(10);

char aSDString[800] = { 0 };    /// File write buffer
unsigned long previousMillis = 0;
const long interval = 1500;


char incomingByte; // for incoming serial data
uint8_t factors[5] = {0,3,6,9,12};

uint8_t Load_status = 0;
bool Discharge_Switch = 0;
bool Charge_Switch  = 0;
uint16_t current = 0;
uint16_t voltage = 0;
uint16_t F_n_A = 0;
uint8_t Soh = 0;
uint8_t Soc = 0;
uint16_t Cycles = 0;

uint8_t No_of_thermistors = 4;
char Temp[4] = {0};

uint8_t No_of_cells = 0;
uint8_t Packet_No = 0;
uint16_t vCells_1_to_16[16] = {0}; //for C1 to c16 Voltage

uint8_t Balance_Config = 0;
uint32_t Balance_State = 0;

uint8_t Chemistry = 0;
uint16_t Capacity = 0;

uint8_t Year = 0;
uint8_t Month = 0;
uint8_t Date = 0;
uint8_t Hour = 0;
uint8_t Minute = 0;
uint8_t Second = 0;
uint8_t Sub_second = 0;
byte cell_loop = 0;

void EF_Update_Data();

union
{
  struct {
    bool bit7: 1;
    bool bit6: 1;
    bool bit5: 1;
    bool bit4: 1;
    bool bit3: 1;
    bool bit2: 1;
    bool bit1: 1;
    bool bit0: 1;
  } fields;
  uint8_t val;
} CMD;


void serialEvent() 
{
  int count = 0;
  while (Serial.available()) 
  {
    incomingByte = Serial.read();

    switch (incomingByte)
    {
      case 'D':  // DataFrame for IOT Device
        {
          Serial.println(aSDString);
         // aSDString[800] = 0;
          
          break;
        }
      default:
        {
          break;
        }
    }
  }
}

void setup() {
  Serial.begin(9600);
  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();
  Serial.println("Ready");
}

void loop()
{
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK)
  {
    Decode(canMsg.data, canMsg.can_dlc);
    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval)
    {
      previousMillis = currentMillis;
      EF_Update_Data(); // for storing all data into global variable aSDString
      Serial.println(aSDString);
      serialEvent();
    }
  }
}

void Decode(uint8_t Data[8], byte DLC) // decode function
{
    if (Data[0] == 0xFC)
    {
      CMD.val = Data[1];
      Load_status = ((CMD.fields.bit3 << 7) | (CMD.fields.bit4 << 6) | (CMD.fields.bit5 << 5));
      Discharge_Switch = CMD.fields.bit6;
      Charge_Switch  = CMD.fields.bit7;
      current = (Data[3] << 8) | Data[2];
      voltage = (Data[5] << 8) | Data[4];
      F_n_A = (Data[7] << 8) | Data[6];
    }

    if (Data[0] == 0x0E)
    {
      Soh = Data[1];
      Soc = Data[2];
      Cycles = (Data[7] << 8) | Data[6];
    }

    if (Data[0] == 0x06)
    {
      No_of_thermistors = DLC - 2;
      
      //Serial.println(DLC);
      
      for (int i = 0; i <= No_of_thermistors; i++)
      {
        Temp[i] = Data[i + 2];
      }
    }

     if (Data[0] == 0x0A)
    {
      Packet_No = Data[1];
      
      if (Packet_No == 0)
      {
        No_of_cells = Data[3];

      }

      // Pattern Not Happening thats why started from 1 //
      for(uint8_t packet=1; packet<=5; packet++) 
      {
          if (Packet_No == packet) // cell voltage
          {
            for (uint8_t i = 1; i < 4; i++)
            {
              vCells_1_to_16[i+factors[packet-1]] = (Data[i * 2 + 1] << 8) + Data[i * 2];
            }
          }
      }
     }

     if (Data[0] == 0x36)
     {
      Balance_Config = Data[2];
      Balance_State =  Data[6] << 24 | Data[5] << 16 | Data[4] << 8 | Data[3];
     }


     if (Data[0] == 0x14)
     {
      Chemistry = Data[1];
      Capacity = (Data[3] << 8) | Data[2];
      Capacity *= 100;
     }


     if (Data[0] == 0x70)
     {
      Year = (Data[2] >> 4) ;
      Month = (Data[2] << 4) ;
      Date = Data[3];
      Hour = Data[4];
      Minute = Data[5];
      Second = Data[6];
      Sub_second = Data[7]; 
     }
 }


void EF_Update_Data()
{
  int i, mx, mn, n;
  int count = 0;

  // Battery Data Identifier //
  count +=  sprintf((char*)aSDString + count, "#BDS,");  

  // Chemistry //
  count +=  sprintf((char*)aSDString + count, "%d,", Chemistry);  
  // Capacity //
  count +=  sprintf((char*)aSDString + count, "%d,", Capacity);  
  // No. of Cells //
  count +=  sprintf((char*)aSDString + count, "%d,", No_of_cells); 


  mx = vCells_1_to_16[1];
  mn = vCells_1_to_16[1];
  
  for (int i = 1; i < No_of_cells + 1; i++)
  { 
    // Cells Data //
    count +=  sprintf((char*)aSDString + count, "%d,",  vCells_1_to_16[i]);  

    if (vCells_1_to_16[i] > mx)
    {
      mx = vCells_1_to_16[i];
    }

    if (vCells_1_to_16[i] < mn)
    {
      mn = vCells_1_to_16[i];
    }
  }  


  // Temperature Identifier //
  count +=  sprintf((char*)aSDString + count, "#T,");  
  // Number of Temperature Sensor //
  count +=  sprintf((char*)aSDString + count, "%d,",No_of_thermistors);  
  for (int i = 0; i < No_of_thermistors; i++) 
  {
    // Data of Temperature Sensors //
    count +=  sprintf((char*)aSDString + count, "%d,", Temp[i]); 
  }

  // Load Status //
  count +=  sprintf((char*)aSDString + count, "%d,", Load_status); 
  // Discharge Switch //
  count +=  sprintf((char*)aSDString + count, "%d,", Discharge_Switch); 
  // Charge Switch //
  count +=  sprintf((char*)aSDString + count, "%d,", Charge_Switch ); 
  // Voltage //
  count +=  sprintf((char*)aSDString + count, "%d,", voltage); 
  // Current //
  count +=  sprintf((char*)aSDString + count, "%d,", current); 

  // Fault & Alert identifier //
  count +=  sprintf((char*)aSDString + count, "#F,"); 
  //Fallut and Alert //
  count +=  sprintf((char*)aSDString + count, "%d,", F_n_A); 
  // SOC //
  count +=  sprintf((char*)aSDString + count, "%d,", Soc);
  // SOH // 
  count +=  sprintf((char*)aSDString + count, "%d,", Soh); 
  // Cycles //
  count +=  sprintf((char*)aSDString + count, "%d,", Cycles); 
  // Balancing Config //
  count +=  sprintf((char*)aSDString + count, "%d,", Balance_Config);
  // Balancing State // 
  count +=  sprintf((char*)aSDString + count, "%d,", Balance_State); 
  // End Identifier //
  count +=  sprintf((char*)aSDString + count, "@BDE");

  //  count +=  sprintf((char*)aSDString + count, "%d,", Year);
  //  count +=  sprintf((char*)aSDString + count, "%d,", Month);
  //  count +=  sprintf((char*)aSDString + count, "%d,", Date);
  //  count +=  sprintf((char*)aSDString + count, "%d,", Hour);
  //  count +=  sprintf((char*)aSDString + count, "%d,", Minute);
  //  count +=  sprintf((char*)aSDString + count, "%d,", Second);
  //  count +=  sprintf((char*)aSDString + count, "%d@", Sub_second);
}

I would suspect array overflow
if is after a fixed time or number of transactions?
what happens if you change the size of array aSDString ?
add println() statements to see if you can determine where it is failing

Hi, @gauravkr
Did you Google;

Guru Meditation Error arduino

Tom... :smiley: :+1: :coffee: :australia:

On a side note ESP32 does support CAN already ie using a MCP2515 board to read just one CAN bus seems superfluous...

15:11:22.140 -> Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited). Exception was unhandled.
15:11:22.235 -> Core 1 register dump:
15:11:22.281 -> PC : 0x00810000 PS : 0x00060530 A0 : 0x800d2258 A1 : 0x3ffb1f50
15:11:22.374 -> A2 : 0x3ffc0264 A3 : 0x3ffbfec4 A4 : 0x000000ff A5 : 0x0000ff00
15:11:22.469 -> A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x800d2231 A9 : 0x3ffb1f40
15:11:22.562 -> A10 : 0x3ffc0264 A11 : 0x3ffbfec4 A12 : 0x000004c1 A13 : 0x0000ff00
15:11:22.656 -> A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x00000004 EXCCAUSE: 0x00000014
15:11:22.750 -> EXCVADDR: 0x00810000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xfffffecf
15:11:22.844 ->
15:11:22.844 -> ELF file SHA256: 0000000000000000
15:11:22.890 ->
15:11:22.890 -> Backtrace: 0x00810000:0x3ffb1f50 0x400d2255:0x3ffb1f70 0x400d10c4:0x3ffb1f90 0x400d26d1:0x3ffb1fb0 0x40086155:0x3ffb1fd0
15:11:23.031 ->
15:11:23.031 -> Rebooting...

Did you put the backtrace info into the ESP exception decoder?

I'd skip the MCP thingy and use transceivers instead. CAN support is built into a ESP32.

#include <CAN_config.h>
#include <ESP32CAN.h>
// http://www.iotsharing.com/2017/09/how-to-use-arduino-esp32-can-interface.html

CAN_device_t CAN_cfg;
// CAN_frame_t rx_frame;
// http://www.iotsharing.com/2017/09/how-to-use-arduino-esp32-can-interface.html
// https://github.com/nhatuan84/arduino-esp32-can-demo

void setup()
{
  CAN_cfg.speed = CAN_SPEED_1000KBPS;
  CAN_cfg.tx_pin_id = GPIO_NUM_12; // green wire
  CAN_cfg.rx_pin_id =  GPIO_NUM_13; // white wire
  CAN_cfg.rx_queue = xQueueCreate(3, sizeof(CAN_frame_t));
  //start CAN Module
  ESP32Can.CANInit();
}


void fSendCAN_Buss( void *pvParameters )
{
  stuSERVO_Message pxServo_Message;
  for ( ;; )
  {
    xEventGroupWaitBits (eg, evtSendCAN_Buss, pdTRUE, pdTRUE, portMAX_DELAY);
    if ( xSemaphoreTake( sema__Send_CAN_Bus, xTicksToWait0 ) == pdTRUE ) // grab semaphore no wait
    {
      CAN_frame_t rx_frame;
      // Serial.println ( " fSendCAN_Buss 2 "  );
      if ( (CAN_cfg.rx_queue != NULL) && (uxQueueMessagesWaiting(CAN_cfg.rx_queue)) ) // if queue not null and something is waiting in queue
      {
        // Serial.println ( uxQueueMessagesWaiting(CAN_cfg.rx_queue) );
        if (xQueueReceive( CAN_cfg.rx_queue, &rx_frame , xTicksToWait0) == pdTRUE )
        {
          if ( rx_frame.MsgID == 2 )
          {
            // Serial.println ( rx_frame.data.u8[0] );
            if ( rx_frame.data.u8[0] == '6' )
            {
              EOT = false;
              // Serial.print ( " frame ID " );
              // Serial.print ( rx_frame.MsgID );
              // Serial.println ( "ACK" );
              //              rx_frame.FIR.B.FF = CAN_frame_std;
              //              rx_frame.MsgID = xServo_EOT.MsgID;
              //              rx_frame.FIR.B.DLC = xServo_EOT.DLC;
              //              rx_frame.data.u8[0] = xServo_EOT.Servo_EOT;
              //              rx_frame.data.u8[1] = xServo_EOT.p4; // send all '0'
              //              rx_frame.data.u8[2] = xServo_EOT.p4;
              //              rx_frame.data.u8[3] = xServo_EOT.p4;
              //              rx_frame.data.u8[4] = xServo_EOT.p4;
              //              rx_frame.data.u8[5] = xServo_EOT.p4;
              //              rx_frame.data.u8[6] = xServo_EOT.p4;
              //              rx_frame.data.u8[7] = xServo_EOT.p4;
              //              ESP32Can.CANWriteFrame(&rx_frame);
              // Serial.println ( " sent Servo controller ack " );
              //              vTaskDelay( pdMS_TO_TICKS( 6 ) );
            }
            //            if (rx_frame.data.u8[0] = '3')
            //              {
            //                EOT = false;
            //              }
            if ( rx_frame.data.u8[0] == '4' )
            {
              //                          rx_frame.FIR.B.FF = CAN_frame_std;
              //                          rx_frame.MsgID = xServo_EOT.MsgID;
              //                          rx_frame.FIR.B.DLC = xServo_EOT.DLC;
              //                          rx_frame.data.u8[0] = '4';
              //                          rx_frame.data.u8[1] = xServo_EOT.p4;
              //                          rx_frame.data.u8[2] = xServo_EOT.p4;
              //                          rx_frame.data.u8[3] = xServo_EOT.p4;
              //                          rx_frame.data.u8[4] = xServo_EOT.p4;
              //                          rx_frame.data.u8[5] = xServo_EOT.p4;
              //                          rx_frame.data.u8[6] = xServo_EOT.p4;
              //                          rx_frame.data.u8[7] = xServo_EOT.p4;
              //                          ESP32Can.CANWriteFrame(&rx_frame);
              // Serial.println ( "InitComplete ack " );
              EOT = false;
              xSemaphoreGive ( sema_HexaPodAdjustment ); // begin walking forward task
            }
          } // if ( rx_frame.MsgID == 2 )
        } // if (xQueueReceive( CAN_cfg.rx_queue, &rx_frame , xTicksToWait5) == pdTRUE )
      } // if ( (CAN_cfg.rx_queue != NULL) && (uxQueueMessagesWaiting(CAN_cfg.rx_queue)) )
      //      // ack the initialization
      if ( xQueueReceive ( xQ_SERVO_Message, &pxServo_Message, QueueReceiveDelayTime ) == pdTRUE )
      {
        rx_frame.FIR.B.FF = CAN_frame_std;
        rx_frame.MsgID = pxServo_Message.MsgID;
        rx_frame.FIR.B.DLC = pxServo_Message.DLC;
        rx_frame.data.u8[0] = pxServo_Message.Instruction;
        rx_frame.data.u8[1] = pxServo_Message.p1;
        rx_frame.data.u8[2] = pxServo_Message.p2;
        rx_frame.data.u8[3] = pxServo_Message.p3;
        rx_frame.data.u8[4] = pxServo_Message.p4; // end of torque to position
        rx_frame.data.u8[5] = pxServo_Message.p5;
        rx_frame.data.u8[6] = pxServo_Message.p6;
        rx_frame.data.u8[7] = pxServo_Message.p7;
        //                Serial.print ( " message in sendCanBus " );
        //                Serial.print ( ", " );
        //                Serial.print ( rx_frame.data.u8[0] );
        //                Serial.print ( ", " );
        //                Serial.print ( rx_frame.data.u8[1] );
        //                Serial.print ( ", " );
        //                Serial.print (rx_frame.data.u8[2] );
        //                Serial.print ( ", " );
        //                Serial.print ( rx_frame.data.u8[3] );
        //                Serial.print ( ", " );
        //                Serial.print ( rx_frame.data.u8[4] );
        //                Serial.println ( " message end." );
        ESP32Can.CANWriteFrame(&rx_frame);
      }
      //
      xSemaphoreGive ( sema__Send_CAN_Bus );
      ////
      // Serial.print( "fSendCAN_Buss " );
      // Serial.print(uxTaskGetStackHighWaterMark( NULL ));
      // Serial.println();
      // Serial.flush();
    }  // if ( xSemaphoreTake( sema__Send_CAN_Bus, xTicksToWait0 ) == pdTRUE ) // grab semaphore no wait
  } // the for loop
  vTaskDelete( NULL );
} // void fSendCAN_Buss( void *pvParameters )

Is a code snippet of my use of ESP32 CAN,

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