ESP32-FreeRTOS에서 로터리 엔코더 이벤트 감지

소개



지난번 스위치 이벤트 감지 을 기재했습니다.
이번에는 로터리 엔코더의 검출에 대해 설명합니다.

개발 환경



다음이 확인한 환경입니다.
  • windows10 64bit
  • Arduino IDE 1.8.10
  • Esplora Built-In by Arduino 1.0.4
  • FreeRTOS by Richard Barry 10.2.0-3
  • RotaryEncoder by Matthias Hertel 1.3.0 - Github - RotaryEncoder

  • vscode 1.41.1
  • PlatformIO - Home 3.0.1, Core 4.1.0


  • 이 코드는 RotaryEncoder 라이브러리을 사용합니다.
    ./lib 아래에 RotaryEncoder 라이브러리를 배치해야합니다.
    ./SampleRe/lib/RotaryEncoder-master/RotaryEncoder.cpp
    ./SampleRe/lib/RotaryEncoder-master/RotaryEncoder.h
    ※Arduino IDE에서도 움직이는 것은 확인했습니다만,
    Arduino IDE에서 실행하는 경우 main.cpp를 .ino 파일로 바꿔야합니다.
    또한 Arduino IDE시는 라이브러리 매니저에서 설치할 수 있습니다.

    장비 및 연결 다이어그램



    2종류의 로터리 엔코더로 확인했으므로 각각 기재합니다.
  • 풀 컬러 RGB LED가있는 로터리 엔코더 사용
  • HiLetgo 회전식 엔코더 모듈 사용

  • 풀 컬러 RGB LED 부착 로터리 엔코더시의 기재



    ※형명이 구입처의 링크가 되어 있습니다.


    품목
    형명
    비고


    ESP32-WROOM-32 개발 보드
    NodeMCU-32S ESP32-WROOM-32
    -

    로터리 엔코더
    EC12PLRGBSDVBF-D-25K-24-24C-61
    DIP화 기판과 납땜 필요

    로터리 엔코더 DIP화 기판 RECNV-2
    AE-RECNV-2

    저항
    10kΩ x 2

    브레드보드
    지정 없음

    점퍼 케이블
    지정 없음



    풀 컬러 RGB LED 부착 로터리 엔코더시의 접속도





    ↓가 실제 사진입니다. 유니버설 보드에 있습니다.



    HiLetgo 회전식 엔코더 모듈의 장비



    ※형명이 구입처의 링크가 되어 있습니다.


    품목
    형명
    비고


    ESP32-WROOM-32 개발 보드
    NodeMCU-32S ESP32-WROOM-32
    -

    로터리 엔코더
    HiLetgo 회전식 엔코더 모듈
    납땜 불필요

    브레드보드
    지정 없음

    점퍼 케이블
    지정 없음



    HiLetgo 회전식 엔코더 모듈의 연결도





    ↓가 실제 사진입니다.



    시퀀스 다이어그램



    작성하는 프로그램의 순서도는 다음과 같습니다.



    코드 배치 위치



    코드는 아래에 배치되어 있습니다.
    esp32Samples - SampleRe

    시퀀스와 코드 코드의 연결



    시퀀스와 코드의 관련 부분을 발췌하여 기재합니다.

    초기화 처리



    RE 인스턴스 생성


  • 사용할 PIN 정의

  • Sytem_Re.h
    #define RE_ASGN_SIGNAL_A    (4)
    #define RE_ASGN_SIGNAL_B    (2)
    
  • 인스턴스 생성

  • ApiRe.cpp
    #include <RotaryEncoder.h>
    
    static RotaryEncoder s_xRotaryEncoder(RE_ASGN_SIGNAL_A, RE_ASGN_SIGNAL_B);
    

    RE 인터럽트 부착



    ApiRe.cpp
        // 割り込み関連の設定
        attachInterrupt(digitalPinToInterrupt(RE_ASGN_SIGNAL_A), vIsrCallbackRe, CHANGE);
        attachInterrupt(digitalPinToInterrupt(RE_ASGN_SIGNAL_B), vIsrCallbackRe, CHANGE);
    
  • vIsrCallbackRe
  • 인터럽트 처리 (후술)

  • CHANGE
  • A상, B상의 변화점이 필요하기 때문에 CHANGE를 지정


  • RE용 타이머 생성



    ApiRe.cpp
    #define RE_CHECK_TIME           (50)        //ロータリーエンコーダチェック間隔:50msec
    ...
    
    static TimerHandle_t s_xTimerRe = NULL;
    
    ...
    
    ErType_t xInitRe(void)
    {
        ...
        s_xTimerRe = xTimerCreate
                        (   cName,                      //text name
                            RE_CHECK_TIME,              //timer period
                            pdTRUE,                     //auto-reload
                            ( void * ) 0,               //number of times
                            vTimerCallbackRe                //callback
                        );
    
    xTimerReset(    s_xTimerRe, RE_CHECK_TIME)
    
    
  • auto-reload : pdTRUE
  • 50msec마다 정기적으로 호출하기 위해 지정


  • 회전 이벤트 감지



    인터럽트 발생/회전수 유지



    ApiRe.cpp
    /**
     * @brief ロータリーエンコーダ割り込み処理
     */
    static void IRAM_ATTR vIsrCallbackRe()
    {
        s_xRotaryEncoder.tick(); // just call tick() to check the state.
    }
    

    인터럽트가 발생하면 위의 함수가 호출됩니다.
    tick()을 호출하여 회전 수를 유지합니다.

    회전수의 취득/회전 상태를 송신



    ApiRe.cpp
    
    /**
     * @brief ロータリーエンコーダのタイマーコールバック関数
     */
    static void vTimerCallbackRe( TimerHandle_t xTimer)
    {
        static int32_t pos;
    
        pos = s_xRotaryEncoder.getPosition();
        if( pos != s_slBakRePosition )
        {
            Serial.printf("%s - (%d), (%d)\n",__func__ ,pos ,(pos - s_slBakRePosition));
            s_slBakRePosition = pos;
        }
    
        return;
    }
    

    50msec마다 위의 함수가 소프트웨어 타이머 작업 내에서 처리됩니다.
    이전의 상태와 다른 경우, Serial.printf()로 유저에게 통지합니다.

    실행 결과 예


  • 시계 방향 실행
  • vTimerCallbackRe - (11), (1)
    vTimerCallbackRe - (12), (1)
    vTimerCallbackRe - (13), (1)
    vTimerCallbackRe - (14), (1)
    vTimerCallbackRe - (17), (3)
    vTimerCallbackRe - (18), (1)
    
  • 반 시계 방향을 실시
  • vTimerCallbackRe - (25), (-1)
    vTimerCallbackRe - (23), (-2)
    vTimerCallbackRe - (21), (-2)
    vTimerCallbackRe - (20), (-1)
    

    참고


  • FreeRTOS Software Timers
  • A Library for the Arduino environment for using a rotary encoder as an input.
  • github - RotaryEncoder
  • 좋은 웹페이지 즐겨찾기