이번에는 간단하게 GPIO를 테스트 해보도록 하자. 일반적으로 ESP32는 핀이 그리 많지 않다. 그래서 하나의 핀이 여러가지 기능으로 동작할 수 있다. 앞서 UART 통신에서도 해당 핀을 RX와 TX핀으로 설정하여 사용했던것을 기억해보자. 마찬가지로 이제 우리는 LED를 끄거나 켜고자 한다. 우리가 사용하는 것이 단지 LED일뿐, 실제로 해당 핀에 Low나 High값이 출력될 뿐이다. 그리고 그 단순한 GPIO는 다양한 형태로 하드웨어에 적용되어 사용된다. 이런 부분은 나중에 일하면서 느끼게 될것이다. 여기에서는 내가 정한 특정핀을 GPIO(General Purpose Input Outout)으로 설정하여 출력으로 설정후 LED를 켜보는 것만 생각하도록 하자. 

     

    --- contents ---

    1. [ESP32] VS Code 개발환경 구성 : https://makeutil.tistory.com/303

    2. [ESP32] 첫 프로젝트 생성하기 : https://makeutil.tistory.com/304

    3. [ESP32] 멀티 테스크 예제 (2 Task) : https://makeutil.tistory.com/305

    4. [ESP32] Task간 데이터 공유 (Queue, Mutex) : https://makeutil.tistory.com/306

    5. [ESP32] 개발보드 별 형상 및 I/O (ESP32/ESP32-S3) : https://makeutil.tistory.com/307

    6. [ESP32] UART 통신 예제 #1 : https://makeutil.tistory.com/309 

    7. [ESP32] UART 통신 예제 #2 : https://makeutil.tistory.com/313

    8. [ESP32] GPIO LED 켜기 : (현재글)

     

    A1. [ESP32] 오류 - Fatal Error : No such file or directory : https://makeutil.tistory.com/308

    ------------------

     

     

    회로를 모두 다 그려서 하면 좋겠지만, 필자는 간단하게 테스트 하려고 LED에 점퍼케이블을 잘라 붙혀서 LED를 만들었다.다. 적색 선에는 330옴 저항을 하나 넣었다. 따라서 켜는 방법은 2가지다. GPIO로 설정할 핀에 적색을 연결하고, 그라운드에 검정색을 연결하거나, 아니면 3.3v에 적색을 연결후 GND를 GPIO에 연결해도 간단하게는 시험을 할 수 있다.  다만 3.3V에 연결할 경우 GPIO가 0이될 때 점등되고, GPIO에 적색을 연결하고 GND에 연결했을 땐, 1이될 때 점등된다. 

     

    우선 첫번째로는 app_main()에서 LED를 켜보고, 다음에는 테스크를 2개를 만들어서 시험 해보도록 하자.

     

    1. GPIO LED 점멸

      간단하게 GPIO를 출력으로 설정하여 LED를 1초 단위로 점등해 보도록 하자. 

    1.1. 소스코드

      소스코드는 간단하다. 원하는 핀을 결정하고, gpio_reset_pin, gpio_set_direction을 통해서 GPIO로 지정하고 출력으로 설정한다. 다음은 while()을 돌면서 상태를 변경하고 출력하면 된다. 

    #include <stdio.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "driver/gpio.h"
    
    #define LED_PIN 10  // GPIO 번호
    
    void app_main(void)
    {
        // 상태변경용 변수
        uint32_t stat=0;
        
        // 핀을 초기화하고 GPIO핀 모드를 출력으로 설정한다.
        gpio_reset_pin(LED_PIN);  
        gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
    
        while (1) 
        {
            if(stat!=0)  // 상태 변경용 조건
                stat=0;  // 1이 입력되면 0으로
            else 
                stat=1;
    
            // LED 점등 또는 소등
            gpio_set_level(LED_PIN, stat);
            vTaskDelay(pdMS_TO_TICKS(1000)); // 1초 대기
        }
    }

     

     

    1.2. 실행결과

      실행결과는 다음과 같다. 필자가 사진을 잘 찍었다고 생각했지만, 그리 밝게 표시되지 않는다. GPIO에 330옴 저항을 썼더니 좀 어두운것 같다. 그래도 자세히 보면 그럭저럭 보인다. 좌측은 꺼졌을 때, 우측은 켜졌을 때가 되겠다. 

     

     

    2. 멀티 Task에서 LED 점멸

      멀티 태스크를 이용해서 2개의 태스크에서 LED를 점등 및 소등 해보자. 

    2.1. 소스코드

      이제 태스크 2개에서 적색 LED와 황색 LED를 동작시키려한다. 적색은 기존의 GPIO 10번이고, 황색은 GPIO 11번을 사용하도록 코드를 추가한다.

    #include <stdio.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "driver/gpio.h"
    
    #define LED1_PIN 10  // GPIO 10번
    #define LED2_PIN 11  // GPIO 11번
    
    void led1_task(void *arg)
    {
        uint32_t stat = 0;
    
        while (1) 
        {
            stat ^= 1;
            gpio_set_level(LED1_PIN, stat);
            vTaskDelay(pdMS_TO_TICKS(1000));  // 1초 대기
        }
    }
    
    void led2_task(void *arg)
    {
        uint32_t stat = 0;
    
        while (1) 
        {
            stat ^= 1;
            gpio_set_level(LED2_PIN, stat);        
            vTaskDelay(pdMS_TO_TICKS(500));  // 500ms 대기
        }
    }
    
    void app_main(void)
    {
        // GPIO 초기화
        gpio_reset_pin(LED1_PIN);
        gpio_set_direction(LED1_PIN, GPIO_MODE_OUTPUT);
        gpio_reset_pin(LED2_PIN);
        gpio_set_direction(LED2_PIN, GPIO_MODE_OUTPUT);
    
        // 태스크 생성
        xTaskCreate(led1_task, "led1_task", 1024, NULL, 5, NULL);
        xTaskCreate(led2_task, "led2_task", 1024, NULL, 5, NULL);
    }

     

     

    2.2. 결과확인

    결과야 뭐 별거 있겠는가. 적색은 1초단위 점멸, 황색은 0.5초 단위로 점멸한다. 

     

     

    3. 주기측정

      그러면 실제 타이밍이 제대로 나와있는지 확인해보도록 하자. GPIO10은 보라색, GPIO11은 파란색으로 표시된다.

     

    3.1. GPIO 10번 (1000ms)

      아래의 데이터를 보면 클록은 길이는 1초이고, 주기는 약 2초에 해당된다. 그리고 아래의 파란색의 경우 절반인 500ms로 동작한다. 

     

    3.2. GPIO 11번 (500ms)

       11번 데이터를 ㄹ보면 약 500ms이고, 주기는 1s임을 알수있다. 

     

     

    시간이 남는 독자들은 Timer를 이용하여 처리하는 것도 한번 해보시기 바란다. 

    반응형
    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기