Hardware | Rotary Encoder 를 사용해 보자

|

1. Rotary Encoder


예전 전자 기기들의 볼륨 조절은, 최저/최고값이 표시되어 있고, 그 안에서만 움직이는 방식이었습니다.


요즘 나오는 자동차의 음성 조절이나 iPod 같은 전자기기의 볼륨도,

min/max 가 정해져 있지 않은 볼륨 조절 장치로 되어 있어요.


이를 Rotary Encoder 라고 부른다고 합니다.


제가 arduio 및 전자 취미시 처음으로 만져본 것은 "Transistor Tester" 라는 기기였습니다.


http://chocoball.tistory.com/entry/Hardware-Transistor-Tester


왼쪽 / 오른쪽으로 끝없이 돌려도 되면서,

위로부터 꾹 누르면 스위치의 "select" 도 구현되어 있는 센서였습니다.



기술 발전이란...




2. 원리


원리는 원반에 구멍이 일정 간격으로 뚫려 있고,

파형상 90도 차이나는 광원을 배치해, 각각 입력되는 펄스의 변화를 가지고 방향 인지 및 count 를 한다 합니다.



입력 시그널은 아래와 같이 나오며, 시계방향과 반시계방향의 펄스 입력값의 차이에 따라 알수 있겠죠.



값의 변화는 다음과 같이 되구요.



시작점을 11 값이라고 본다면, 각 방향으로 돌렸을 때의 변화값이 다르다는 것을 알 수 있습니다.



결국 저 작은 뭉퉁이에 photo diode 와 conuter 가 들어있다는 거네요.

예전같으면 불가능 했겠지만, sensor 들이 작아지면서 가능한 부품이 탄생한 것 같습니다.


참고한 사이트는 아래 두곳입니다.


http://howtomechatronics.com/tutorials/arduino/rotary-encoder-works-use-arduino/


- http://openhardware.ro/rotary-encoders-experiments/





3. AliExpress 에서 구매


Rotary Encoder 로 검색하면 여러가지 제품이 나옵니다.

그중에 가장 적당한 것으로 골랐습니다.


이걸 고른 이유는, 항상 LED 가 켜져 있어서 알려주는 indicator 가 없어서 였고 (눈부심),

괜찮게 저렴했기 때문이지요.



구매 링크는 다음과 같고, 사양은 아래와 같이 나와 있습니다.


https://ko.aliexpress.com/item/Rotary-Encoder-Module-Brick-Sensor-Development-Board-For-Arduino/1893663630.html


"rotation counts are not limited" 라고 되어 있어서, 어느 방향으로나 영원히 돌릴 수 있고,

"With the buttons on the rotary encoder can be reset to its initial state, that starts counting from 0" 라고 되어 있어서,

버튼 스위치가 구현되어 있다고 하네요.


=======================================

100% Brand new and high quality

Material: Electronic components + PCB

Size: About 31 * 19 * 29mm / 1.22" * 0.75" * 1.14"

Main color: Black

Working voltage: 5V

Pulse circle: 20

  

By rotating the rotary encoder can be counted in the positive direction and the reverse direction during rotation of the output pulse frequency, unlike rotary potentiometer count, this rotation counts are not limited. With the buttons on the rotary encoder can be reset to its initial state, that starts counting from 0. 

=======================================


다만, 가장 좋은 외형은 아래와 같이,

중간에 나사산이 있고, 윗부분에 어떤이라도 씌울 수 있는 돌기가 세겨져 있는 것이 좋을 듯 합니다.



비슷한 제품은 역시 괜찮은 sensor 들을 만들고 있는 SparkFun 에 있네요.

배송만 문제 없으면 이걸 구입하고 싶은데, 그냥 AliExpress 구매 제품으로도 만족합니다.





4. 도착


잊고 있었는데, 어느새 도착했습니다.

HDD 포장하는 것처럼 정전기 방지 비닐로 왔습니다.



필요한 단자는 다 있는 듯 합니다.



뒷면입니다.

중간에 R1 하나가 빠져 있는데, 괜찮은지 모르겠습니다.

아무래도 ripple 관련하여 있으면 좋지만 없어도 되는 부분을 뺀듯 합니다.


기회되면 나중에 10K 짜리 저항을 달아줘야겠습니다.





5. Layout


Pin 배열은 다음과 같습니다.


  Rotay  |
  Encder | Arduino Nano
-------------------------
    CLK  |     D2
    DT   |     D3
    SW   |   (empty)
     +   |     3.3V
    GND  |     GND
-------------------------

  SSD1306 | Arduino Nano
-------------------------
    VCC   |     3.3V
    GND   |     GND
    SDC   |     A5
    SDA   |     A4
-------------------------


전체 layout 은 다음과 같아요.






6. Sketch


Sketch 소스는 다음 link 를 참조하였습니다.


http://domoticx.com/arduino-rotary-encoder-met-oled-scherm/


원 저작자는

------------------------------------------------

"U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST); // Dev 0, Fast I2C / TWI"

------------------------------------------------


을 로딩했지만, 저는 SSD1306 OLED 이므로, 다음과 같이 수정하였습니다.

------------------------------------------------

"U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);   // Fast I2C / TWI"

-----------------------------------------------


// U8glib Bibliotheek importeren
#include "U8glib.h"
// U8glib Bibliotheek configureren voor het juiste display
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);   // Fast I2C / TWI
 
// Encoder pins configureren.
int pinEncA=2;
int pinEncB=3;
 
static byte abOud;       // Initialiseer status.
volatile int teller = 0; // rotatie teller.
int teller_oud;          // oude rotatie teller.
 
// Waarden voor variabel getal reserveren.
enum {BufSize=6};
char tellerStr[BufSize];
 
void setup() {
  // Encoder pinnen instellen.
  pinMode(pinEncA, INPUT);
  pinMode(pinEncB, INPUT);
 
  // Interrupts instellen (pin hoog-laag verandering).
  // Interrupt 0 = Pin 2 op de Arduino UNO.
  // Interrupt 1 = Pin 3 op de Arduino UNO.
  attachInterrupt(0, pinActie, CHANGE);
  attachInterrupt(1, pinActie, CHANGE);
 
  u8g.setFont(u8g_font_5x8); // Lettertype instellen voor u8glib.
}
 
void loop() {
  // IF loop wanneer er aan de encoder is gedraaid.
  if (teller_oud != teller) {
    teller_oud = teller;  
    snprintf(tellerStr, BufSize, "%d", teller);  // Converteer de "teller" INT naar STR (tbv OLED scherm)
  
    // OLED scherm loop.
    u8g.firstPage();  
    do {
      u8g.drawStr(0, 10, "Encoder:");
      
      u8g.drawBox(0, 14, 128, 16);    // Teken een witte rechthoek, 0px vanaf links, 14px van boven, 128px breed, 16px hoog.
      u8g.setColorIndex(0);           // zet kleur negatief (pixel uit).
      u8g.setScale2x2();              // maak het lettertype 2x groter.
      u8g.drawStr(25, 14, tellerStr); // print "teller" tekst.
      
      u8g.undoScale();                // zet het lettertype weer terug.
      u8g.setColorIndex(1);           // zet de kleur positief (pixel aan).
    } while( u8g.nextPage() );
  }
  // Overige code...
}
 
// Wanneer een interrupt heeft plaatsgevonden, lees de input pinnen, bereken nieuwe status, pas de telling aan.
void pinActie() {
  enum { upMask = 0x66, downMask = 0x99 };
  byte abNieuw = (digitalRead(pinEncA) << 1) | digitalRead(pinEncB);
  byte criteria = abNieuw^abOud;
  if (criteria==1 || criteria==2) {
    if (upMask & (1 << (2*abOud + abNieuw/2)))
      teller++;    // tel naar boven.
    else teller--; // tel naar beneden.
  }
  abOud = abNieuw; // bewaar nieuwe status.
}




7. 구동


아래는 실제 구동 영상 입니다.



IDE 로 메뉴 프로그래밍만 잘 하면 멋진걸 만들 수 있을것 같습니다.




FIN


단순한 입력 센서가 아닌, 설정하고 조정하는 조절센서로는 처음인것 같습니다.

여러가지로 활용해 봐야지.

And