Sampling I2C sensor using a Timer Interrupt

DaveGo
Posts: 1
Joined: Wed Nov 10, 2021 2:39 pm

Sampling I2C sensor using a Timer Interrupt

Postby DaveGo » Wed Nov 10, 2021 3:06 pm

Hi everyone, I am new in the espressif community.
I am working on a project and my goal is to sample two different I2C sensors (flow and pressure) with a precise and specific frequency. In order to guarantee a specific frequency I am sampling these sensors inside the function attached to the interrupt, but i am receiving different errors. I think that a possible issue is related to the wire.h library. I am using this library inside the interrupt function in order to read the sensor, and maybe this can be the problem. Is it possible that these functions are too slow to be placed in an interrupt? My interrupt is really slow (1 Hz) so i don't think that can be the problem. This is the error

Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC : 0x400896b6 PS : 0x00060e34 A0 : 0x800888ab A1 : 0x3ffbea40
A2 : 0x3ffb7f38 A3 : 0x3ffbc830 A4 : 0x00000001 A5 : 0x00000001
A6 : 0x00060e23 A7 : 0x00000000 A8 : 0x3ffbc830 A9 : 0x3ffbc830
A10 : 0x00000019 A11 : 0x00000019 A12 : 0x00000001 A13 : 0x00000001
A14 : 0x00060e23 A15 : 0x00000000 SAR : 0x0000000a EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000
Core 1 was running in ISR context:
EPC1 : 0x400d14e4 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400896b6

ELF file SHA256: 0000000000000000

Backtrace: 0x400896b6:0x3ffbea40 0x400888a8:0x3ffbea60 0x40086c0b:0x3ffbea80 0x40086c79:0x3ffbeac0 0x400d1be9:0x3ffbeae0 0x400d1eb2:0x3ffbeb10 0x400d1251:0x3ffbeb30 0x400d1306:0x3ffbeb60 0x400d1355:0x3ffbeb90 0x40080f48:0x3ffbebb0 0x400817b9:0x3ffbebd0 0x40084431:0x3ffbebf0 0x400ea837:0x3ffbc720 0x400e2b2b:0x3ffbc740 0x4008853a:0x3ffbc760 0x40086dd1:0x3ffbc780

Core 0 register dump:
PC : 0x40087db2 PS : 0x00060034 A0 : 0x80088571 A1 : 0x3ffbe570
A2 : 0x3ffbdfd4 A3 : 0x0000cdcd A4 : 0xb33fffff A5 : 0x00000001
A6 : 0x00060021 A7 : 0x0000abab A8 : 0x0000cdcd A9 : 0x3ffc0420
A10 : 0x00000003 A11 : 0x00060023 A12 : 0x00060021 A13 : 0x3ffbbaf0
A14 : 0x00000000 A15 : 0x3ffbbe80 SAR : 0x00000013 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000

ELF file SHA256: 0000000000000000

Backtrace: 0x40087db2:0x3ffbe570 0x4008856e:0x3ffbe5a0 0x40086ebb:0x3ffbe5c0 0x40089539:0x3ffbe5e0 0x4008443a:0x3ffbe5f0 0x400ea837:0x3ffbc190 0x400e2b2b:0x3ffbc1b0 0x4008853a:0x3ffbc1d0 0x40086dd1:0x3ffbc1f0

Rebooting...
ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5856
entry 0x400806a8

and this is my code

#include <Arduino.h>
#include <AMS.h>
#include <Wire.h>
volatile float Pressure;
volatile float Flow;
int PressureInt;
byte Flow_shift;
byte Pressure_shift;
byte combine;
String DataString;
String p="p";
String f="f";
String pressure;
String flow;
String package;
String ending="e";
int offset = 32768; // Offset for the sensor
float scale = 800.0;
volatile bool flag;
volatile int count;

AMS AMSa(5915, 0x28,0,2068); //dovrebbe essere 0x28 l'i2c address del AMS 5915


hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

// Code with critica section
void IRAM_ATTR onTime() {

portENTER_CRITICAL_ISR(&timerMux);
flag =true;
Wire.requestFrom(0x28, 2);
Pressure = AMSa.readPressure();
Wire.requestFrom(0x40, 2); // read 2 bytes from device with address 0x40
uint8_t b[2];
b[1] = Wire.read(); //
b[0] = Wire.read(); //10 100 nano condensatore
uint16_t c {0};
c = (b[1] << 8) | b[0];// second received byte stored here
float Flow = ((float)c - offset) / scale;
portEXIT_CRITICAL_ISR(&timerMux);
}

void setup() {
Serial.begin(115200);
flag = false;

timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTime, true);

// Sets an alarm to sound every second
timerAlarmWrite(timer, 1000000, true);
timerAlarmEnable(timer);
Wire.begin();
int a = 0;
int b = 0;
int c = 0;

delay(1000);

Wire.beginTransmission(byte(0x40)); // transmit to device #064 (0x40)
Wire.write(byte(0x10)); //
Wire.write(byte(0x00)); //
Wire.endTransmission();

delay(5);

Wire.requestFrom(0x40, 3); //
a = Wire.read(); // first received byte stored here
b = Wire.read(); // second received byte stored here
c = Wire.read(); // third received byte stored here
Wire.endTransmission();
Serial.print(a);
Serial.print(b);
Serial.println(c);

delay(5);

Wire.requestFrom(0x40, 3); //
a = Wire.read(); // first received byte stored here
b = Wire.read(); // second received byte stored here
c = Wire.read(); // third received byte stored here
Wire.endTransmission();
Serial.print(a);
Serial.print(b);
Serial.println(c);
delay(5);
}

void loop() {
if(flag){
flag =false;
String stringOne = String(Pressure, 5);
pressure=p+stringOne;
String stringOne1 = String(Flow, 4);
flow=f+stringOne1;
package=pressure+flow+ending;
Serial.println(package);
}
}

Thank you all
Attachments
prova_interrupt.zip
(2.83 KiB) Downloaded 269 times
AMS.zip
(42.15 KiB) Downloaded 272 times

rodmcm
Posts: 65
Joined: Sat Sep 02, 2017 3:31 am

Re: Sampling I2C sensor using a Timer Interrupt

Postby rodmcm » Sun Nov 21, 2021 3:29 am

Hi
What are you exactly trying to do by sampling through an interrupt? What is the purpose?

rodmcm
Posts: 65
Joined: Sat Sep 02, 2017 3:31 am

Re: Sampling I2C sensor using a Timer Interrupt

Postby rodmcm » Sun Nov 21, 2021 3:32 am

If you set up a simple wire read from both sensors you can measure the period to read them both which will be well below your sample period. You can then sample the reading through then interrupt

Who is online

Users browsing this forum: No registered users and 55 guests