ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ESP-IDF 디바운싱 (vscode)
    소프트웨어 2023. 3. 23. 23:56

    #esp32 윈도우 vscode 환경
    #선행(필수) ESP-IDF 윈도우 개발환경 세팅(VSCODE)
    #선행(필수) ESP-IDF 외부 폴더에서 예제 파일 실행(VSCODE)
    #선행(필수) ESP-IDF GPIO 인풋, 아웃풋(VSCODE)
    #선행(추천) ESP-IDF 인터럽트 (esp32, vscode)
    #선행(추천) FreeRTOS : Queue 포스트 예정


    1) 채터링
    스위치를 누를 때 한 번에 연결되는 것 같지만 실제로는 접점이 여러 번 붙었다 떨어졌다 하게 됩니다.
    채터링은 수 ms 내에 벌어지기 때문에 눈으로 감지를 못 하지만 ESP32는 이 신호들을 감지하게 됩니다. 
    이런 현상을 채터링 이라고 합니다.

     
     
    2) 디바운싱
    첫 신호를 받고, 매우 짧은 시간 안에 다시 들어온 신호를 채터링으로 간주하고
    받지 않도록 소프트웨어로 처리하는 것을 디바운싱이라고 합니다
     
     
    3) 코드

    #include <stdio.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "freertos/queue.h"
    #include "driver/gpio.h"
    
    #define PIN_SWITCH 17
    
    QueueHandle_t interruptQueue;
    
    static void IRAM_ATTR gpio_isr_handler(void *args)
    {
        int pinNumber = (int)args;
        xQueueSendFromISR(interruptQueue, &pinNumber, NULL);
    }
    
    void buttonPushedTask(void *params)
    {
        int pinNumber, count = 0;
        while (true)
        {
            if (xQueueReceive(interruptQueue, &pinNumber, portMAX_DELAY))
            {
                gpio_isr_handler_remove(pinNumber);
                do
                {
                    vTaskDelay(20 / portTICK_PERIOD_MS);
                } while(gpio_get_level(pinNumber) == 1);
                printf("GPIO %d was pressed %d times. The state is %d\n", pinNumber, count++, gpio_get_level(PIN_SWITCH));
                gpio_isr_handler_add(pinNumber, gpio_isr_handler, (void *)pinNumber);
            }
        }
    }
    
    void app_main()
    {
        gpio_set_direction(PIN_SWITCH, GPIO_MODE_INPUT);
        gpio_pulldown_en(PIN_SWITCH);
        gpio_pullup_dis(PIN_SWITCH);
        gpio_set_intr_type(PIN_SWITCH, GPIO_INTR_POSEDGE);
    
        interruptQueue = xQueueCreate(10, sizeof(int));
        xTaskCreate(buttonPushedTask, "buttonPushedTask", 2048, NULL, 1, NULL);
    
        gpio_install_isr_service(0);
        gpio_isr_handler_add(PIN_SWITCH, gpio_isr_handler, (void *)PIN_SWITCH);
    }

     
     gpio_isr_handler_remove(pinNumber);
                do
                {
                    vTaskDelay(20 / portTICK_PERIOD_MS);
                } while(gpio_get_level(pinNumber) == 1);
    이 부분이 디바운싱 부분 입니다.
    (1) 버튼을 누르면 인터럽트 함수로 들어와 큐로 버튼 GPIO 핀 번호를 넘깁니다.
    (2) 실행 중이던 buttonPushedTask  portMAX_DELAY에 의해 큐에 값이 있을 때 까지 기다리고 있었는데,
         마침 (1)에서 큐로 보내온 값을 확인하고 실행 됩니다.
    (3) 실행 되고 첫 줄의 gpio_isr_handler_remove(pinNumber);에 의해, 버튼 GPIO 핀의 인터럽트를 제거 합니다.
    (4) 버튼 GPIO 핀이 HIGH이니, vTaskDelay(20 / portTICK_PERIOD_MS); 이 실행되고 20ms 동안 버튼 GPIO 핀의 입력은 무시됩니다.
     
     

    *공부하는 입장에서 정리중인 자료들 입니다.


    ESP-IDF 윈도우 개발환경 세팅 (VSCODE)
    ESP-IDF 외부 폴더에서 예제 파일 실행 (VSCODE)
    ESP-IDF GPIO 인풋, 아웃풋 (VSCODE)
    ESP-IDF 인터럽트 (VSCODE)

    ESP-IDF 디바운싱 (esp32, vscode)
    ESP-IDF .c .h 참조 cMakeLists (vscode)

    ESP-IDF components 참조 cMakeLists (vscode)
    ESP-IDF LCD 출력(vscode)
    ESP-IDF 메모리 - Flash (vscode)
    ESP-IDF 메모리 - SRAM (vscode)
    ESP-IDF FreeRTOS - buffer (vscode)

    ESP-IDF 쿨링팬 FG센서, PWM제어(vscode)

     

     

    <포스트 예정>

    *ESP-IDF 메모리 - ROM
    *LCD - 메뉴 만들고 버튼으로 메뉴 이동(터미널로 작업)
    *LCD - 2차원 배열로 메뉴 진입, 뒤로가기(터미널로 작업)
    *LCD - 메뉴 만든 것 LCD 출력
    *LCD - 메뉴 UI 제작.  연두색 블럭은 메인 메뉴 회색 블럭은 서브 메뉴
            (1.팬  1-1.ON  1-2.OFF  1-3.BACK   2.LED  2-1.밝기 약  2-2.밝기 중  2-3.밝기 강   2-4.BACK   3.빛 밝기 출력 lux(+PPFD 변환)
    *Easy EDA툴 활용하여 커스텀 ESP32 보드 제작
    *LCD - LCD , 팬 , 펌프 ,  ESP32 연결 가능한 PCB 제작 주문.
    *LCD - 간이 스마트팜 제작
    *ESP32 JTAG 디버그
    *FreeRTOS
    *FreeRTOS - QUEUE
    *FreeRTOS - timer
    *FreeRTOS - Semaphore , mutex
    *FreeRTOS - event group , notification
    *FreeRTOS - buffer
    *ESP-IDF I2C SPI UART
    *ESP-IDF wifi
    *ESP-IDF MQTT
    *ESP-IDF Server (XAMPP 로컬 서버 연결)

    *DIY 컨테이너 / 유리온실 스마트팜 제작

     

     
     
Designed by PixelSpace