TOOLS GAMES DEVLOG DOCS ABOUT CONTACT
HOME > DOCS > Embedded / IoT > 하드웨어 펄스 카운터(PCNT)를 활용한 지터 없는 로터리 엔코더 읽기
Embedded / IoT Advanced ESP-IDF / Arduino

하드웨어 펄스 카운터(PCNT)를 활용한 지터 없는 로터리 엔코더 읽기

인터럽트 채터링 및 CPU 부하 없이 ESP32 내장 PCNT 하드웨어 모듈이 엔코더의 A/B 위상 구형파를 직접 카운팅하는 초정밀 입력 드라이버.

#Embedded #ESP32 #Hardware #Encoder #Interrupt
핵심 개념로터리 엔코더를 GPIO 외부 인터럽트(attachInterrupt)로 읽으면 빠른 회전 시 인터럽트 누락이나 기계적 스위치 채터링(바운싱)으로 인해 카운트가 튀는 현상이 생깁니다. ESP32 전용 하드웨어 펄스 카운터(PCNT)를 쓰면 CPU 개입 0%로 정확한 펄스를 적산할 수 있습니다.

1. PCNT 하드웨어 엔코더 설정 C 코드

pcnt_encoder.c
#include "driver/pcnt.h"

#define PCNT_UNIT       PCNT_UNIT_0
#define ENCODER_PIN_A   18
#define ENCODER_PIN_B   19

void init_encoder()
{
    pcnt_config_t pcnt_config = {
        .pulse_gpio_num = ENCODER_PIN_A,
        .ctrl_gpio_num = ENCODER_PIN_B,
        .channel = PCNT_CHANNEL_0,
        .unit = PCNT_UNIT,
        .pos_mode = PCNT_COUNT_INC,   // 상승 에지 카운트 증가
        .neg_mode = PCNT_COUNT_DEC,   // 하강 에지 카운트 감소
        .lctrl_mode = PCNT_MODE_REVERSE,
        .hctrl_mode = PCNT_MODE_KEEP,
        .counter_h_lim = 30000,
        .counter_l_lim = -30000,
    };
    pcnt_unit_config(&pcnt_config);

    // 하드웨어 디바운스 필터 적용 (80MHz 클럭 기준 글리치 제거)
    pcnt_set_filter_value(PCNT_UNIT, 1023);
    pcnt_filter_enable(PCNT_UNIT);

    pcnt_counter_pause(PCNT_UNIT);
    pcnt_counter_clear(PCNT_UNIT);
    pcnt_counter_resume(PCNT_UNIT);
}

int16_t get_encoder_count()
{
    int16_t count = 0;
    pcnt_get_counter_value(PCNT_UNIT, &count);
    return count;
}

참고자료 & 관련 링크