아두이노 우노 R4 로터리 인코더

이 가이드에서는 아두이노 UNO R4와 함께 증분 인코더를 사용하는 방법에 대해 배워볼 것입니다. 우리는 다음을 다룰 것입니다:

아두이노 우노 R4 로터리 인코더

준비물

1×Arduino UNO R4 WiFi or Arduino UNO R4 Minima
1×(또는) DIYables STEM V4 IoT, Compatible with Arduino Uno R4 WiFi 쿠팡 | 아마존
1×USB 케이블 타입-A to 타입-C (USB-A PC용) 쿠팡 | 아마존
1×USB 케이블 타입-C to 타입-C (USB-C PC용) 아마존
1×로터리 엔코더 (Rotary Encoder) 쿠팡 | 아마존
1×점퍼케이블 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 스크루 터미널 블록 쉴드 쿠팡 | 아마존
1×(추천) Sensors/Servo Expansion Shield for Arduino UNO R4 아마존
1×(추천) 아두이노 우노 R4용 브레드보드 쉴드 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 케이스 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 전원 분배기 쿠팡 | 아마존
1×(추천) 아두이노 우노용 프로토타이핑 베이스 플레이트 & 브레드보드 키트 아마존
공개: 이 포스팅 에 제공된 일부 링크는 아마존 제휴 링크입니다. 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
Arduino Uno R4 WiFi Compatible Boards

로터리 엔코더에 대하여

회전 인코더는 회전 운동을 전기 신호로 변환하는 장치입니다. 이는 샤프트나 손잡이의 회전과 위치를 확인합니다. 주로 두 가지 유형이 있습니다:

  • 증분형 엔코더: 위치 변화를 측정하기 위해 펄스를 생성합니다.
  • 절대형 엔코더: 각 위치에 대해 특별한 디지털 코드를 제공하여, 전원이 꺼져도 정확한 위치 지정에 적합합니다.

이 튜토리얼은 증분 인코더에 관한 것입니다.

로터리 인코더 모듈 핀아웃

로터리 엔코더 핀아웃

로터리 인코더 모듈은 네 개의 핀으로 구성되어 있습니다:

  • CLK 핀 (출력 A): 이 핀은 노브를 한 번 클릭하는 방향으로 돌릴 때마다 신호를 보냅니다. 이는 LOW에서 HIGH로, 다시 LOW로 가는 완전한 신호 주기를 보여주며, 노브가 얼마나 회전했는지를 알려줍니다.
  • DT 핀 (출력 B): CLK 핀과 유사하지만, 이 핀의 신호는 CLK 신호보다 90도 지연되어 발생합니다. 이 지연은 회전이 시계 방향인지 반시계 방향인지 판단하는 데 도움이 됩니다.
  • SW 핀: 이 핀은 인코더의 내부 푸시버튼에 연결되어 있으며, 보통 열려 있습니다. 이 핀에 풀업 저항을 사용하면 노브가 눌리지 않았을 때 HIGH를, 눌렸을 때 LOW를 나타냅니다.
  • VCC 핀 (+): 이 핀을 3.3V에서 5V 사이의 전원을 공급하는 전원 공급 장치에 연결하세요.
  • GND 핀: 이 핀을 접지 (0V)에 연결하세요.

로터리 엔코더 vs 포텐셔미터

회전 인코더를 아두이노 우노 R4 - 가변저항기와 혼동할 수 있지만, 이들은 다른 부품입니다. 다음은 그 비교입니다:

  • 로터리 엔코더는 완전히 계속해서 회전할 수 있지만, 포텐쇼미터는 전체 원의 4분의 3만 회전할 수 있습니다.
  • 로터리 엔코더는 펄스를 출력하는 반면, 포텐쇼미터는 아날로그 전압을 출력합니다.
  • 로터리 엔코더는 노브가 얼마나 회전했는지를 아는 데 유용하지만, 정확한 위치는 알 수 없습니다. 포텐쇼미터는 노브의 정확한 위치를 찾는 데 좋습니다.

로터리 인코더의 작동 원리

로터리 엔코더 출력

인코더에는 C라는 이름의 핀과 연결된 슬롯이 있는 디스크가 있으며, 이는 공통 접지로 작용합니다. 또한 두 개의 추가 핀, A와 B가 있습니다.

  • 손잡이를 회전하면 핀 A와 B가 공통 접지 핀 C와 접촉하게 되지만, 회전 방향에 따라 시계 방향 또는 반시계 방향으로 특정 순서에 따라 작동합니다.
  • 이 접촉은 타이밍이 약간 다른 두 개의 신호를 생성합니다. 이는 한 핀이 다른 핀보다 먼저 접지에 연결되기 때문입니다. 이 신호들은 90도 어긋나 있으며, 이를 사분면 인코딩이라 부릅니다.
  • 손잡이를 시계 방향으로 돌리면 핀 A가 핀 B보다 먼저 접지에 접촉됩니다. 반시계 방향으로 돌리면 핀 B가 핀 A보다 먼저 접지에 접촉됩니다.
  • 각 핀이 접지와 접촉하거나 끊어지는 시점을 관찰함으로써 손잡이의 회전 방향을 결정할 수 있습니다. 이는 핀 A와 비교하여 핀 B의 변화를 분석함으로써 수행됩니다.
회전 인코더의 작동 원리

A가 LOW에서 HIGH로 전환될 때:

  • B가 LOW이면 손잡이를 시계 방향으로 돌리세요.
  • B가 HIGH이면 손잡이를 반시계 방향으로 돌리세요.

※ 주의:

A핀과 B핀은 CLK 및 DT 핀에 연결되어 있습니다. 배치는 제조업체에 따라 다를 수 있습니다. 여기 제공된 코드는 DIYables의 로터리 인코더로 테스트되었습니다.

로터리 엔코더를 프로그래밍하는 방법

  • CLK 핀에서 신호를 확인하세요.
  • 신호가 LOW에서 HIGH로 변할 때, DT 핀이 무엇을 나타내고 있는지 확인하세요.
    • DT 핀이 HIGH를 나타내면, 다이얼이 반시계 방향으로 돌아갑니다. 카운터에 1을 더하세요.
    • DT 핀이 LOW를 나타내면, 다이얼이 시계 방향으로 돌아갑니다. 카운터에서 1을 빼세요.

선연결

아두이노 우노 R4 로터리 엔코더 배선도

이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.

Arduino Uno R4와 기타 부품에 전원을 공급하는 가장 효과적인 방법을 확인하시려면, 아래 링크를 참조하세요: 아두이노 우노 R4 전원 공급 방법.

아두이노 UNO R4 코드 – 인터럽트 없는 로터리 엔코더

이 Arduino UNO R4 코드는 다음 작업을 수행합니다:

  • 인코더가 어떻게, 그리고 얼마나 회전하는지를 감지합니다.
    • 노브가 오른쪽으로 한 칸 클릭되었다고 감지하면 카운터에 1을 더합니다.
    • 노브가 왼쪽으로 한 칸 클릭되었다고 감지하면 카운터에서 1을 뺍니다.
  • 버튼이 눌렸는지 알아차립니다.
/* * 이 아두이노 우노 R4 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 우노 R4 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-r4/arduino-uno-r4-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 2 // The Arduino UNO R4 pin connected to the CLK pin of encoder #define DT_PIN 3 // The Arduino UNO R4 pin connected to the DT pin of encoder #define SW_PIN 4 // The Arduino UNO R4 pin connected to the SW pin of encoder #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction int counter = 0; int direction = DIRECTION_CW; int CLK_state; int prev_CLK_state; ezButton button(SW_PIN); // create ezButton object that attach to pin 4 void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // read the initial state of the rotary encoder's CLK pin prev_CLK_state = digitalRead(CLK_PIN); } void loop() { button.loop(); // MUST call the loop() function first // read the current state of the rotary encoder's CLK pin CLK_state = digitalRead(CLK_PIN); // If the state of CLK is changed, then pulse occurred // React to only the rising edge (from LOW to HIGH) to avoid double count if (CLK_state != prev_CLK_state && CLK_state == HIGH) { // if the DT state is HIGH // the encoder is rotating in counter-clockwise direction => decrease the counter if (digitalRead(DT_PIN) == HIGH) { counter--; direction = DIRECTION_CCW; } else { // the encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } Serial.print("DIRECTION: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" | COUNTER: "); Serial.println(counter); } // save last CLK state prev_CLK_state = CLK_state; if (button.isPressed()) { Serial.println("The button is pressed"); } }

우리는 ezButton 라이브러리를 사용하여 버튼 디바운싱 코드를 더욱 간단하게 만듭니다.

자세한 사용 방법

다음 지침을 단계별로 따르세요:

  • Arduino Uno R4 WiFi/Minima를 처음 사용하는 경우, 아두이노 우노 R4 - 소프트웨어 설치에 대한 튜토리얼을 참조하십시오.
  • 제공된 다이어그램에 따라 로터리 인코더를 Arduino UNO R4에 연결합니다.
  • USB 케이블을 사용하여 Arduino Uno R4 보드를 컴퓨터에 연결합니다.
  • 컴퓨터에서 Arduino IDE를 실행합니다.
  • 적절한 Arduino Uno R4 보드(예: Arduino Uno R4 WiFi) 및 COM 포트를 선택합니다.
  • EzButton 라이브러리를 Arduino IDE에 추가합니다. 지침은 다음 링크를 방문하십시오: ezButton 라이브러리
  • 제공된 코드를 복사하여 Arduino IDE에서 엽니다.
  • Arduino IDE에서 Upload 버튼을 클릭하여 코드를 Arduino UNO R4에 로드합니다.
  • 노브를 시계 방향 및 시계 반대 방향으로 회전시킵니다.
  • 노브를 누릅니다.
  • 시리얼 모니터에서 결과를 확인합니다.
Newbiely | Arduino IDE 2.3.8
──
File
Edit
Sketch
Tools
Help
Arduino Uno R4 WiFi
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno R4 WiFi' on 'COM15')
New Line
9600 baud
DIRECTION: Clockwise | COUNTER: 1 DIRECTION: Clockwise | COUNTER: 2 DIRECTION: Clockwise | COUNTER: 3 DIRECTION: Clockwise | COUNTER: 4 DIRECTION: Clockwise | COUNTER: 5 DIRECTION: Counter-clockwise | COUNTER: 4 DIRECTION: Counter-clockwise | COUNTER: 3 DIRECTION: Counter-clockwise | COUNTER: 2 DIRECTION: Counter-clockwise | COUNTER: 1 DIRECTION: Counter-clockwise | COUNTER: 0 The button is pressed
Ln 11, Col 1
Arduino Uno R4 WiFi on COM15
2

코드 설명

코드의 각 줄에 있는 주석을 보세요.

Arduino UNO R4 코드 – 인터럽트를 사용한 로터리 엔코더

이전 코드 예제에서는 핀의 상태를 지속적으로 확인하는 폴링 방식을 사용했습니다. 이 방법에는 두 가지 단점이 있습니다:

  • Arduino UNO R4 자원을 비효율적으로 사용합니다.
  • 다른 코드가 실행되는 데 너무 오래 걸리면 일부 카운트가 건너뛰어질 수 있습니다.

이를 제어하는 하나의 방법은 인터럽트를 통해서입니다. 인터럽트는 특정 이벤트를 지속적으로 확인해야 하는 필요성을 피하는 데 도움을 줍니다. 이를 통해 Arduino UNO R4는 이벤트를 모니터링하면서도 다른 작업을 수행할 수 있습니다.

다음 코드를 보면서 인터럽트를 사용하여 인코더에서 값을 읽는 방법을 알아봅시다.

/* * 이 아두이노 우노 R4 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 우노 R4 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-r4/arduino-uno-r4-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 2 // The Arduino UNO R4 pin connected to the CLK pin of encoder #define DT_PIN 3 // The Arduino UNO R4 pin connected to the DT pin of encoder #define SW_PIN 4 // The Arduino UNO R4 pin connected to the SW pin of encoder #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction volatile int counter = 0; volatile int direction = DIRECTION_CW; volatile unsigned long last_time; // for debouncing int prev_counter; ezButton button(SW_PIN); // create ezButton object that attach to pin 4 void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // use interrupt for CLK pin is enough // call ISR_encoderChange() when CLK pin changes from LOW to HIGH attachInterrupt(digitalPinToInterrupt(CLK_PIN), ISR_encoderChange, RISING); } void loop() { button.loop(); // MUST call the loop() function first if (prev_counter != counter) { Serial.print("DIRECTION: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" | COUNTER: "); Serial.println(counter); prev_counter = counter; } if (button.isPressed()) { Serial.println("The button is pressed"); } // TO DO: your other work here } void ISR_encoderChange() { if ((millis() - last_time) < 50) // debounce time is 50ms return; if (digitalRead(DT_PIN) == HIGH) { // the encoder is rotating in counter-clockwise direction => decrease the counter counter--; direction = DIRECTION_CCW; } else { // the encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } last_time = millis(); }
  • 제공된 코드를 복사하여 Arduino IDE에서 엽니다.
  • Arduino IDE에서 Upload 버튼을 클릭하여 코드를 Arduino UNO R4에 로드합니다.

이제 다이얼을 돌리면 이전 코드에서 보았던 것과 유사하게 직렬 모니터에 정보가 표시됩니다.

※ 주의:

  • Arduino UNO R4에 인코더의 CLK 핀을 인터럽트를 사용하여 연결하려면 핀 2 또는 3을 사용해야 합니다. 이 핀들만 인터럽트를 지원합니다.
  • 일부 온라인 가이드에서는 하나의 엔코더에 두 개의 인터럽트를 사용하는 것을 제안할 수 있지만, 이는 필요하지 않습니다. 하나의 인터럽트만 사용하는 것으로 충분합니다.
  • 글로벌 변수에 인터럽트를 사용할 때는 volatile 키워드를 반드시 사용하여 문제를 피해야 합니다.
  • 인터럽트 내부의 프로그래밍은 간단하게 유지하십시오. Serial.print() 또는 Serial.println()을 사용하지 마십시오.

동영상

비디오 제작은 시간이 많이 걸리는 작업입니다. 비디오 튜토리얼이 학습에 도움이 되었다면, YouTube 채널 을 구독하여 알려 주시기 바랍니다. 비디오에 대한 높은 수요가 있다면, 비디오를 만들기 위해 노력하겠습니다.

관련 튜토리얼