Hey every body. I have a problem regarding setting up two timers on ESP32 using Arduino.h library.
when I set up the first timer it works properly but when I set up the second one, The ESP32 crashes every one minutes and reboots probably when the the flags set or reset in my program.
Timer1 overflows each 4ms
Timer3 overflows every 1 second.
As it is obvious from the results, timer 1 works properly and also Timer 3 works properly because every second the build in LED of ESP32 blinks but every one minute, my ESP crashes. I would appreciate any feedback.
Thanks in advance.
Kind Regards
#include <SPI.h>
#include <Arduino.h>
#define HSPI_MISO 12
#define HSPI_MOSI 13
#define HSPI_SCLK 14
#define HSPI_SS 15
//function prototypes;
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 *xdata);
float Read_Z_Axis(int8_t *xdata);
void Wall_Clock_Manager(void);
static const int spiClk = 1000000; // 1 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 onorder to reset it.
//Senors's reset register address
uint8_t READ_BYTE = 0x01;
uint8_t WRITE_BYTE = 0x00;
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[1000] = {0};
//Y axis variables
int8_t ydata[3]={0,0,0};
int32_t Ydata_i=0;
float Ydata_d[1000] = {0};
//Z axis variables
int8_t zdata[3]={0,0,0};
int32_t Zdata_i=0;
float Zdata_d[1000] = {0};
char uart_buff[200];
uint8_t second = 0;
uint8_t minute = 0;
uint8_t hour = 0;
uint32_t Sample_Counter = 0;
//Corresponding global variable to Timer 0.
hw_timer_t * timer3 = NULL;
hw_timer_t * timer1 = NULL;
portMUX_TYPE timerMux3 = portMUX_INITIALIZER_UNLOCKED;
portMUX_TYPE timerMux1 = portMUX_INITIALIZER_UNLOCKED;
volatile byte state = LOW;
uint8_t Sampling_Permision_perhour = 1;
uint8_t Sampling_Permision_per4ms = 0;
//bool Show_DataSet_Flag = false;
uint8_t wall_clock_Flag = 0;
void IRAM_ATTR onTimer3(){
portENTER_CRITICAL_ISR(&timerMux3);
wall_clock_Flag = 1;
portEXIT_CRITICAL_ISR(&timerMux3);
}
void IRAM_ATTR onTimer1(){
portENTER_CRITICAL_ISR(&timerMux1);
if(Sampling_Permision_perhour == 1){
Sampling_Permision_per4ms = 1;
}
portEXIT_CRITICAL_ISR(&timerMux1);
}
void setup() {
//Blue LED of NODE MCU initialization.
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, 0);
//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.
//Initializing the UART
Serial.begin(921600);
//Timer3 Initialization
timer3 = timerBegin(0, 80, true); //uint8_t num, uint16_t prescalar 80, bool countUp . our clock is 80MHz
timerAttachInterrupt(timer3, &onTimer3, true);
timerAlarmWrite(timer3, 1000000, true); //the callback function will be executed when timer ticks 1000000 times
Serial.println("The timer3 has been activated");
//Timer1 Initialization
timer1 = timerBegin(1, 80, true); //uint8_t num, uint16_t prescalar 80, bool countUp . our clock is 80MHz
timerAttachInterrupt(timer1, &onTimer1, true);
timerAlarmWrite(timer1, 4000, true);
timerAlarmEnable(timer3);
timerAlarmEnable(timer1);
Serial.println("The timer1 has been activated");
//delay(1000);
}
// the loop function runs over and over again until power down or reset
void loop() {
//Wall_Clock_Manager();
if(wall_clock_Flag){
Wall_Clock_Manager();
}
if (Sampling_Permision_per4ms == 1 && Sampling_Permision_perhour == 1) {
Sampling_Permision_per4ms = 0;
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 == 1000) {
Sampling_Permision_perhour = 0;
Sample_Counter == 0;
for (int i = 0; i < 1000; 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, "DataSet for hour %d", hour);
Serial.println(uart_buff);
}
}
}
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* xdata){
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* xdata){
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;
};
void Wall_Clock_Manager(void){
wall_clock_Flag = 0;
second++;
if(second == 60){
minute++;
second = 0;
if(minute == 1){
minute = 0;
hour++;
Sampling_Permision_perhour = 1;
}
}
state = !state;
digitalWrite(LED_BUILTIN, state);
}


