Hallo,
I have an ESP-WROOM-32 connected to accelerometer ADXL345 through SPI. When the accelerometer collects 16 samples of x,y,z data, it toggles its interrupt pin, which is connected to ESP32 GPIO pin 12 - see the code below. I have attached an Interrupt Service Routine to this pin to fill the data into a larger array. The guru mediation error occurs (see the attached error message), when I try to write data into global variable Lambda in ISR(). When I remove this line everything works fine. I do not understand why. Can anyone explain to me why this error occurs?
Thanks a lot!
#include <SparkFun_ADXL345.h> // SparkFun ADXL345 Library
ADXL345 adxl = ADXL345(SS); // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
#define accSamples 16
void printByte(byte b);
void printByte(int b);
volatile float ** volatile xyzData;
volatile float ** volatile set1 = new volatile float * [3];
volatile float ** volatile set2 = new volatile float * [3];
volatile bool debugPrint (false);
const int accINTpin (12);
const int accPowPin (15);
void ISR();
volatile int i (0);
bool setFlag (0);
const int N (514);
volatile float Lambda (0.f);
volatile long cas1 (0);
volatile long cas2 (0);
volatile byte ODR;
/******************** SETUP ********************/
/* Configure ADXL345 Settings */
void setup(){
byte rangeSet = B00000000;
double dtr;
byte bDtr;
bool intActive;
byte fifoCtlReg;
byte enabledINT;
byte INTmapping;
double temp [3];
set1[0] = new volatile float [N];
set1[1] = new volatile float [N];
set1[2] = new volatile float [N];
set2[0] = new volatile float [N];
set2[1] = new volatile float [N];
set2[2] = new volatile float [N];
Serial.begin(9600); // Start the serial terminal
Serial.println("SETUP");
Serial.println();
pinMode(accINTpin, INPUT);
pinMode(13, INPUT);
pinMode(accPowPin, OUTPUT);
digitalWrite(accPowPin,LOW);
delay(100);
digitalWrite(accPowPin,HIGH);
adxl.powerOn(); // Power on the ADXL345 in standby mode
adxl.offsets[0] = -3;
adxl.offsets[1] = 0;
adxl.offsets[2] = 12;
adxl.gains[0] = 1;
adxl.gains[1] = 1;
adxl.gains[2] = 1;
adxl.setRangeSetting(16); // Give the range settings
// Accepted values are 2g, 4g, 8g or 16g
// Higher Values = Wider Measurement Range
// Lower Values = Greater Sensitivity
adxl.setSpiBit(0); // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
// Default: Set to 1
// SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library
adxl.getRangeSetting(&rangeSet);
Serial.println("Range setting");
printByte(rangeSet);
adxl.set_bw(ADXL345_BW_100);
bDtr = adxl.get_bw_code();
Serial.print("BW code = ");
printByte(bDtr);
ODR = dtr = adxl.getRate(); // bity D3 - D0 z registu BW_RATE
Serial.println("Data rate = ");
Serial.println(dtr);
adxl.disableAllINT();
enabledINT = adxl.getEnabledINT();
Serial.print("INT ENABLE reg = ");
printByte(enabledINT);
adxl.setFifoStream();
fifoCtlReg = adxl.getFifoCtl();
Serial.print("fifo ctl registr = ");
printByte(fifoCtlReg);
adxl.setInterruptMapping(ADXL345_WATERMARK,0);
INTmapping = adxl.getInterruptMapping();
Serial.print("Interrupt mapping = ");
printByte(INTmapping);
fifoCtlReg = adxl.WatermarkINT(1,accSamples);
intActive = adxl.isInterruptEnabled(ADXL345_WATERMARK);
enabledINT = adxl.getEnabledINT();
Serial.print("FIFO ctl reg = ");
printByte(fifoCtlReg);
Serial.print("Is watermark INT activated? : ");
Serial.println(intActive);
Serial.print("Activated interrupts: ");
printByte(enabledINT);
Serial.println("FIFO flush");
for(int h=0;h<31;++h){
adxl.get_Gxyz(temp);
}
if(!digitalRead(accINTpin)){
attachInterrupt(digitalPinToInterrupt(accINTpin), ISR , RISING);
Serial.println("ISR set!");
delay(1000);
}
adxl.setToMeasure();
xyzData = set1;
}
/****************** MAIN CODE ******************/
/* Accelerometer Readings and Interrupt */
void loop(){
}
void printByte(byte b){
for(int i=7; i>=0 ; i--){
Serial.print(bitRead(b,i));
}
Serial.println("");
}
void printByte(int b){
for(int i=15; i>=0 ; i--){
Serial.print(bitRead(b,i));
}
Serial.println("");
}
void ISR(){
byte INTreg;
bool watermarkBit;
int k;
int index;
double xyz [3];
INTreg = adxl.getInterruptSource();
watermarkBit = (INTreg >> 1) & 1;
if(watermarkBit){
for(k=0;k<accSamples;++k){
adxl.get_Gxyz(xyz);
index = accSamples*i+k;
xyzData[0][index] = xyz[0];
xyzData[1][index] = xyz[1];
xyzData[2][index] = xyz[2];
}
++i;
if(i==N/accSamples){
cas2 = micros();
Lambda = float(cas2-cas1)/1000.f;
/*xyzData[0][N-2] = Lambda;
xyzData[1][N-2] = Lambda;
xyzData[2][N-2] = Lambda;
xyzData[0][N-1] = (float)ODR;
xyzData[1][N-1] = (float)ODR;
xyzData[2][N-1] = (float)ODR;
*/
cas1 = micros();
// switch of field for storege of data
setFlag = !setFlag;
if(setFlag){
xyzData = set2;
}
else{
xyzData = set1;
}
i = 0;
debugPrint=false;
}
else{
debugPrint=true;
}
}
}
Output of the serial monitor is the following:
SETUP
Range setting
00001011
BW code = 00001011
Data rate =
200.00
INT ENABLE reg = 00000000
fifo ctl registr = 10010000
Interrupt mapping = 00000000
FIFO ctl reg = 10010000
Is watermark INT activated? : 1
Activated interrupts: 00000010
FIFO flush
ISR set!
Guru Meditation Error: Core 1 panic'ed (Coprocessor exception)
Core 1 register dump:
PC : 0x400d0ebb PS : 0x00060231 A0 : 0x80080ef4 A1 : 0x3ffbe6b0
A2 : 0x003b4f1d A3 : 0x00000001 A4 : 0x3ffc0168 A5 : 0x00000000
A6 : 0x3ffc015c A7 : 0x3ffb91fc A8 : 0x800d0ea0 A9 : 0x3ffbe750
A10 : 0x003b4f1d A11 : 0x447a0000 A12 : 0x00000000 A13 : 0x43720000
A14 : 0x80000000 A15 : 0x00000000 SAR : 0x0000001d EXCCAUSE: 0x00000004
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Core 1 was running in ISR context:
EPC1 : 0x400d0ebb EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x40086e4f
Backtrace: 0x400d0ebb:0x3ffbe6b0 0x40080ef1:0x3ffbe770 0x40080ef1:0x3ffbe7b0 0x40084db1:0x3ffbe7d0 0x400d3e2d:0x3ffb1fb0 0x400889d9:0x3ffb1fd0
Rebooting...