ESP8266 external interrupt doubt

Hi,

I am studing ESP8266 (ESP12F) and got a problem when I try to use external interrupt. I connect a push button on a GPIO12 and upload a simple code, but the led on blink without press the button.

The code is this:

const byte pin = 12;
const byte led = 2;

volatile byte state = LOW;

void setup() {
  pinMode(led, OUTPUT);
  pinMode(pin, INPUT);

  digitalWrite(led, state);
  
  attachInterrupt(digitalPinToInterrupt(pin), handleLed, CHANGE);
}

void loop() {
  delay(100);
}

void handleLed() {
  state = !state;
  digitalWrite(led, state);
}

in a other hand this code works very well:

const byte pin = 12;
const byte led = 2;

volatile byte state = LOW;

void setup() {
  pinMode(pin, INPUT);
  pinMode(led, OUTPUT);
  
  digitalWrite(led, state);
} 

void loop() {

  if (digitalRead(pin) == LOW) {
    state = !state;
    digitalWrite(led, state);
    delay(100)    
  }

    delay(100);
}

So, I believe the hardware is OK, but I dont know what I am doing wrong with the external interrupt.

Any suggestion is welcome ;)

Thanks, Felipe

Several problems. 1) don't use interrupts for button presses (unless it's just an experiment to know about interrupts). 2) you don't debounce the button in the first code (with interrupts): in the second you have a delay(100) after reading the button, which takes care of that. 3) the second code will not switch on the LED, it will blink it very fast while you hold the button pressed. It will look like it's on, in 50% of the cases it will remain on when you release the button. Is that really what you intend to do? 4) you don't use the ICACHE_FLASH_ATTR flag on the ISR function. You must have an older ESP core, as the latest ones enforce this. This will lead to occasional crashes. Also I do assume you have an external pull-up resistor in place, as you don't use the internal ones. That will also give rise to spurious triggers.

wvmarle:
Several problems.

  1. don’t use interrupts for button presses (unless it’s just an experiment to know about interrupts).
  2. you don’t debounce the button in the first code (with interrupts): in the second you have a delay(100) after reading the button, which takes care of that.
  3. the second code will not switch on the LED, it will blink it very fast while you hold the button pressed. It will look like it’s on, in 50% of the cases it will remain on when you release the button. Is that really what you intend to do?
  4. you don’t use the ICACHE_FLASH_ATTR flag on the ISR function. You must have an older ESP core, as the latest ones enforce this. This will lead to occasional crashes.
    Also I do assume you have an external pull-up resistor in place, as you don’t use the internal ones. That will also give rise to spurious triggers.

what will be effect if we increase the time from 100 to 2000 …
the as it will stay on one position?

In the first sketch (wiht interrupt): no change. The second: you'll see a slower blink. Try it!

wvmarle: Several problems. 1) don't use interrupts for button presses (unless it's just an experiment to know about interrupts). 2) you don't debounce the button in the first code (with interrupts): in the second you have a delay(100) after reading the button, which takes care of that. 3) the second code will not switch on the LED, it will blink it very fast while you hold the button pressed. It will look like it's on, in 50% of the cases it will remain on when you release the button. Is that really what you intend to do? 4) you don't use the ICACHE_FLASH_ATTR flag on the ISR function. You must have an older ESP core, as the latest ones enforce this. This will lead to occasional crashes. Also I do assume you have an external pull-up resistor in place, as you don't use the internal ones. That will also give rise to spurious triggers.

wvmarle, thanks for the answer !

1) Yes, it is only to understand the interrupts. I tried to do a minimal code as possible. In a real life, a TTL circuit will trigger the interrupt

2) In this case (push button), ok I will debounce the button. For a real life TTL signal trigger, will I need to do something similar?

3) Yes, if I keep hold the button the led blinks and the final state is aleatory (50%).

3.1) For the first code (interrupt) I expect only change the led state when I press the button and when I Release the button, because the interrurt is configured to trigger on CHANGE pin state. Is this correct?

4) I don't know about ICACHE_FLASH_ATTR , I will look for more information abou it.

5) Yes, I have an external pull-up resistor on VCC with button trigger on GND.

Regards! Felipe

felipeksw: 3.1) For the first code (interrupt) I expect only change the led state when I press the button and when I Release the button, because the interrurt is configured to trigger on CHANGE pin state. Is this correct?

It would be - except that buttons bounce, so you get lots of triggers. Maybe so fast you miss a change (interrupts do take time to run, even if not much). To debounce, add a small cap (10-100 nF) parallel to the button. Electronic signals normally do not bounce.

4) I don't know about ICACHE_FLASH_ATTR , I will look for more information abou it.

It's ESP8266 specific; forcing the ISR to be kept in the processor's working memory. Otherwise especially in larger sketches it may be flushed releasing this icache memory for other uses. Then when the ISR gets called it's not available in memory, resulting in a crash. That's basically what's going on.