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);
}