Page 1 of 1

ESP32 crash on reading ADS1115 on interrupt

Posted: Sun May 02, 2021 10:26 am
by smah80
Hi,
I am using ADS1115 and reading its trying to read its value based on interrupt.
but it get crashed when trying to read the following line.

Code: Select all

void ICACHE_RAM_ATTR encoder_isr() {
adc0 = ads.readADC_SingleEnded(0); // Crashed here.[adc0 is volatile int16_t];
voltage = ads.computeVolts(adc0);
}
here is the exception what serial monitor shows

Code: Select all

Guru Meditation Error: Core 1 panic’ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC : 0x400d18ac PS : 0x00060a34 A0 : 0x800d1e21 A1 : 0x3ffbe660
A2 : 0x3ffbebe8 A3 : 0x00000000 A4 : 0x00000190 A5 : 0x00000064
A6 : 0x000000c8 A7 : 0x60013000 A8 : 0xffffc000 A9 : 0x0155409f
A10 : 0x0e4e1c00 A11 : 0x00000001 A12 : 0x00000000 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001d EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000
Core 1 was running in ISR context:
EPC1 : 0x400d295e EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d18ac
Backtrace: 0x400d18ac:0x3ffbe660 0x400d1e1e:0x3ffbe680 0x400d1f4c:0x3ffbe6b0 0x400d1245:0x3ffbe6d0 0x400d1299:0x3ffbe6f0 0x400d10a1:0x3ffbe710 0x400d0f0e:0x3ffbe730 0x400d0f69:0x3ffbe750 0x400d0fc0:0x3ffbe770 0x40080f17:0x3ffbe790 0x40080fd9:0x3ffbe7b0 0x40084e99:0x3ffbe7d0 0x40081ddb:0x3ffb1f30 0x40082963:0x3ffb1f50 0x40081a33:0x3ffb1f70 0x400d0d96:0x3ffb1f90 0x400d27d1:0x3ffb1fb0 0x40088ac1:0x3ffb1fd0
Core 0 register dump:
PC : 0x400ea46e PS : 0x00060134 A0 : 0x800d5196 A1 : 0x3ffbbff0
A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000000 A5 : 0x00000001
A6 : 0x00060120 A7 : 0x00000000 A8 : 0x800d4d5e A9 : 0x3ffbbfc0
A10 : 0x00000000 A11 : 0x40085624 A12 : 0x00060120 A13 : 0x3ffbb690
A14 : 0x00000000 A15 : 0x3ffbbce0 SAR : 0x00000000 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Backtrace: 0x400ea46e:0x3ffbbff0 0x400d5193:0x3ffbc010 0x4008a262:0x3ffbc030 0x40088ac1:0x3ffbc050
Any idea why this is happening?

Re: ESP32 crash on reading ADS1115 on interrupt

Posted: Thu May 06, 2021 3:11 am
by ESP_Sprite
Likely ads.readADC_SingleEnded is not safe to call from an ISR. Suggest you use e.g. a FreeRTOS semaphore to communicate the fact that an interrupt happened to a task, then do the read in that task instead.

Re: ESP32 crash on reading ADS1115 on interrupt

Posted: Fri Jul 09, 2021 8:20 pm
by smah80
I am trying to work on a balancing system, that need to read signals (in form of voltage) and at the same time I should be able to read the encoder value (degree).
FreeRtos is something that seems be able to do it by using ESP32 multi-core feature, but as I am not familiar with it.
currently this is my configuration

ESP32
OMRON 360 pulse encoder having A,B,Z.

ADS1115 attached with SDA, SCL.

A voltage generator(sensor) is connecting to ADS1115.

Machine is running on 1350 RPM. A encoder and voltage generator attached with ESP32. while I am sending all the serially to my UI. (i.e. RPM calculation and the collected data)

If I stop reading ADS1115, on 1200-1350 RPM its skipping 2-5 pulses. but when I added reading ADC part, it start skipping 50-70 pulses of encoder.

Please any suggestion and help is highly appreciated, as this becomes a nightmare for me.

Note: the crash issue is fixed as I put it in the main loop
Thanks

Re: ESP32 crash on reading ADS1115 on interrupt

Posted: Mon Jul 12, 2021 2:27 am
by ESP_Sprite
Impossible to say; is your code available somewhere?

Re: ESP32 crash on reading ADS1115 on interrupt

Posted: Sun Jul 18, 2021 7:22 am
by smah80
hi, I fixed that crashing issue, that was because the ADS1115 library not worked on ISR. I pull out it from ISR and put in main loop, so it start working.

But still have problem, that encoder is now missing the pulses while going to read the ADC.
here is my complete code. I want it to read encoder using PCNT. and another task would be reading the ADC value at the same time.
could you please help to write a routine in which I can read the Encoder (having A,B,Z) pulses using PCNT and at the same time read the ADC. your help will be highly appreciated.

Code: Select all

#include <Adafruit_ADS1X15.h>
#define RUNTIME_MS  10000
// Pin definitions
const byte ZeroPin = 27;  
const byte COSPin = 26;   
const byte SINPin = 25;   
Adafruit_ADS1115 ads;

volatile int encoder_position = 0;
volatile int encoder_oldpos = 0; 
volatile float weight = 0.0;
volatile float hi_weight = 3.09;
volatile int angle, hi_angle = 0;
volatile int rev =0;
static uint32_t lastMillis = 0;
volatile int16_t adc0;
void ICACHE_RAM_ATTR encoder_isr();
void ICACHE_RAM_ATTR zero_detection_isr();
int elapsedTime,rpm = 0;
boolean isEnd = false;
void setup() {
  ads.setGain(GAIN_ONE);
  ads.begin();
  Serial.begin(115200);
  
  pinMode(SINPin, INPUT_PULLUP);
  pinMode(COSPin, INPUT_PULLUP);
  pinMode(ZeroPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(COSPin), encoder_isr, RISING);

  attachInterrupt(digitalPinToInterrupt(ZeroPin), zero_detection_isr, HIGH);
  
}


void loop() {
  
   while((millis() - elapsedTime) <= RUNTIME_MS){
  // Detect Encoder Stop
if(encoder_position !=encoder_oldpos){
printdata();
readADC();
encoder_oldpos = encoder_position;
}
if (millis() - lastMillis > 1000) {
  lastMillis = millis();
rpm = rev;
rev=0;
}
}
if(!isEnd) {
noInterrupts();
printFinalData();
delay(1000);
isEnd = true;
}
}
void ICACHE_RAM_ATTR encoder_isr() {
  
  if  (digitalRead(SINPin) == LOW) {
    encoder_position++;
  } else {
    encoder_position--;    
    
  } 

}

void readADC() {

  adc0  = ads.readADC_SingleEnded(0);
   weight = ads.computeVolts(adc0);
  if((int) (weight * 10) < (int) (hi_weight * 10) ){
  hi_weight = weight;
  hi_angle = encoder_position;
  }
  }

void ICACHE_RAM_ATTR zero_detection_isr() {
  encoder_position = 0;
  rev++;
}

void printdata() {
   angle = encoder_position;
 Serial.print(angle); 
   Serial.print("*");
    Serial.print(weight);
    Serial.print("*");
    Serial.print(hi_angle);
    Serial.print("*");   
    Serial.print(hi_weight);
    Serial.print("*");   
    Serial.print(rpm);
    Serial.print("#\n");   
  }
  void printFinalData() {
     Serial.print(angle);
    Serial.print("*");
    Serial.print(weight);
    Serial.print("*");
    Serial.print(hi_angle);
    Serial.print("*");   
    Serial.print(hi_weight);
    Serial.print("*");   
    Serial.print((rpm * 0));
Serial.print("*TO#");
}