이 블로그는 Web 환경을 이용한 원격 제어 기술에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 WiFi Module과 Raspberry Pi, Raspberry Pi Pico, ATmega128 보드, Arduino Mega 보드(ATmega2560)를 사용 합니다.

timer-pwm-arduino

ESP8266/ESP32 Timer와 PWM - Arduino
ESP8266/ESP32 Timer와 PWM(Pulse width modulation) - Arduino


  • Arduino에서 사용하는 시간(Time)에 관계되는 기본함수(Basic functions)
    • Arduino 프로그램에서 사용하는 시간(Time)에 관계되는 기본함수(Basic functions)
    • Arduino 기본함수는 대부분의 프로세서에서 Hardware timer를 사용하지 않고 프로세서에 별도로 내장된 RTC(Real Time Clock) counter를 이용하여 구현된다.

      참고자료: ATmega128에서 RTC를 구현(ATmega128에는 별도의 RTC counter가 없기 때문에 Timer0를 이용함)하는 예 "Real time clock(Timer를 이용)를 이용한 Time delay"

      • millis()
        • 이 함수는 Arduino 보드가 현재 프로그램을 실행하기 시작한 이후 경과된 milliseconds 수를 반환한다.
        • 이 숫자는 약 50일 후에 Overflows(rolls back to zero) 된다.
        • micros가 반환하는 값은 unsigned long int 이다.
        • 사용 예
        • unsigned long time;

          time = millis();

      • micros()
        • 이 함수는 Arduino 보드가 현재 프로그램을 실행하기 시작한 이후 경과된 microseconds 수를 반환한다.
        • 이 숫자는 약 70분 후에 Overflows(rolls back to zero) 된다.
        • micros가 반환하는 값은 unsigned long int 이다.
        • 사용 예
        • unsigned long time;

          time = micros();

      • delay(value)
        • value 값(milliseconds) 만큼 프로그램을 일시 지연(중지)하는 함수이다.
      • delayMicroseconds(value)
        • value 값(microseconds) 만큼 프로그램을 일시 지연(중지)하는 함수이다.
    • Arduino 기본 시간 함수(Basic time functions)를 이용한 LED 점멸 주기 제어
      • 이 예는 Arduino 기본 시간 함수(Basic time functions)를 이용한 LED 점멸 주기 제어 예이다.

        LED는 개발보드(GPIO2)에 내장된 LED를 이용한다. 회로 구성을 위한 개발보드 Pin 배열은 "ESP8266/ESP32 개발보드 Pin"을 참고하기 바람.

        실험 회로 구성 예

      • LED 점멸 주기 제어 프로그램 예: led-period-control-basic.ino
      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 위 "실험 회로 구성 예"와 같이 GPIO4와 GPIO5에 switch를 연결한다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "led-period-control-basic.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면(NodeMCU ESP8266 개발보드는 GPIO0를 프로그램에서 제어하기 때문에 GPIO0 SW를 누르지 않아도 됨) 개발 보드에 업로드가 시작된다.
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "업로드 완료" 매세지가 출력되고 프로그램이 시작되어 LED가 2Sec 간격으로 점멸한다.
          • "툴 -> 시리얼 모니터"를 실행하면 시리얼 모니터 창이 열리고 Interval 값이 출력된다. 필요한 경우 보드레이트를 115200로 설정한다.
          • "GPIO4" Switch을 누르면 Interval 값이 작아지고 LED의 점멸 속도가 빨라진다.
          • "GPIO5" Switch을 누르면 Interval 값이 커아지고 LED의 점멸 속도가 느려진다.

          주: Switch의 Bouncing 현상으로 Switch을 한번 눌러도 두번 또는 세번 누른 것과 같은 결과가 발생할 수 있다.


    • Switch에서 발생하는 Bouncing 문제
      • 아래 그림은 Switch의 금속 접점이 이상적이지 않기 때문에 Switch를 Closed 하거나 Open 하는 순간에 발생하는 Bouncing 현상 예 이다. Bouncing은 Switch의 상태에 따라 대략 5mSec - 16mSec 사이에 발생 한다.

        소프트웨어로 Bouncing 문제를 해결(Debouncing) 하는 방법은 처음 Switch 누름을 인지한 다음 약 15mSec - 20mSec 후, Switch 상태를 다시 확인하여 이 때 까지 누름 상태가 지속되는 경우 누름 상태로 판단한다.

      • SW의 Bouncing 현상을 관찰하기 위한 프로그램 예: sw-counter-bouncing.ino
        • 이 프로그램은 Switch를 사용할 때 발생하는 Bouncing 현상을 관찰하기 위한 프로그램이다.

          Bouncing 현상을 관찰하기 위하여 Switch Input port에 GPIO Interrupt를 사용하고, 빠른 ISR의 실행을 위하여 ISR 내 Code의 길이을 짧게 작성하였다.

      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 위 "실험 회로 구성 예"와 같이 GPIO4에 switch를 연결한다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "sw-counter-bouncing.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면(NodeMCU ESP8266 개발보드는 GPIO0를 프로그램에서 제어하기 때문에 GPIO0 SW를 누르지 않아도 됨) 개발 보드에 업로드가 시작된다.
          • "툴 -> 시리얼 모니터"를 실행하면 시리얼 모니터 창이 열린다. 필요한 경우 보드레이트를 115200로 설정한다.
          • "GPIO4" Switch을 누르면 counter 값이 1씩 증가하고 결과가 시리얼 모니터 창에 출력되고, 개발 보드의 LED가 Toggle 된다.

          주: Switch의 Bouncing 현상으로 Switch을 한번 눌러도 두번 또는 세번 누른 것과 같은 결과가 발생할 수 있다.


      • Software에 의한 SW Debouncing 프로그램 예: sw-counter-soft-debouncing.ino
        • 이 프로그램은 Software를 사용한 Debouncing 프로그램이다. Software debouncing 기술을 사용하기 때문에 프로그램이 효율적이지는 않지만 Debouncing 기술을 이해하는데는 유용한 방법이다.

      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 위 "실험 회로 구성 예"와 같이 GPIO4에 switch를 연결한다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "sw-counter-soft-debouncing.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면(NodeMCU ESP8266 개발보드는 GPIO0를 프로그램에서 제어하기 때문에 GPIO0 SW를 누르지 않아도 됨) 개발 보드에 업로드가 시작된다.
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "툴 -> 시리얼 모니터"를 실행하면 시리얼 모니터 창이 열린다. 필요한 경우 보드레이트를 115200로 설정한다.
          • "GPIO4" Switch을 누르면 counter 값이 1씩 증가하고 결과가 시리얼 모니터 창에 출력되고, 개발 보드의 LED가 Toggle 된다.

          주: Bouncing 문제가 해결 되었으면 버튼을 누를 때 마다 카운터 값이 1 씩 증가 하여야 한다.


  • ESP8266/ESP32 Timer와 Timer interrupt
    • ESP8266는 Hardware timer보다 시간(Time) 함수를 사용하는 것이 일반적이기 때문에 여기서는 ESP32 Hardware timer에 대하여만 설명한다.

      Hardware Timer 이해에 도움이되는 참고자료: "ATmega128 timer"

    • Hardware Timer
      • ESP8266 Hardware timer
        • ESP8266 보드는 2개의 Timer(Timer0, Timer1)가 있지만 Timer0는 WiFi function에서 사용하기 때문에 WiFi를 사용하는 경우 Timer1만 사용할 수 있다.
        • ESP8266 Hardware timer interrupt 참고자료: "ESP8266 TimerInterrupt"

      • ESP32의 Hardware timer
        • ESP32에는 두 개의 Hardware timer 그룹이 있고, 각 그룹에는 2개의 범용 Hardware timer가 있기 때문에 ESP32에는 0-3으로 번호가 매겨진 총 4개의 Timer가 있다.
        • ESP32의 Hardware timer는 모두 일반 64비트 기반 Timer 이다.
        • 각 Timer에는 16-bit Prescaler(2 ~ 65536)가 있고,
        • 자동으로 다시 로드(Automatically reloaded)할 수 있는,
        • 64비트 오름차순/내림차순 카운터(Ascending/Descending counters)가 있다.
      • Timer interrupt를 사용하는 프로그램 작성시 고려하여야하는 사항
        • Timer interrupt ISR 내에는 가능한 빠르게 실행되는 코드(변수 값의 update 등)만 포함하여야 한다. 속도가 느린 코드(Serial port를 이용한 통신 등)는 Arduino 프로그램인 경우 loop()에서 처리하는 것이 바람직하다.
        • Timer interrupt ISR은 Timer interrupt이 발생하면 바로 시작된다. 실제 ISR 내에 있는 Code의 실행 시간은 Interrupt mode에 따라 다르다. One-shot mode인 경우 지정된 시간 후에 Code가 실행된다.
        • ESP32에 있는 4개의 타이머는 서로 다른 별도의 Timer interrupt ISR를 실행할 수 있다.
        • volatile로 선언된 변수의 내용을 Interrupt ISR에서 공유할 수 있다.
      • Prescaler (Time divider) 와 Tics
        • Timer는 Processor clock를 사용하여 경과 시간을 계산한다. ESP32의 Clock 주파수는 80MHz 이다.
        • ESP32 Timer는 64비트 Counters와 16비트 Prescaler(Time dividers)를 기반으로 한다.
        • Prescaler는 기본 신호의 주파수(ESP32의 경우 80MHz)를 나누는 데 사용되며, Prescaler의 출력은 Timer counter의 입력(Timer counter를 Up/Down 하는 Clock)으로 사용된다.
      • ESP32를 사용하는 Arduino project에서 Timer 사용하기
        • Timer를 구성하려면 아래 예와 같은 hw_timer_t 유형의 변수 포인터가 필요하다.
        • hw_timer_t * timer = NULL;

        • 아래 예와 같이 timerbegin(id, prescaler, flag) 함수를 사용하여 Timer를 초기화한다.
        • timer = timerBegin(0, 80, true);

          • 위 예는 id(Timer 번호)가 0 이고,
          • prescaler 값이 80 이고,
          • flag 값이 true인 경우 Up count로 동작하고, false 인 경우에는 Down count로 동작한다.
        • Timer를 활성화하기 전에 timerAttachInterrupt(timer, function, trigger) 함수를 사용하여 인터럽트가 트리거될 때마다 실행될 함수(ISR)를 설정하여야 한다. 이 메서드에는 세 가지 매개변수를 필요로 한다.
          • timer: timer는 timerBegin() 함수에 의하여 생성된 Timer의 포인터이다.
          • function: Timer가 Triggered 될때 실행되는 함수(ISR)이다.
          • trigger: Timer clock에 동기되어 Trigger가 발생하는 조건을 설정한다.
          • trigger는 아래 2가지 중 한 Type으로 설정한다.

            • true: Timer 가 Rising edge에서 trigger 된다.
            • false: Timer clock 신호 Level이 변경될 때 trigger 된다.
        • Timer alarm 설정 함수: timerAlarmWrite(timer, alarm_value, autoreload)
          • timer: timer는 timerBegin() 함수에 의하여 생성된 Timer의 포인터이다.
          • alarm_value: Trigger 발생에 필요한 Timer의 clock(Tic) 수를 설정한다.
          • autoreload: Trigger가 발생한 다음 Timer의 Counter에 초기값의 자동 Load 여부를 설정한다.
            • true: Trigger가 발생한 다음 Timer의 Counter에 초기값의 자동으로 Load 된다. 이 경우 Timer는 일정한 주기마다 Trigger가 발생(Period mode)한다.
            • false: Trigger가 발생한 다음 Timer의 Counter에 초기값의 Load 되지 않는다. 이 경우 Timer는 일정한 시가 후에 한번만 Trigger가 발생(One-shot mode)한다.
        • Start alarm method의 예는 아래와 같다.
          • timerAlarmEnable(timer);

        • Disable alarm method의 예는 아래와 같다.
          • timerAlarmDisable(timer);


    • 주기적인 Timer interrupt를 이용한 LED 점멸 주기 제어
      • ESP32 Hardware timer를 사용하여 일정한 주기를 발생시키는 프로그램 예: ESP32-led-period-control-timer.ino

      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 위 "실험 회로 구성 예"와 같이 GPIO4에 switch를 연결한다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "led-period-control-timer.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면 개발 보드에 업로드가 시작된다.
          • 프로그램이 시작되면 LED가 1초에 한번씩 점멸 된다.
          • "GPIO4" Switch을 누르면 timerAlarmDisable() 함수가 실행되어 LED의 점멸이 정지 된다.

    • Hardware timer의 One-shot mode를 이용한 Debouncing
    • 이 예는 Timer를 이용하여 일정한 시간 후에 Trigger를 발생(One-shot interrupt)하는 방법을 이해하기 위한 것이다. 이 예는 일정한 시간이 지난 다음 발생하는 Trigger를 이용하여 스위치에서 발생하는 Bouncing 문제를 해결(Debouncing) 하는 예 이다.

        ESP32 Hardware timer의 One-shot mode를 이용한 Debouncing 프로그램 예: ESP32-sw-counter-timer-debouncing.ino

      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 위 "실험 회로 구성 예"와 같이 GPIO4에 switch를 연결한다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "sw-counter-timer-debouncing.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면 개발 보드에 업로드가 시작된다.
          • "툴 -> 시리얼 모니터"를 실행하면 시리얼 모니터 창이 열린다. 필요한 경우 보드레이트를 115200로 설정한다.
          • "GPIO4" Switch을 누르면 counter 값이 1씩 증가하고 그 결과가 시리얼 모니터 창에 출력되고, 개발 보드의 LED가 Toggle 된다.

          주: Bouncing 문제가 해결 되었으면 버튼을 누를 때 마다 카운터 값이 1 씩 증가 하여야 한다.


    • Hardware timer의 One-shot mode를 이용한 장치 제어
      • 이 예는 Timer를 이용하여 일정한 시간 후에 장치가 동작(One-shot interrupt)하도록 제어하는 예 이다. 이 예는 일정한 시간이 지난 다음 장치가 동작하여 설정한 시간 후에 자동으로 종료되도록 제어한다.

        ESP32 Timer One-shot interrupt를 이용하여 장치를 제어하는 프로그램 예: ESP32-sw-led-timer-one-shot.ino

      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 위 "실험 회로 구성 예"와 같이 GPIO4에 switch를 연결한다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "sw-led-timer-one-shot.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면 개발 보드에 업로드가 시작된다.
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "툴 -> 시리얼 모니터"를 실행하면 시리얼 모니터 창이 열린다. 필요한 경우 보드레이트를 115200로 설정한다.
          • Command Switch(GPIO4)을 누르면 3초 후에 LED가 On 되고 2초 후에 Off 된다.

          주: 시리얼 모니터에 출력되는 내용은 프로그램의 실행 순서를 이해 하도록 하기 위한 메세지이다. 프로그램 개발이 완료되면 이 메세지 출력 명령은 삭제한다.


  • ESP8266/ESP32 PWM(Pulse width modulation)
    • PWM(Pulse width modulation) 개요
    • PWM 신호의 Pulse 폭과 PWM 신호의 평균 값(Analog 값)의 관계

      • PWM은 일정한 주기(T)의 펄스 신호에서 신호가 High 상태인 비율을 조정(제어)하여 부하(예: LED, DC 모터 등)에 가하는 전력을 제어하는 기술이다.
      • 신호 주기 동안 계속 High 상태인 경우 부하에 최대 전력이 공급되고, 주기의 50% 동안 High 인경우 최대 전력의 50%가 공급된다. 신호 주기 동안 계속 Low 상태인 경우 부하에 전력은 0 이 된다.
      • PWM 신호의 특성을 결정하는 중요한 매개변수(Parameter)
        • PWM Frequency: PWM frequency는 Pulse 주기가 T인 경우 1/T 로 정의된다. LED의 밝기를 제어(PWM 신호가 High 일때 LED 가 On 되고 Low 일 때 Off)하는 경우 PWM 주기가 너무 낮으면 LED의 깜박 거림이 느껴 진다. 일반적으로 LED 제어에는 1KHz 정도의 주기가 적당하다.
        • PWM Resolution: PWM 신호의 해상도는 한 주기 T를 표시하는 Bit 수를 나타낸다. 해상도를 8Bits로 설정하는 경우 PWM 신호의 한 주기는 256이 되고, 선택할 수 있는 Duty cycle의 값은 [0 - 255] 이 된다. 해상도를 10Bits로 설정하는 경우 PWM 신호의 한 주기는 1024이 되고, 선택할 수 있는 Duty cycle의 값은 [0 - 1023] 이 된다.해상도를 높게 설정하면 더 세밀하게 Duty를 설정할 수 있다.
        • PWM Duty Cycle: PWM 신호의 Pulse 폭을 결정하는 매개변수 이다. 해상도를 8Bits로 설정하면 설정할 수 있는 Duty 값의 범위는 0 - 255 가 된다.
    • ESP8266 PWM(Pulse width modulation)
      • ESP8266 PWM는 Software 적으로 구현되기 때문에 모든 I/O Pin을 PWM 출력으로 사용할 수 있다.
      • Arduino에서 PWM 출력은 analogWrite(PIN,VALUE) 함수를 사용하여 구현된다.
      • ESP8266 PWM은 10-bit Resolution을 갖기 때문에 VALUE 값은 0 - 1023 값을 갖는다.
      • PWM 신호의 주파수는 대략 1KHz 정도이다.
      • 주: analogWrite() 함수의 출력은 실제로는 Analog 신호를 출력하는 것이 아니라 Pulse 신호를 출력한다. 출력된 Pulse 신호의 평균 값(Analog 값)은 Pulse 신호의 폭에 비례한다.

      • LED 밝기 제어(PWM) 프로그램 예: ESP8266-pwm_led_brigth_cont.ino
      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "ESP8266-pwm_led_brigth_cont.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면(NodeMCU ESP8266 개발보드는 GPIO0를 프로그램에서 제어하기 때문에 GPIO0 SW를 누르지 않아도 됨) 개발 보드에 업로드가 시작된다.
          • 프로그램이 시작되면 LED가 점점 밝아지고, 점점 어두워 지기를 반복한다.

    • ESP32 PWM(Pulse width modulation)
    • ESP32 PWM hardware block diagram

      • ESP32 PWM는 위 Block diagram과 같이 High Speed Channal과 Low Speed Channal 2개 그룹에 각각 8 Channels 씩, 모두 16개의 독립된 Channel로 구성되어 있다.
      • 해상도는 1 - 16 bits 사이에서 선택하여 설정할 수 있다.
      • ESP32 PWM에서 사용하는 Pins
        • ESP32 PWM hardware는 16 개의 독립된 Channel을 갖고 있다.
        • 각 Channel은 임의의 GPIO pin을 사용할 수 있다.
        • 그러나 우리가 사용하는 대부분의 개발보드는 4개의 GPIO pin(GPIO34, 35, 36, 39)은 Input으로만 사용할 수 있도록 설정되어 있기 때문에 이 4개의 Pin를 제외한 Pin를 PWM Output으로 사용할 수 있다.
        • GPIO6 ~ GPIO11은 일부 ESP32 개발 보인 경우 외부 Pin에 연결되어 있다. 그러나 이 핀은 ESP-WROOM-32 칩의 통합 SPI 플래시에 연결되기 때문에 다른 용도로 사용은 권장되지 않는다. 따라서 PWM 프로젝트에서 이 핀을 사용하지 않는 것이 좋다.
      • PWM 자주 사용하는 함수
        • ledcAttachPin(pin, channel);
        • PWM channel을 GPIO Pin에 배정한다.

          • pin: PWM 신호를 출력하는 GPIO Pin 번호
          • channel: PWM channel 번호[0 – 15]
        • ledcSetup(channel, frequency, resolution_bits);
        • 선택한 PWM channel의 Frequency와 PWM Resolution을 설정한다.

          • channel: PWM channel 번호[0 – 15]
          • frequency: 선택한 channel의 PWM Frequency. LED 제어인 경우 1KHz(1000Hz)로 설정한다.
          • resolution_bits: 선택할 수 있는 PWM Resolution은 [ 1Bit – 16Bits ] 이다.
        • ledcWrite(channel, dutycycle);
        • 선택한 PWM channel의 dutycycle을 설정한다.

          • channel: PWM channel 번호[0 – 15]
          • dutycycle: 이 값의 범위는 PWM Resolution의 값에 의하여 결정된다. 해상도를 8Bits로 설정하는 경우 PWM 신호의 한 주기는 256이 되고, 선택할 수 있는 Duty cycle의 값은 [0 - 255] 이 된다.
    • ESP32 PWM을 이용한 LED 밝기 제어
      • 이 예는 PWM을 이용한 DC 전력제어(예: LED 밝기제어, DC 모터 속도제어 등) 기술를 이해하기 위한 것이다.

      • LED 밝기 제어(PWM) 프로그램 예: pwm_led_brigth_cont.ino
      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "pwm_led_brigth_cont.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면 개발 보드에 업로드가 시작된다.
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • 프로그램이 시작되면 LED가 점점 밝아지고, 점점 어두워 지기를 반복한다.

    • ESP32 Pulse Width 제어와 Pulse Width 측정
      • 펄스폭 측정을 위한 회로 구성 예

        이 예는 펄스 신호의 펄스폭을 제어(변경)과 펄스폭을 측정하는 기술을 이해하기 위한 예로 micros() 함수를 사용한다.

      • PWM과 micros() 함수를 이용한 Pulse 발생과 Width 측정 프로그램 예: ppulse_width_measure.ino
      • 실험을 위한 준비
        • Button switch: 위 "실험 회로 구성 예"와 같이 GPIO4와 GPIO5에 switch를 연결한다.
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • PWM 출력 신호(GPIO2)와 측정 신호 입력(GPIO16) Pin을 연결 한다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • 편집 창의 프로그램을 File name "pulse_width_measure.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면 개발 보드에 업로드가 시작된다.
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "툴 -> 시리얼 모니터"를 실행하면 시리얼 모니터 창이 열린다. 필요한 경우 보드레이트를 115200로 설정한다.
          • 콘솔 창에 측정값이 1초 간격으로 출력된다. GPIO4 버튼을 누르면 펄스폭이 증가하고, GPIO5 버튼을 누르면 펄스폭이 감소한다.

          주: 이 프로그램은 SW Debouncing이 생략되어 있기 때문에 Bouncing 현상이 발생할 수 있다.


  • ESP8266/ESP32 Timer 관련 페이지 보기