Hi.
in my program, I created two tasks, one timer . a flag (sampling_permission) which is set in the ISR of the timer is used in one of my task (ADXL_Handler). after printing the data-set for the second time, the ESP32 crashes. I have no Idea what is the reason.
if the flag is not used inside my task which is ADXL handler, everything is fine and ESP does not crash. the program will run without problem.
Here is the error after crashing :
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
Core 1 register dump:
PC : 0x4008a394 PS : 0x00060d35 A0 : 0x800895e6 A1 : 0x3ffbed7c
A2 : 0x3ffb8a00 A3 : 0x3ffb8890 A4 : 0x00000004 A5 : 0x00060d23
A6 : 0x00060d23 A7 : 0x00000001 A8 : 0x3ffb8890 A9 : 0x00000018
A10 : 0x3ffb8890 A11 : 0x00000018 A12 : 0x00000004 A13 : 0x00060d23
A14 : 0x007beed8 A15 : 0x003fffff SAR : 0x0000001f EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400860d5 LEND : 0x400860e5 LCOUNT : 0xffffffee
Core 1 was running in ISR context:
EPC1 : 0x400db09f EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x00000000
Backtrace:0x4008a391:0x3ffbed7c |<-CORRUPTED
Core 0 register dump:
PC : 0x4008a50b PS : 0x00060035 A0 : 0x8008920f A1 : 0x3ffbe82c
A2 : 0x3ffbeed8 A3 : 0xb33fffff A4 : 0x0000abab A5 : 0x00060023
A6 : 0x00060021 A7 : 0x0000cdcd A8 : 0x0000abab A9 : 0xffffffff
A10 : 0x00000000 A11 : 0x00000000 A12 : 0x3ffc1ef8 A13 : 0x00000007
A14 : 0x007beed8 A15 : 0x003fffff SAR : 0x0000001a EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Backtrace:0x4008a508:0x3ffbe82c |<-CORRUPTED
ELF file SHA256: 0000000000000000
Rebooting...
Here is the code:
#include <Arduino.h>
#include <SPI.h>
#if CONFIG_FREERTOS_UNICORE
static const BaseType_t app_cpu = 0;
#else
static const BaseType_t app_cpu = 1;
#endif
#define HSPI_MISO 12
#define HSPI_MOSI 13
#define HSPI_SCLK 14
#define HSPI_SS 15
//function protopypes
bool SPI_Write_Reg(uint8_t register_addr, uint8_t register_value);
uint8_t SPI_Read_Reg(uint8_t Reg_Addr);
float Read_X_Axis(int8_t *xdata);
float Read_Y_Axis(int8_t *ydata);
float Read_Z_Axis(int8_t* zdata);
//Global vairiables
static const int led_pin = LED_BUILTIN;
static const int spiClk = 4000000; // 4 MHz
//Address for the Range Register
const uint8_t RANGE = 0x2C; //Considered Reset value for this Register is 0x81.
const uint8_t RANGE_2G = 0x01; //value to set the 2G_range of the sensor
const uint8_t POWER_CTL = 0x2D; //Power control Register's Address.
const uint8_t MEASURE_MODE = 0x06; // Only accelerometer
const uint8_t ADXL_Reset_Reg_Address= 0x2F; //this Reg is only Writable. put 0x00 to this Reg in order to reset it.
//Senors's reset register address
static uint8_t READ_BYTE = 0x01;
static uint8_t WRITE_BYTE = 0x00;
static uint8_t reg_adress = 0x00;
//address of the X axis
const uint8_t XDATA3 = 0x08;
const uint8_t XDATA2 = 0x09;
const uint8_t XDATA1 = 0x0A;
//address of the Y axis
const uint8_t YDATA3 = 0x0B;
const uint8_t YDATA2 = 0x0C;
const uint8_t YDATA1 = 0x0D;
//address of the Z axis
const uint8_t ZDATA3 = 0x0E;
const uint8_t ZDATA2 = 0x0F;
const uint8_t ZDATA1 = 0x10;
//X axis variables
int8_t xdata[3]={0,0,0};
int32_t Xdata_i=0;
float Xdata_d[200] = {0.0};
//static float Xdata_d = 0;
//Y axis variables
int8_t ydata[3]={0,0,0};
int32_t Ydata_i=0;
float Ydata_d[200] = {0.0};
//static float Ydata_d = 0;
//Z axis variables
int8_t zdata[3]={0,0,0};
int32_t Zdata_i=0;
float Zdata_d[200] = {0.0};
//static float Zdata_d = 0;
char uart_buff[200]={0};
uint8_t sample_counter = 0;
bool sampling_permission = true;
uint64_t dataset_counter = 0;
uint8_t led_status = 0;
hw_timer_t * timer3 = NULL;
portMUX_TYPE timerMux3 = portMUX_INITIALIZER_UNLOCKED;
static TaskHandle_t LED_HANDLER_Handle = NULL;
static TaskHandle_t ADXL_task_Handle = NULL;
bool uart_show_dataset = false;
void IRAM_ATTR onTimer3(){
//portENTER_CRITICAL_ISR(&timerMux3);
sampling_permission = true;
Serial.println(" 2 minute has passed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
//portEXIT_CRITICAL_ISR(&timerMux3);
}
//LED Handler task
void LED_HANDLER(void *parameter){
while(1){
led_status = !led_status;
digitalWrite(LED_BUILTIN, led_status);
vTaskDelay(500 / portTICK_PERIOD_MS); // time interval dring which the task is executed,// vtask delay expects the number of tiks or time intervals,//which is set to 1ms by default
// Serial.println(" 500ms has passed " + String(millis()) + " Task LED-Blinker running on core " + String(xPortGetCoreID()));
}
}
//Accelerometer Handler task
void ADXL_Handler(void *parameter){
while(1){
if(sampling_permission){
Xdata_d[sample_counter] = Read_X_Axis(xdata);
Ydata_d[sample_counter] = Read_Y_Axis(ydata);
Zdata_d[sample_counter] = Read_Z_Axis(zdata);
sample_counter++;
if(sample_counter == 200){
sampling_permission = false;
sample_counter = 0;
dataset_counter++;
uart_show_dataset = true;
for ( int i = 0; i<200 ; i++) {
sprintf(uart_buff, "Sensor data: Ax = %.3f Ay = %.3f Az = %.3f", Xdata_d[i], Ydata_d[i], Zdata_d[i]);
Serial.println(uart_buff);
}
sprintf(uart_buff, "end of data set %d", dataset_counter);
Serial.println(uart_buff);
Serial.print("ADXL_Handler is running on core ");
Serial.println(xPortGetCoreID());
//memset(Xdata_d, 0, 200);
//memset(Ydata_d, 0, 200);
//memset(Zdata_d, 0, 200);
}
}
vTaskDelay(50 / portTICK_PERIOD_MS); //suspend this task every 4ms during which RTOS run other tasks.
}
}
void setup() {
//vTaskSuspend();
pinMode(led_pin, OUTPUT);
Serial.begin(921600);
//SPI Initializations
SPI.begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_SS); //SPI-BUS initializing
pinMode(HSPI_SS, OUTPUT); //HSPI Slave select pin defined as output
//ADXL355 initialiyation
SPI_Write_Reg (ADXL_Reset_Reg_Address , 0x52); //resetting the ADXL
SPI_Write_Reg (RANGE, RANGE_2G); //Setting the ADXL Range to 2G
SPI_Write_Reg (POWER_CTL, MEASURE_MODE); //Setting the ADXL to the measurment mode.
//create the LED Handler Task
xTaskCreatePinnedToCore(
LED_HANDLER, // function to be called as the task
"LED_HANDLER", // name of the task
1024, // stack size of the task in KB, min value 756 Byte
NULL, // parameter to pass to function
1, // task priority which is 0 to 24, higher number higher peiority
&LED_HANDLER_Handle, // a pointer used for handling the current task from other tasks or main loop
app_cpu); // choosing our core
// remember that loop() and setup() are considered as task with priority one.
//create the Acceleremetor Handler Task
xTaskCreatePinnedToCore(
ADXL_Handler, // function to be called as the task
"ADXL_Handler", // name of the task
8192, // stack size of the task in KB, min value 756 Byte
NULL, // parameter to pass to function
2, // task priority which is 0 to 24, higher number higher peiority
&ADXL_task_Handle, // a pointer used for handling the current task from other tasks or main loop
app_cpu); // choosing our core
// remember that loop() and setup() are considered as task with priority one.
//Timer1 Initialization
timer3 = timerBegin(3, 80, true); //uint8_t num, uint16_t prescalar 80, bool countUp . our clock is 80MHz
timerAttachInterrupt(timer3, &onTimer3, true); //true: trigger on edge
timerAlarmWrite(timer3, 120000000, true); // timer tick = 1u sec
timerAlarmEnable(timer3);
//vTaskResume(ADXL_task_Handle);
}
void loop() {
// put your main code here, to run repeatedly:
}
//our function definitions
bool SPI_Write_Reg (uint8_t register_addr , uint8_t register_value){
uint8_t Modif_addr = 0;
Modif_addr = (register_addr << 1) | WRITE_BYTE;
digitalWrite(HSPI_SS, LOW);
SPI.transfer(Modif_addr);
SPI.transfer(register_value);
digitalWrite(HSPI_SS, HIGH);
return true;
}
uint8_t SPI_Read_Reg(uint8_t Reg_Addr){
uint8_t Mod_Reg_Addr = (Reg_Addr << 1) | READ_BYTE;
uint8_t Reg_Value = 0;
digitalWrite(HSPI_SS, LOW);
SPI.transfer(Mod_Reg_Addr);
Reg_Value = SPI.transfer(0x00);
digitalWrite(HSPI_SS, HIGH);
return Reg_Value;
}
float Read_X_Axis(int8_t* xdata){
int32_t Xdata_i;
float Xdata_d;
xdata[0] = SPI_Read_Reg(XDATA1);
xdata[1] = SPI_Read_Reg(XDATA2);
xdata[2] = SPI_Read_Reg(XDATA3);
Xdata_i = ((int32_t)xdata[0] >> 4) + ((int32_t)xdata[1] << 4) + ((int32_t)xdata[2] << 12);
Xdata_d = (float)Xdata_i/256000;
return Xdata_d;
};
float Read_Y_Axis(int8_t* ydata){
int32_t Ydata_i;
float Ydata_d;
ydata[0] = SPI_Read_Reg(YDATA1);
ydata[1] = SPI_Read_Reg(YDATA2);
ydata[2] = SPI_Read_Reg(YDATA3);
Ydata_i = ((int32_t)ydata[0] >> 4) + ((int32_t)ydata[1] << 4) + ((int32_t)ydata[2] << 12);
Ydata_d = (float)Ydata_i/256000;
return Ydata_d;
};
float Read_Z_Axis(int8_t* zdata){
int32_t Zdata_i;
float Zdata_d;
zdata[0] = SPI_Read_Reg(ZDATA1);
zdata[1] = SPI_Read_Reg(ZDATA2);
zdata[2] = SPI_Read_Reg(ZDATA3);
Zdata_i = ((int32_t)zdata[0] >> 4) + ((int32_t)zdata[1] << 4) + ((int32_t)zdata[2] << 12);
Zdata_d = (float)Zdata_i/256000;
return Zdata_d;
};