I'm trying to create a switch debounce that uses a task to handle the debounce delay rather than servicing all of the switch bounce interrupts. After the first switch interrupt, the interrupt is disabled then a semaphore is given to a task that delays for the debounce time then reads the switch state.
The code generally works well but making small changes to the code causes core 1 panic messages. In the vDebounceSwitch task, uncommenting the Serial.print line creates continuous panics. After removing the line the code may panic a few times on the restart but then works correctly.
Similarly, commenting out the attachInterrupt line has the same effect.
So I don't know if I have a fundamental flaw in the coding or my understanding of how the tasks are being processed.
Any comments appreciated.
Code included below along with panic error display.
Code: Untitled.cpp Select all
#include <Arduino.h>
#define SWITCH_PIN 5
#define DEBOUNCE_TIME 20 / portTICK_PERIOD_MS
bool switchClosed = false;
volatile SemaphoreHandle_t switchSemaphore = xSemaphoreCreateBinary();
void IRAM_ATTR handleSwitchISR() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
detachInterrupt(SWITCH_PIN);
xSemaphoreGiveFromISR(switchSemaphore, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
void vDebounceSwitch(void * pvParameters){
for ( ;; ) {
xSemaphoreTake(switchSemaphore, portMAX_DELAY);
//interrupt has occurred, wait for debounce time
vTaskDelay(DEBOUNCE_TIME);
//Serial.println("debounced");
//check switch state, pin High is switch Open
if (digitalRead(SWITCH_PIN)){
switchClosed = false;
} else {
switchClosed = true;
}
attachInterrupt(SWITCH_PIN, handleSwitchISR, GPIO_INTR_ANYEDGE);
}
vTaskDelete( NULL );
}
void vPrintSwitchStatus(void * pvParameters){
bool prevSwitchState = false;
for ( ;; ) {
if (prevSwitchState != switchClosed){
if (switchClosed){
Serial.println("...OPEN");
} else {
Serial.println("CLOSED");
}
prevSwitchState = switchClosed;
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
vTaskDelete( NULL );
}
void setup() {
Serial.begin(115200);
pinMode(SWITCH_PIN, INPUT_PULLUP);
attachInterrupt(SWITCH_PIN, handleSwitchISR, GPIO_INTR_ANYEDGE);
xTaskCreate(vDebounceSwitch, "", 1000, NULL, 2, NULL);
xTaskCreate(vPrintSwitchStatus, "", 1000, NULL, 1 , NULL);
Serial.println("Setup Complete");
vTaskStartScheduler();
}
void loop() {}
Code: Select all
Rebooting...
ets Jul 29 2019 12:21:46
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:12784
load:0x40080400,len:3032
entry 0x400805e4
Setup Complete
Guru Meditation Error: Core 1 panic'ed (Unhandled debug exception).
Debug exception reason: BREAK instr
Core 1 register dump:
PC : 0x40083ef8 PS : 0x00020016 A0 : 0x40080306 A1 : 0x3ffb2770
A2 : 0x00000005 A3 : 0x400ecb94 A4 : 0xb33fffff A5 : 0x3ffbdb8c
A6 : 0x3ffb9114 A7 : 0x00000000 A8 : 0x800d3379 A9 : 0x00000000
A10 : 0x00000000 A11 : 0x00000000 A12 : 0xb33fffff A13 : 0x00060c23
A14 : 0x00000002 A15 : 0x00000000 SAR : 0x00000038 EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0xb33fffff LCOUNT : 0x00000000