-->
Page 1 of 2

NodeMCU and Interrupt

PostPosted: Mon Mar 12, 2018 5:53 am
by avaccaro
I am experiencing a strange behavior using interrupts on a NodeMCU.

I simply connected an LED + resistor on digital port D5 and I was trying to make it blink when I receive an interrupt on another pin.

Here the code:

Code: Select all
const int ch0 = D5;
const byte interruptPin1 = D1;

const int triggertime = 1000;

int triggers = 0;

void sendPulse(int chan){
  digitalWrite ( chan, HIGH );
  delay (triggertime);
  digitalWrite ( chan, LOW );   
  triggers ++;
  Serial.print("Got trigger ");
  Serial.println(triggers);
}

void handleInterrupt() {
  Serial.println("Got interrupt 1"); 
  sendPulse(ch0);
}

void setup() {
 
  pinMode ( ch0, OUTPUT );
  digitalWrite ( ch0, LOW );
  Serial.begin ( 115200 );

  pinMode(interruptPin1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), handleInterrupt, FALLING);
 
}

void loop() {
 
}



I attached a button to digital pin D1 and I would like to see the LED turn on for 1 second when the button is pressed.
I don't actually care of how many interrupts get triggered: I only want that when the button is pressed the LED gets powered for 1 second.

Everything works fine for a few clicks, then the LED does not turn on any longer when I press the key, while on the serial monitor I still see that the code is fully executed (interrupts detected and handlers processed).

What am I doing wrong?

Re: NodeMCU and Interrupt - SOLVED

PostPosted: Tue Mar 13, 2018 2:24 am
by avaccaro
I found that the issue was due to the use of the delay function in my sendPulse code.
Using delayMilliseconds instead everything works fine.

Re: NodeMCU and Interrupt

PostPosted: Wed Mar 14, 2018 8:12 pm
by tele_player
It’s still not a good idea to delay in an interrupt handler. Safer to set a variable in the handler, and have loop() check the variable to see if button was pressed.

Re: NodeMCU and Interrupt

PostPosted: Thu Mar 15, 2018 2:09 am
by reaper7
as @tele_player wrote, inside interrupt handle set only flag

Code: Select allvolatile bool myintflag = false;

void handleInterrupt() {
  if ( myintflag == false ) // optional: only when the previous call has been fully handled in loop
    myintflag = true;       // mandatory: set flag
}

void loop() {
  if ( myintflag == true ) {
    Serial.println("Got interrupt 1");
    sendPulse(ch0);
    myintflag = false;     // mandatory: reset flag
  }
}