I want to use interrupts on my ESP 8266 to monitor the digital outputs of a power meter and water meter.
The idea is to increment a counter in the ISRs and at some point to take the value of the counter and to set the counter back to 0 in the loop() function. I've red about critical sections, noInterrupts() and interrupts() and then I started to wonder if an ISR will be executed while the code is between noInterrupts() and interrupts(). On theory it should be because the interrupt flag in the chip will be raised and the ISR will be invoked after the code exits the critical section. I wrote a program to test it, but my findings prove the opposite.
#include <Arduino.h>
#define REPORT_TIME 5000
#define INTERRUPT_PIN D1
unsigned long base_time;
volatile unsigned int interrupt_counter = 0;
void IRAM_ATTR isr() {
interrupt_counter++;
}
void setup() {
Serial.begin(115200);
// The interrupt will be FALLING EDGE
pinMode(INTERRUPT_PIN, INPUT_PULLUP);
pinMode(LED_BUILTIN_AUX, OUTPUT);
digitalWrite(LED_BUILTIN_AUX, HIGH);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), isr, FALLING);
base_time = millis();
}
bool written = false;
void loop() {
if (!written)
{
written = true;
for (int i = 0; i < 100; i++)
{
digitalWrite(LED_BUILTIN_AUX, LOW);
digitalWrite(LED_BUILTIN_AUX, HIGH);
}
}
unsigned long time_now = millis();
if (time_now - base_time >= REPORT_TIME)
{
written = false;
base_time = time_now;
unsigned int interrupt_counter_local;
//Guard the critical section
noInterrupts();
interrupt_counter_local = interrupt_counter;
interrupts();
digitalWrite(LED_BUILTIN_AUX, LOW);
digitalWrite(LED_BUILTIN_AUX, HIGH);
Serial.print("counter ");
Serial.println(interrupt_counter_local);
Serial.println();
}
}
Using a wire I attached the pin of the builtin led to the interrupt pin and in the serial monitor I could see the values are:
counter 100
counter 201
counter 302
When I modify the critical section to be like:
noInterrupts();
interrupt_counter_local = interrupt_counter;
digitalWrite(LED_BUILTIN_AUX, LOW);
digitalWrite(LED_BUILTIN_AUX, HIGH);
interrupts();
I expect the same output as above but the values are:
counter 100
counter 200
counter 300
Am I missing something or the interrupts doesn't work as I expect?