ESP32 + DEEP SLEEP + I2C - Interrupt ProblemI2C Sampling RateArduino (AVR ATMega328) Timer1 does not seem to trigger at the right timeHow to change the length of Fast LEDs CRGB array based on inputArduino Bluetooth SerialTM4C123GX - why isn't 16/32-bit Timer0A interrupt working?ESP32 deep Sleep wakeup with disabled RFI2C and interruptsESP32 to ESP32 AP/client WiFi connection problemESP32 to ESP32 WiFi Server/Client ProblemESP32 interrupt problem with 20kHz signal

Minkowski space

To string or not to string

Is it legal for company to use my work email to pretend I still work there?

Service Entrance Breakers Rain Shield

Has the BBC provided arguments for saying Brexit being cancelled is unlikely?

Why was the small council so happy for Tyrion to become the Master of Coin?

What would happen to a modern skyscraper if it rains micro blackholes?

What does it mean to describe someone as a butt steak?

Approximately how much travel time was saved by the opening of the Suez Canal in 1869?

The Two and the One

Theorem, big Paralist and Amsart

can i play a electric guitar through a bass amp?

Risk of getting Chronic Wasting Disease (CWD) in the United States?

What's the output of a record cartridge playing an out-of-speed record

A newer friend of my brother's gave him a load of baseball cards that are supposedly extremely valuable. Is this a scam?

Fencing style for blades that can attack from a distance

Have astronauts in space suits ever taken selfies? If so, how?

What typically incentivizes a professor to change jobs to a lower ranking university?

Do VLANs within a subnet need to have their own subnet for router on a stick?

Email Account under attack (really) - anything I can do?

"You are your self first supporter", a more proper way to say it

Why does Kotter return in Welcome Back Kotter?

How is it possible to have an ability score that is less than 3?

Why doesn't Newton's third law mean a person bounces back to where they started when they hit the ground?



ESP32 + DEEP SLEEP + I2C - Interrupt Problem


I2C Sampling RateArduino (AVR ATMega328) Timer1 does not seem to trigger at the right timeHow to change the length of Fast LEDs CRGB array based on inputArduino Bluetooth SerialTM4C123GX - why isn't 16/32-bit Timer0A interrupt working?ESP32 deep Sleep wakeup with disabled RFI2C and interruptsESP32 to ESP32 AP/client WiFi connection problemESP32 to ESP32 WiFi Server/Client ProblemESP32 interrupt problem with 20kHz signal






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I am having problem of executing deepsleep and i2c communication in the ISR(Interrupt Mode).



I am using this library coding it in Arduino IDE :



https://github.com/espressif/arduino-esp32



https://techtutorialsx.com/2017/09/30/esp32-arduino-external-interrupts/



It's working fine for i2c (such as turning on LED) when I run it in the void loop() function, but when I port it to interrupt it doesn't work.



Same with deepsleep, I can't execute it in the interrupt mode. The way I go around it is that I set a flag in interrupt mode to show that I want to deepsleep and then execute it in the void loop() function.



Does anyone have any solution on how to make this work? (code is just for i2c and esp32)



#include <Wire.h>

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif

// Interrupt Setup - TIMER
hw_timer_t * timer = NULL; //configure the timer, need pointer to a variable type of hw_timer_t
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // used to sync main loop and ISR
RTC_DATA_ATTR bool should_sleep = false;

// Setting ADC Properties - BATTERY
int voltage_amplifier = 0;
int battery_percentage = 0;

// Set i2c Address - I/O EXPANDER
const int address = 0x20;
uint16_t led_status = word(B11111111,B11111111);

// INTERRUPT MODE - INSERT INBETWEEN portENTER and portEXIT
void IRAM_ATTR onTimer()
portENTER_CRITICAL_ISR(&timerMux);
// led_battery(); led doesn't update if used here
portEXIT_CRITICAL_ISR(&timerMux);


void led_battery()
voltage_amplifier = analogRead(34);
Serial.println(voltage_amplifier);
int bit_max = 4096;
int battery_percentage = voltage_amplifier*100/bit_max;

// If battery is below 20%
if (battery_percentage <= 20)= ~word(B11000000,B00000000); // setting up the bits that we want to change
pf575_write(led_status);


else if (battery_percentage <= 40)
led_status &= word(B00011111,B11111111); // clearing the bits that we want to change whilst preserving the other unchanged bits
led_status

else if (battery_percentage <= 60)
led_status &= word(B00001111,B11111111); // clearing the bits that we want to change whilst preserving the other unchanged bits
led_status

else if (battery_percentage <= 80)= ~word(B11111000,B00000000); // setting up the bits that we want to change
pf575_write(led_status);


else if (battery_percentage <= 100)= ~word(B11111100,B00000000); // setting up the bits that we want to change
pf575_write(led_status);



void ioexpander_setup()
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("n Blinker Ready");
Wire.begin();


void pf575_write(uint16_t data)
Wire.beginTransmission(address);
Wire.write(lowByte(data));
Wire.write(highByte(data));
Wire.endTransmission();


void timer_setup() Clock Cycle = 1us [in this case]
timer = timerBegin(0,80,true); // return a pointer to a structure of type hw_timer_t

// Timer binded to a handling function
timerAttachInterrupt(timer, &onTimer, true); // Parameter : (timer_initialization, address_interrupt,flag_to_activate - true(edge)/false(level))

// Specify the counter value in which the timer interrupt will be generated (set every 10 ms)
timerAlarmWrite(timer, 10000, true); // Parameter : (timer_initialization, when_to_interrupt (us), flag_to_reload)

// Enable the timer
timerAlarmEnable(timer);


void setup()
Serial.begin(115200);

// IO Expander
ioexpander_setup();

// Timer
timer_setup();



void loop()
led_battery(); //led update if used here










share|improve this question
























  • Please share a minimal, viable, complete example of code that demonstrates your problem.

    – John Romkey
    Mar 22 at 0:54











  • @JohnRomkey here you go, hope it is clear. Sorry if there's any annoying formatting, I'm new to stackoverflow.

    – Ricco Yudha
    Mar 22 at 1:41

















0















I am having problem of executing deepsleep and i2c communication in the ISR(Interrupt Mode).



I am using this library coding it in Arduino IDE :



https://github.com/espressif/arduino-esp32



https://techtutorialsx.com/2017/09/30/esp32-arduino-external-interrupts/



It's working fine for i2c (such as turning on LED) when I run it in the void loop() function, but when I port it to interrupt it doesn't work.



Same with deepsleep, I can't execute it in the interrupt mode. The way I go around it is that I set a flag in interrupt mode to show that I want to deepsleep and then execute it in the void loop() function.



Does anyone have any solution on how to make this work? (code is just for i2c and esp32)



#include <Wire.h>

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif

// Interrupt Setup - TIMER
hw_timer_t * timer = NULL; //configure the timer, need pointer to a variable type of hw_timer_t
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // used to sync main loop and ISR
RTC_DATA_ATTR bool should_sleep = false;

// Setting ADC Properties - BATTERY
int voltage_amplifier = 0;
int battery_percentage = 0;

// Set i2c Address - I/O EXPANDER
const int address = 0x20;
uint16_t led_status = word(B11111111,B11111111);

// INTERRUPT MODE - INSERT INBETWEEN portENTER and portEXIT
void IRAM_ATTR onTimer()
portENTER_CRITICAL_ISR(&timerMux);
// led_battery(); led doesn't update if used here
portEXIT_CRITICAL_ISR(&timerMux);


void led_battery()
voltage_amplifier = analogRead(34);
Serial.println(voltage_amplifier);
int bit_max = 4096;
int battery_percentage = voltage_amplifier*100/bit_max;

// If battery is below 20%
if (battery_percentage <= 20)= ~word(B11000000,B00000000); // setting up the bits that we want to change
pf575_write(led_status);


else if (battery_percentage <= 40)
led_status &= word(B00011111,B11111111); // clearing the bits that we want to change whilst preserving the other unchanged bits
led_status

else if (battery_percentage <= 60)
led_status &= word(B00001111,B11111111); // clearing the bits that we want to change whilst preserving the other unchanged bits
led_status

else if (battery_percentage <= 80)= ~word(B11111000,B00000000); // setting up the bits that we want to change
pf575_write(led_status);


else if (battery_percentage <= 100)= ~word(B11111100,B00000000); // setting up the bits that we want to change
pf575_write(led_status);



void ioexpander_setup()
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("n Blinker Ready");
Wire.begin();


void pf575_write(uint16_t data)
Wire.beginTransmission(address);
Wire.write(lowByte(data));
Wire.write(highByte(data));
Wire.endTransmission();


void timer_setup() Clock Cycle = 1us [in this case]
timer = timerBegin(0,80,true); // return a pointer to a structure of type hw_timer_t

// Timer binded to a handling function
timerAttachInterrupt(timer, &onTimer, true); // Parameter : (timer_initialization, address_interrupt,flag_to_activate - true(edge)/false(level))

// Specify the counter value in which the timer interrupt will be generated (set every 10 ms)
timerAlarmWrite(timer, 10000, true); // Parameter : (timer_initialization, when_to_interrupt (us), flag_to_reload)

// Enable the timer
timerAlarmEnable(timer);


void setup()
Serial.begin(115200);

// IO Expander
ioexpander_setup();

// Timer
timer_setup();



void loop()
led_battery(); //led update if used here










share|improve this question
























  • Please share a minimal, viable, complete example of code that demonstrates your problem.

    – John Romkey
    Mar 22 at 0:54











  • @JohnRomkey here you go, hope it is clear. Sorry if there's any annoying formatting, I'm new to stackoverflow.

    – Ricco Yudha
    Mar 22 at 1:41













0












0








0








I am having problem of executing deepsleep and i2c communication in the ISR(Interrupt Mode).



I am using this library coding it in Arduino IDE :



https://github.com/espressif/arduino-esp32



https://techtutorialsx.com/2017/09/30/esp32-arduino-external-interrupts/



It's working fine for i2c (such as turning on LED) when I run it in the void loop() function, but when I port it to interrupt it doesn't work.



Same with deepsleep, I can't execute it in the interrupt mode. The way I go around it is that I set a flag in interrupt mode to show that I want to deepsleep and then execute it in the void loop() function.



Does anyone have any solution on how to make this work? (code is just for i2c and esp32)



#include <Wire.h>

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif

// Interrupt Setup - TIMER
hw_timer_t * timer = NULL; //configure the timer, need pointer to a variable type of hw_timer_t
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // used to sync main loop and ISR
RTC_DATA_ATTR bool should_sleep = false;

// Setting ADC Properties - BATTERY
int voltage_amplifier = 0;
int battery_percentage = 0;

// Set i2c Address - I/O EXPANDER
const int address = 0x20;
uint16_t led_status = word(B11111111,B11111111);

// INTERRUPT MODE - INSERT INBETWEEN portENTER and portEXIT
void IRAM_ATTR onTimer()
portENTER_CRITICAL_ISR(&timerMux);
// led_battery(); led doesn't update if used here
portEXIT_CRITICAL_ISR(&timerMux);


void led_battery()
voltage_amplifier = analogRead(34);
Serial.println(voltage_amplifier);
int bit_max = 4096;
int battery_percentage = voltage_amplifier*100/bit_max;

// If battery is below 20%
if (battery_percentage <= 20)= ~word(B11000000,B00000000); // setting up the bits that we want to change
pf575_write(led_status);


else if (battery_percentage <= 40)
led_status &= word(B00011111,B11111111); // clearing the bits that we want to change whilst preserving the other unchanged bits
led_status

else if (battery_percentage <= 60)
led_status &= word(B00001111,B11111111); // clearing the bits that we want to change whilst preserving the other unchanged bits
led_status

else if (battery_percentage <= 80)= ~word(B11111000,B00000000); // setting up the bits that we want to change
pf575_write(led_status);


else if (battery_percentage <= 100)= ~word(B11111100,B00000000); // setting up the bits that we want to change
pf575_write(led_status);



void ioexpander_setup()
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("n Blinker Ready");
Wire.begin();


void pf575_write(uint16_t data)
Wire.beginTransmission(address);
Wire.write(lowByte(data));
Wire.write(highByte(data));
Wire.endTransmission();


void timer_setup() Clock Cycle = 1us [in this case]
timer = timerBegin(0,80,true); // return a pointer to a structure of type hw_timer_t

// Timer binded to a handling function
timerAttachInterrupt(timer, &onTimer, true); // Parameter : (timer_initialization, address_interrupt,flag_to_activate - true(edge)/false(level))

// Specify the counter value in which the timer interrupt will be generated (set every 10 ms)
timerAlarmWrite(timer, 10000, true); // Parameter : (timer_initialization, when_to_interrupt (us), flag_to_reload)

// Enable the timer
timerAlarmEnable(timer);


void setup()
Serial.begin(115200);

// IO Expander
ioexpander_setup();

// Timer
timer_setup();



void loop()
led_battery(); //led update if used here










share|improve this question
















I am having problem of executing deepsleep and i2c communication in the ISR(Interrupt Mode).



I am using this library coding it in Arduino IDE :



https://github.com/espressif/arduino-esp32



https://techtutorialsx.com/2017/09/30/esp32-arduino-external-interrupts/



It's working fine for i2c (such as turning on LED) when I run it in the void loop() function, but when I port it to interrupt it doesn't work.



Same with deepsleep, I can't execute it in the interrupt mode. The way I go around it is that I set a flag in interrupt mode to show that I want to deepsleep and then execute it in the void loop() function.



Does anyone have any solution on how to make this work? (code is just for i2c and esp32)



#include <Wire.h>

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif

// Interrupt Setup - TIMER
hw_timer_t * timer = NULL; //configure the timer, need pointer to a variable type of hw_timer_t
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // used to sync main loop and ISR
RTC_DATA_ATTR bool should_sleep = false;

// Setting ADC Properties - BATTERY
int voltage_amplifier = 0;
int battery_percentage = 0;

// Set i2c Address - I/O EXPANDER
const int address = 0x20;
uint16_t led_status = word(B11111111,B11111111);

// INTERRUPT MODE - INSERT INBETWEEN portENTER and portEXIT
void IRAM_ATTR onTimer()
portENTER_CRITICAL_ISR(&timerMux);
// led_battery(); led doesn't update if used here
portEXIT_CRITICAL_ISR(&timerMux);


void led_battery()
voltage_amplifier = analogRead(34);
Serial.println(voltage_amplifier);
int bit_max = 4096;
int battery_percentage = voltage_amplifier*100/bit_max;

// If battery is below 20%
if (battery_percentage <= 20)= ~word(B11000000,B00000000); // setting up the bits that we want to change
pf575_write(led_status);


else if (battery_percentage <= 40)
led_status &= word(B00011111,B11111111); // clearing the bits that we want to change whilst preserving the other unchanged bits
led_status

else if (battery_percentage <= 60)
led_status &= word(B00001111,B11111111); // clearing the bits that we want to change whilst preserving the other unchanged bits
led_status

else if (battery_percentage <= 80)= ~word(B11111000,B00000000); // setting up the bits that we want to change
pf575_write(led_status);


else if (battery_percentage <= 100)= ~word(B11111100,B00000000); // setting up the bits that we want to change
pf575_write(led_status);



void ioexpander_setup()
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("n Blinker Ready");
Wire.begin();


void pf575_write(uint16_t data)
Wire.beginTransmission(address);
Wire.write(lowByte(data));
Wire.write(highByte(data));
Wire.endTransmission();


void timer_setup() Clock Cycle = 1us [in this case]
timer = timerBegin(0,80,true); // return a pointer to a structure of type hw_timer_t

// Timer binded to a handling function
timerAttachInterrupt(timer, &onTimer, true); // Parameter : (timer_initialization, address_interrupt,flag_to_activate - true(edge)/false(level))

// Specify the counter value in which the timer interrupt will be generated (set every 10 ms)
timerAlarmWrite(timer, 10000, true); // Parameter : (timer_initialization, when_to_interrupt (us), flag_to_reload)

// Enable the timer
timerAlarmEnable(timer);


void setup()
Serial.begin(115200);

// IO Expander
ioexpander_setup();

// Timer
timer_setup();



void loop()
led_battery(); //led update if used here







arduino microcontroller esp32






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 22 at 1:45







Ricco Yudha

















asked Mar 22 at 0:08









Ricco YudhaRicco Yudha

32




32












  • Please share a minimal, viable, complete example of code that demonstrates your problem.

    – John Romkey
    Mar 22 at 0:54











  • @JohnRomkey here you go, hope it is clear. Sorry if there's any annoying formatting, I'm new to stackoverflow.

    – Ricco Yudha
    Mar 22 at 1:41

















  • Please share a minimal, viable, complete example of code that demonstrates your problem.

    – John Romkey
    Mar 22 at 0:54











  • @JohnRomkey here you go, hope it is clear. Sorry if there's any annoying formatting, I'm new to stackoverflow.

    – Ricco Yudha
    Mar 22 at 1:41
















Please share a minimal, viable, complete example of code that demonstrates your problem.

– John Romkey
Mar 22 at 0:54





Please share a minimal, viable, complete example of code that demonstrates your problem.

– John Romkey
Mar 22 at 0:54













@JohnRomkey here you go, hope it is clear. Sorry if there's any annoying formatting, I'm new to stackoverflow.

– Ricco Yudha
Mar 22 at 1:41





@JohnRomkey here you go, hope it is clear. Sorry if there's any annoying formatting, I'm new to stackoverflow.

– Ricco Yudha
Mar 22 at 1:41












1 Answer
1






active

oldest

votes


















0














When you call led_battery() from the interrupt handler, you're doing waaaaay too much work there.



The interrupt can interrupt anything that doesn't have interrupts locked out.



Suppose your code is outputting something using Serial and the timer interrupt happens. Now your code was running code somewhere inside Serial, and you call Serial again... while the software and hardware can be in inconsistent states.



This is the case with every subroutine and hardware access you do from an interrupt handler. The only way to protect against this is to disable interrupts whenever your code might be accessing hardware or might have modifying data structures.



Unfortunately, disabling interrupts is error-prone - if you forget to do it, you'll have mysterious crashes. If you forget to reenable them, you're in big trouble - your network, timers and Serial will all stop working. It also adds a lot of overhead to your code. And it degrades your overall system performance - it will delay or cause you to miss network and timer events. You may drop characters from the serial port. And you can be certain that none of the code in the Arduino Core is doing this for you.



So, long story short, locking out interrupts so that you can do a lot in an interrupt handler is just not practical.



You also want to minimize the time you spend in the interrupt handler, as this preempts network stack, timer, serial and other hardware processing and may block other



You pointed out the way we deal with this in your original post: set a flag (make sure it's volatile) in the interrupt handler and handle it in a task. Unless you really, really know what you're doing and how all the software works in your system, this is the only practical way to handle this. If you try to do the amount of work and call the things you're calling from an interrupt handler, your program will malfunction and crash.






share|improve this answer























  • Yeah, just found out that you can't use interrupt to keep track of something consistently unless it's really urgent, and you need to spend minimal time on that state. Thanks for your input ! @JohnRomkey

    – Ricco Yudha
    Mar 25 at 22:06












  • @RiccoYudha, if you find my answer to be accurate then please accept it as the solution.

    – John Romkey
    Mar 26 at 3:21











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55290996%2fesp32-deep-sleep-i2c-interrupt-problem%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














When you call led_battery() from the interrupt handler, you're doing waaaaay too much work there.



The interrupt can interrupt anything that doesn't have interrupts locked out.



Suppose your code is outputting something using Serial and the timer interrupt happens. Now your code was running code somewhere inside Serial, and you call Serial again... while the software and hardware can be in inconsistent states.



This is the case with every subroutine and hardware access you do from an interrupt handler. The only way to protect against this is to disable interrupts whenever your code might be accessing hardware or might have modifying data structures.



Unfortunately, disabling interrupts is error-prone - if you forget to do it, you'll have mysterious crashes. If you forget to reenable them, you're in big trouble - your network, timers and Serial will all stop working. It also adds a lot of overhead to your code. And it degrades your overall system performance - it will delay or cause you to miss network and timer events. You may drop characters from the serial port. And you can be certain that none of the code in the Arduino Core is doing this for you.



So, long story short, locking out interrupts so that you can do a lot in an interrupt handler is just not practical.



You also want to minimize the time you spend in the interrupt handler, as this preempts network stack, timer, serial and other hardware processing and may block other



You pointed out the way we deal with this in your original post: set a flag (make sure it's volatile) in the interrupt handler and handle it in a task. Unless you really, really know what you're doing and how all the software works in your system, this is the only practical way to handle this. If you try to do the amount of work and call the things you're calling from an interrupt handler, your program will malfunction and crash.






share|improve this answer























  • Yeah, just found out that you can't use interrupt to keep track of something consistently unless it's really urgent, and you need to spend minimal time on that state. Thanks for your input ! @JohnRomkey

    – Ricco Yudha
    Mar 25 at 22:06












  • @RiccoYudha, if you find my answer to be accurate then please accept it as the solution.

    – John Romkey
    Mar 26 at 3:21















0














When you call led_battery() from the interrupt handler, you're doing waaaaay too much work there.



The interrupt can interrupt anything that doesn't have interrupts locked out.



Suppose your code is outputting something using Serial and the timer interrupt happens. Now your code was running code somewhere inside Serial, and you call Serial again... while the software and hardware can be in inconsistent states.



This is the case with every subroutine and hardware access you do from an interrupt handler. The only way to protect against this is to disable interrupts whenever your code might be accessing hardware or might have modifying data structures.



Unfortunately, disabling interrupts is error-prone - if you forget to do it, you'll have mysterious crashes. If you forget to reenable them, you're in big trouble - your network, timers and Serial will all stop working. It also adds a lot of overhead to your code. And it degrades your overall system performance - it will delay or cause you to miss network and timer events. You may drop characters from the serial port. And you can be certain that none of the code in the Arduino Core is doing this for you.



So, long story short, locking out interrupts so that you can do a lot in an interrupt handler is just not practical.



You also want to minimize the time you spend in the interrupt handler, as this preempts network stack, timer, serial and other hardware processing and may block other



You pointed out the way we deal with this in your original post: set a flag (make sure it's volatile) in the interrupt handler and handle it in a task. Unless you really, really know what you're doing and how all the software works in your system, this is the only practical way to handle this. If you try to do the amount of work and call the things you're calling from an interrupt handler, your program will malfunction and crash.






share|improve this answer























  • Yeah, just found out that you can't use interrupt to keep track of something consistently unless it's really urgent, and you need to spend minimal time on that state. Thanks for your input ! @JohnRomkey

    – Ricco Yudha
    Mar 25 at 22:06












  • @RiccoYudha, if you find my answer to be accurate then please accept it as the solution.

    – John Romkey
    Mar 26 at 3:21













0












0








0







When you call led_battery() from the interrupt handler, you're doing waaaaay too much work there.



The interrupt can interrupt anything that doesn't have interrupts locked out.



Suppose your code is outputting something using Serial and the timer interrupt happens. Now your code was running code somewhere inside Serial, and you call Serial again... while the software and hardware can be in inconsistent states.



This is the case with every subroutine and hardware access you do from an interrupt handler. The only way to protect against this is to disable interrupts whenever your code might be accessing hardware or might have modifying data structures.



Unfortunately, disabling interrupts is error-prone - if you forget to do it, you'll have mysterious crashes. If you forget to reenable them, you're in big trouble - your network, timers and Serial will all stop working. It also adds a lot of overhead to your code. And it degrades your overall system performance - it will delay or cause you to miss network and timer events. You may drop characters from the serial port. And you can be certain that none of the code in the Arduino Core is doing this for you.



So, long story short, locking out interrupts so that you can do a lot in an interrupt handler is just not practical.



You also want to minimize the time you spend in the interrupt handler, as this preempts network stack, timer, serial and other hardware processing and may block other



You pointed out the way we deal with this in your original post: set a flag (make sure it's volatile) in the interrupt handler and handle it in a task. Unless you really, really know what you're doing and how all the software works in your system, this is the only practical way to handle this. If you try to do the amount of work and call the things you're calling from an interrupt handler, your program will malfunction and crash.






share|improve this answer













When you call led_battery() from the interrupt handler, you're doing waaaaay too much work there.



The interrupt can interrupt anything that doesn't have interrupts locked out.



Suppose your code is outputting something using Serial and the timer interrupt happens. Now your code was running code somewhere inside Serial, and you call Serial again... while the software and hardware can be in inconsistent states.



This is the case with every subroutine and hardware access you do from an interrupt handler. The only way to protect against this is to disable interrupts whenever your code might be accessing hardware or might have modifying data structures.



Unfortunately, disabling interrupts is error-prone - if you forget to do it, you'll have mysterious crashes. If you forget to reenable them, you're in big trouble - your network, timers and Serial will all stop working. It also adds a lot of overhead to your code. And it degrades your overall system performance - it will delay or cause you to miss network and timer events. You may drop characters from the serial port. And you can be certain that none of the code in the Arduino Core is doing this for you.



So, long story short, locking out interrupts so that you can do a lot in an interrupt handler is just not practical.



You also want to minimize the time you spend in the interrupt handler, as this preempts network stack, timer, serial and other hardware processing and may block other



You pointed out the way we deal with this in your original post: set a flag (make sure it's volatile) in the interrupt handler and handle it in a task. Unless you really, really know what you're doing and how all the software works in your system, this is the only practical way to handle this. If you try to do the amount of work and call the things you're calling from an interrupt handler, your program will malfunction and crash.







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 22 at 21:43









John RomkeyJohn Romkey

1,059176




1,059176












  • Yeah, just found out that you can't use interrupt to keep track of something consistently unless it's really urgent, and you need to spend minimal time on that state. Thanks for your input ! @JohnRomkey

    – Ricco Yudha
    Mar 25 at 22:06












  • @RiccoYudha, if you find my answer to be accurate then please accept it as the solution.

    – John Romkey
    Mar 26 at 3:21

















  • Yeah, just found out that you can't use interrupt to keep track of something consistently unless it's really urgent, and you need to spend minimal time on that state. Thanks for your input ! @JohnRomkey

    – Ricco Yudha
    Mar 25 at 22:06












  • @RiccoYudha, if you find my answer to be accurate then please accept it as the solution.

    – John Romkey
    Mar 26 at 3:21
















Yeah, just found out that you can't use interrupt to keep track of something consistently unless it's really urgent, and you need to spend minimal time on that state. Thanks for your input ! @JohnRomkey

– Ricco Yudha
Mar 25 at 22:06






Yeah, just found out that you can't use interrupt to keep track of something consistently unless it's really urgent, and you need to spend minimal time on that state. Thanks for your input ! @JohnRomkey

– Ricco Yudha
Mar 25 at 22:06














@RiccoYudha, if you find my answer to be accurate then please accept it as the solution.

– John Romkey
Mar 26 at 3:21





@RiccoYudha, if you find my answer to be accurate then please accept it as the solution.

– John Romkey
Mar 26 at 3:21



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55290996%2fesp32-deep-sleep-i2c-interrupt-problem%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript