Use interrupts correctly!
by Edi · 29/05/2023
What is an interrupt?
When an interrupt occurs, the microprocessor stops the execution of the current program and jumps to a predefined interrupt service routine (ISR). The ISR is a special section of code that performs the tasks required for the interrupt. This can be, for example, reading data from an input device, updating a timer or processing a hardware error.
There are different types of interrupts, including hardware interrupts and software interrupts. Hardware interrupts are triggered by external events, such as keystrokes. Software interrupts are activated by special commands in the program code to execute or communicate certain actions.
After the ISR is completed, the microprocessor returns to the interrupted program sequence and continues execution with the next command.
The Interrupt Service Routine (ISR)
The ISR should be kept as short as possible to ensure that the normal program sequence can be resumed quickly. Long ISRs can lead to delays in the system and impair the responsiveness of the microprocessor. Therefore, as a rule, only the absolutely necessary tasks are executed within the ISR. More complex tasks or time-consuming operations are normally carried out outside the ISR.
The syntax for the ISR function is as follows.
IRAM_ATTR void ISR() {
ISR Funktion;
}
There are a few rules for the ISR that should be followed.
- Do not use delay(), micros() or millis() function
- Only use global variables that are declared as volatile.
- No serial library, so do not use output on the serial monitor
- Ensure that the pin used is an interrupt pin
Trigger the interrupt service routine
To trigger the interrupt service routine, we use the attachInterrupt() function in the setup() section. The interrupt can be deactivated with detachInterrupt(). The attachInterrupt() function requires three parameters.
The first parameter is the interrupt number. With digitalPinToInterrupt(), the number of the digital pin to which the button is attached is used.
The second parameter is the name of the interrupt service routine that is called when the interrupt is triggered.
The third parameter is the interrupt mode. The interrupt mode defines the type of signal that triggers the interrupt. There are four different interrupt modes:
• LOW - the interrupt is triggered when the interrupt pin is LOW
• RISING - the interrupt is triggered when the signal goes from LOW to HIGH
• FALLING - the interrupt is triggered when the signal goes from HIGH to LOW
• CHANGE - the interrupt is triggered when the signal changes either from HIGH to LOW or from LOW to HIGH
attachInterrupt(digitalPinToInterrupt(buttonPin), ISR_button, CHANGE);
The hardware interrupt
In this example, we use a Wemos d1 mini, which switches an LED on and off via a pushbutton. An interrupt is used to check whether the button is pressed and the button is also debounced. The button is connected to GPIO D1 and the LED is switched via D2.
const byte buttonPin = 5; //D1
const byte LEDPin = 4; //D2
byte lastButtonState = 0;
const int debounceTime = 30; // millis
byte toggleState = 0;
unsigned long lastButtonTimeChange = 0;
volatile int buttonFlag;
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(LEDPin, OUTPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), ISR_button, CHANGE);
}
IRAM_ATTR void ISR_button() {
buttonFlag = 1;
}
void loop() {
if (millis() - lastButtonTimeChange > debounceTime && buttonFlag) {
lastButtonTimeChange = millis();
if(digitalRead(buttonPin) == 0 && lastButtonState == 1){
toggleState =! toggleState;
digitalWrite(LEDPin, toggleState);
lastButtonState = 0;
}
else if(digitalRead(buttonPin) == 1 && lastButtonState == 0) {
lastButtonState = 1;
}
buttonFlag = 0;
}
}
The software interrupt
const byte LEDPin = 4; //D2 - Wemos d1 mini
byte toggleState = 0;
long previousMillis = 0;
long interval = 1000; // 1000 Millisekunden = 1 Sekunde
void setup() {
Serial.begin(115200);
pinMode(LEDPin, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
toggleState =! toggleState;
digitalWrite(LEDPin, toggleState);
}
}
Letzte Aktualisierung am 2024-09-09 / Affiliate Links / Bilder von der Amazon Product Advertising API