ESP32 - 로터리 엔코더 | ESP32 - Rotary Encoder
이 가이드에서는 ESP32와 로터리 인코더를 사용하는 방법을 배우게 됩니다. 다음은 우리가 배울 내용입니다:
- 로터리 엔코더와 포텐쇼미터의 차이점은 무엇인가요?
- 로터리 엔코더는 어떻게 작동하나요?
- 로터리 엔코더를 ESP32에 어떻게 연결하나요?
- 인터럽트 없이 ESP32가 로터리 엔코더의 방향과 위치를 읽을 수 있도록 코드를 작성하는 방법은 무엇인가요?
- 인터럽트를 활용하여 ESP32가 로터리 엔코더의 방향과 위치를 읽을 수 있도록 코드를 작성하는 방법은 무엇인가요?
준비물
1 | × | ESP-WROOM-32 Dev Module | 쿠팡 | Amazon | |
1 | × | USB Cable Type-C | 쿠팡 | Amazon | |
1 | × | Rotary Encoder | 쿠팡 | Amazon | |
1 | × | Breadboard | 쿠팡 | Amazon | |
1 | × | Jumper Wires | Amazon | |
1 | × | (Recommended) Screw Terminal Expansion Board for ESP32 | 쿠팡 | Amazon |
로터리 엔코더 정보
라디오와 같은 회전 노브는 전기로 변환되는 신호를 보낼 수 있습니다. 이는 노브가 얼마나 돌았고 어디에 배치되었는지 알 수 있게 도와줍니다. 주로 두 가지 유형이 있습니다:
- 증분 엔코더: 이것은 빠른 신호를 사용하여 무언가가 위치를 얼마나 변경했는지를 측정합니다.
- 절대 엔코더: 이 유형은 각 위치마다 비밀 코드를 제공하여, 전력이 사라져도 무언가가 어디에 있는지 찾을 수 있게 도와줍니다.
이 수업은 주로 첫 번째 유형인 증분 엔코더에 관한 것입니다.
로터리 인코더 모듈 핀 배치
로터리 인코더 모듈에는 4개의 핀이 있습니다:
- CLK 핀 (출력 A): 회전이 얼마나 발생했는지 알려주는 주요 펄스입니다. 노브를 어느 방향으로든 한 단계(클릭) 돌릴 때마다, CLK 핀은 전체 주기(LOW → HIGH → LOW)를 완료하는 신호를 출력합니다.
- DT 핀 (출력 B): CLK 핀과 비슷하게 작동하지만 CLK 신호보다 90도 지연된 신호를 출력합니다. 이것은 회전의 방향(시계 방향 또는 반시계 방향)을 파악하는 데 도움이 됩니다.
- SW 핀: 인코더의 버튼에서 나옵니다. 보통 열려 있습니다. 이 핀에 풀업 저항을 추가하면 노브가 눌리지 않았을 때 SW 핀은 HIGH이고 눌렸을 때는 LOW입니다.
- VCC 핀 (+): VCC(3.3과 5 볼트 사이)에 연결해야 합니다.
- GND 핀: GND(0V)에 연결해야 합니다.
로터리 인코더 대 비교 가변저항기
회전 엔코더를 포텐쇼미터와 혼동할 수 있습니다. 하지만 그것들은 서로 다른 부품입니다. 다음은 그들 사이의 비교입니다:
- 로터리 엔코더는 현대 버전의 포텐쇼미터와 같지만, 더 많은 일을 할 수 있습니다.
- 로터리 엔코더는 멈추지 않고 완전한 원을 돌 수 있지만, 포텐쇼미터는 원의 약 3/4만 돌 수 있습니다.
- 로터리 엔코더는 펄스를 출력하는 반면, 포텐쇼미터는 아날로그 전압을 출력합니다.
- 로터리 엔코더는 노브가 얼마나 움직였는지만 파악할 때 유용합니다. 정확히 위치가 어디인지는 필요하지 않을 때입니다. 포텐쇼미터는 노브의 정확한 위치를 정말로 알아야 할 때 유용합니다.
로터리 인코더의 작동 원리
인코더 내부에는 C라고 불리는 핀에 연결된 슬롯이 있는 작은 디스크가 있으며, 이는 공유 그라운드처럼 작동합니다. A와 B라는 두 개의 핀이 더 있습니다.
- 노브를 돌리면 A 핀과 B 핀이 공유 접지 핀 C를 접촉하지만, 시계 방향이나 반시계 방향으로 돌리는지에 따라 접촉 순서가 달라집니다.
- 이 접촉들은 두 개의 신호를 생성합니다. 한 핀이 다른 핀보다 먼저 접지를 접촉하기 때문에 타이밍이 약간 다릅니다. 이러한 신호들은 90도로 동기화되지 않는데, 이를 쿼드러처 인코딩이라고 합니다.
- 노브를 시계 방향으로 돌리면 A 핀이 B 핀보다 먼저 접지에 닿습니다. 그러나 반시계 방향으로 돌리면 B 핀이 A 핀보다 먼저 접지에 닿습니다.
- 각 핀이 접지에 닿거나 떨어지는 시점을 확인함으로써 노브가 어느 방향으로 돌아가는지 알아낼 수 있습니다. 이는 A 핀이 변할 때 B 핀에 무슨 일이 일어나는지 확인함으로써 이루어집니다.
A가 LOW에서 HIGH로 상태가 바뀔 때:
- B가 높으면, 노브는 반시계 방향으로 돌립니다.
- B가 낮으면, 노브는 시계 방향으로 돌립니다.
※ NOTE THAT:
A핀과 B핀은 CLK 및 DT 핀에 연결됩니다. 그러나 제조업체에 따라 순서가 다를 수 있습니다. 아래에 제공된 코드는 DIYables에서 제공하는 로터리 인코더와 함께 테스트되었습니다.
로터리 엔코더를 위한 프로그래밍 방법
- ESP32는 CLK 핀에서 신호를 읽습니다.
- 상태가 LOW에서 HIGH로 변경되면, ESP32는 DT 핀의 상태를 읽습니다.
- DT 핀이 HIGH일 경우, 노브가 반시계 방향으로 돌아가면, ESP32는 카운터를 1 증가시킵니다.
- DT 핀이 LOW일 경우, 노브가 시계 방향으로 돌아가면, ESP32는 카운터를 1 감소시킵니다.
선연결
이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.
ESP32 및 다른 구성 요소에 전원을 공급하는 방법에 대해 잘 알지 못하는 경우, 다음 튜토리얼에서 안내를 찾을 수 있습니다: ESP32 전원 공급 방법.
ESP32 코드 - 로터리 엔코더
아래 ESP32 코드는 다음 작업을 수행합니다:
- 인코더의 회전 방향과 양을 감지합니다.
- 시계 방향으로 한 단계(클릭) 돌아간 것을 감지하면, 카운터를 1 증가시킵니다.
- 반시계 방향으로 한 단계(클릭) 돌아간 것을 감지하면, 카운터를 1 감소시킵니다.
- 버튼이 눌렸는지 감지합니다.
버튼 디바운싱 코드를 간단하게 하기 위해, ezButton 라이브러리가 사용됩니다.
사용 방법
이것이 처음으로 ESP32를 사용하는 경우라면, Arduino IDE에서 ESP32 환경 설정하는 방법을 참고하세요.
- Arduino IDE에 ezButton 라이브러리를 설치하세요.
- 위의 코드를 복사하고 Arduino IDE로 엽니다.
- Arduino IDE에서 Upload 버튼을 클릭하여 코드를 ESP32에 업로드하세요.
- 손잡이를 시계 방향으로, 그 다음에 반시계 방향으로 돌리세요.
- 손잡이를 누르세요.
- 시리얼 모니터에서 결과를 확인하세요.
코드 설명
코드의 줄마다 달린 주석을 확인하세요.
ESP32 코드 - 인터럽트를 사용한 로터리 엔코더
이전 코드에서는 지속적으로 핀의 상태를 확인하기 위해 폴링(Polling)을 사용하는 것이 ESP32 리소스를 낭비할 수 있으며, 다른 코드 실행이 느린 경우 카운트 누락이 발생할 수 있습니다.
효과적인 해결책은 폴링이 필요 없게 만드는 인터럽트를 활용하는 것입니다. 이를 통해 ESP32가 카운트를 놓치지 않으면서 다른 작업을 수행할 수 있습니다. 아래는 로터리 인코더로부터 방향과 위치를 읽기 위해 인터럽트를 사용하는 ESP32 코드입니다.
이제, 손잡이를 돌리면 직전 코드에서 보았던 것과 비슷한 방식으로 시리얼 모니터에 정보가 표시되는 것을 알 수 있습니다.
※ NOTE THAT:
- 다른 웹사이트에서 두 개의 인터럽트를 하나의 엔코더에 사용하는 튜토리얼을 접할 수 있지만, 이는 불필요하고 낭비입니다. 단 하나의 인터럽트만으로 충분합니다.
- 인터럽트에서 사용되는 전역 변수에는 volatile 키워드를 사용하는 것이 중요합니다. 이를 무시하면 예상치 못한 문제가 발생할 수 있습니다.
- 인터럽트 내의 코드를 가능한 한 간단하게 유지하십시오. 인터럽트 내에서 Serial.print()나 Serial.println()의 사용을 피하십시오.
ESP32 로터리 엔코더 애플리케이션
로터리 엔코더를 사용하여 다음과 같은 작업을 할 수 있지만 이에 국한되지 않습니다:
- ESP32 - 로터리 엔코더가 서보 모터의 위치를 제어함
- ESP32 - 로터리 엔코더가 LED의 밝기를 제어함
- ESP32 - 로터리 엔코더가 스테퍼 모터의 속도를 제어함
동영상
비디오 제작은 시간이 많이 걸리는 작업입니다. 비디오 튜토리얼이 학습에 도움이 되었다면, YouTube 채널 을 구독하여 알려 주시기 바랍니다. 비디오에 대한 높은 수요가 있다면, 비디오를 만들기 위해 노력하겠습니다.