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.
- #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