Hi, I am trying to make a function that blink a led half a second with an external interruption that displays something on a LCD.
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
const int Band=300;
long Time=0;
const byte interruptPin = 2;
const byte interruptPin2= 3;
volatile byte state = LOW;
const byte ledPin = 8;
void setup() {
// put your setup code here, to run once:
lcd.init();
lcd.backlight();
attachInterrupt(digitalPinToInterrupt(interruptPin2), blink1, CHANGE);
attachInterrupt(digitalPinToInterrupt(interruptPin), intent1, CHANGE);
pinMode(interruptPin, INPUT);
pinMode(ledPin,OUTPUT);
pinMode(7,OUTPUT);
}
void loop() {
int i=0;
// put your main code here, to run repeatedly:
for(i=0;i<=99;i++){
digitalWrite(7,HIGH);
delay(500);
digitalWrite(7,LOW);
delay(500);
}
}
void blink1() {
if(millis()-Time>Band){
state = !state;
Time=millis();
digitalWrite(ledPin,state);
}
}
void intent1(void) {
if(millis()-Time>Band){
lcd.setCursor(0,1);
lcd.print("I WORKED :)");
}
}
The blink part works well as the blink1 interruption, the problem comes when I push the button to activate intent 1, then the program freeze. I have identified that if I removed the lcd commands on the interruption it works.
What could be the problem? :c
Without looking any further, I see you are asking for an interrupt to occur every time a change occurs on those pins. Every time you push the button you get AT least TWO interrupts and if the switch bounces, many interrupts.
Paul
As @Whandall said you can't use anything that uses interrupts inside an ISR.
The Wire library uses interrupts. And while it uses interrupts it also polls flags set by an ISR (forever) waiting for certain things to complete.
So if you are inside an ISR and you call the lcd library which calls the Wire library, the Wire library gets stuck in an infinite loop waiting for a flag to get set by the Wire h/w ISR because interrupts are masked.
Thank both of you.
So this means that if for some case I want to write in my lcd inside the interruption function I need to use the lcd without the I2C, because the Wire library is used for the I2C communication, isn't it?
While it would probably work and block many pins, it's not a good idea.
The best ISRs just set some flags and gather information,
they do nothing that could be done later in normal mode,
or in a less elevated mode, if running on a more sophisticated processor like an ESP32.