피코보드에서 Rotary Encoder 움직임을 OLED 화면에 표시하기

피코보드에서 Rotary Encoder 움직임을  OLED 화면에 표시하기

1. Rotary Encoder의 기본 조작 방법 응용

라즈베리 파이 피코보드에서 로터리 인코더를 사용하는 기본적인 방법을 앞선 글에서 소개하였다.

https://kongyine.com/223194923812

se-l-large_image” id=”SE-a0d0fe66-5e01-4812-8d1c-c8a011162d1c”>

a0d0fe66-5e01-4812-8d1c-c8a011162d1c”, “data” : {“link” : “https://kongyine.com/223194923812”, : “false”, “thumbnail” : “https://dthumb-phinf.pstatic.net/?src=%22https%3A%2F%2Fblogthumb.pstatic.net%2FMjAyMzA4MjdfMjYx%2FMDAxNjkzMTMxODg5ODYx.urAJ9WkqzqS5n6Z7V8-GJh5pG24T5v8n9YdPrLiGYPAg.LdwdyAH8URJc9KtnvcbGbOTLZeP0gst98N39bDW9Z3Mg.PNG.mythee1%2Fimage.png%3Ftype%3Dw2%22&type=ff500_300

이번 글에서는 앞선 글에서 소개한 방법으로 입력받은 로터리 인코더의 회전 값과 스위치 조작 값을 이용하여, 128×64 해상도를 가지는 OELD 화면에서 로터리 인코더가 회전하는 각도만큼 시계 바늘이 회전하도록 구현해 보았다.

또한, 로터리 인코더의 스위치가 눌려지는 경우, 해당 동작을 OLED 화면에서 작은 폭죽이 터지는듯한 형태로 구현해 보았다.

2. OLED 모듈의 기본 조작 방법

OLED 모듈 자체에 대한 소개와, 기본적인 동작 방법에 대해서는 이전 글에서 소개한 바 있으며, 다음 링크를 이용하여 참고하기 바란다.

https://kongyine.com/223193377274

se-l-large_image” id=”SE-d76eade5-9eae-4fd0-9b15-f375b5885c8b”>

d76eade5-9eae-4fd0-9b15-f375b5885c8b”, “data” : {“link” : “https://kongyine.com/223193377274”, : “false”, “thumbnail” : “https://dthumb-phinf.pstatic.net/?src=%22https%3A%2F%2Fblogthumb.pstatic.net%2FMjAyMzA4MjVfMjkx%2FMDAxNjkyOTQ0MjY2ODIx.NFnTtRulQV389ZIts71LLPrF0NA65XHychHdqvu2wqkg.w33yXxlFGj8Sypin2PAtuApy2HSq69mYAHx1NjCmE40g.JPEG.mythee1%2F2023-08-25_14_17_13.jpg%3Ftype%3Dw2%22&type=ff500_300

3. 예제 배선 – OLED와 조이스틱의 조합

본 예제에서는 바로 앞글에서 사용한 로터리 인코더용 회로에, 0번과 1번 핀을 이용하여 I2C 통신이 가능하도록 OLED 모듈의 SDA와 CLK를 연결해 주었다.

3.3V와 GND는 두 가지 모듈에 모두 필요하므로 적절히 이동하여 배선해 주었다.

4. 예제 Code 및 동작

이 기능을 구현하는 과정에서 중요한 것은 각도 계산인데,

먼저 로터리 인코더는 1회전이 20스텝이므로, 입력값으로부터 각도를 계산했고,

angle=step_new/20*365

OLED 화면에서 표시될 시계바늘의 중심은 화소의 가장 중앙인 64와 32에 위치시키되,

선을 그어줄 위치의 좌표는 다음식을 이용하여 계산하였다. 길이 32인 시계바늘을 이용하고, sin 및 Cos 함수를 이용하여 이를 기준 위치인 64,32 좌표에 더하는 방식으로 계산했다.

oled.line(64,32, 64+int(32*math.sin(math.radians(angle))), 32-int(30*math.cos(math.radians(angle))),1)

한 가지 주의사항은 피코 보드에 사용되는 마이크로 파이썬에서 삼각함수는 기본 내장함수가 아니어서

Code 초반부에서 다음 라이브러리 사용을 선언해 주어야 한다.

import math

또한 Sin/Cos에 적용되는 기본적인 각도 단위가 radian이므로, 이를 degree로 변환해 주어야 했다.

결과적으로 사용한 예제 코드는 다음과 같다.

import machine
import utime  
from rotary_irq_rp2 import RotaryIRQ
from ssd1306 import SSD1306_I2C
import math

WIDTH =128
HEIGHT= 64
sda=machine.Pin(0)
scl=machine.Pin(1)

i2c=machine.I2C(0,scl=scl, sda=sda, freq=400000)
oled = SSD1306_I2C(WIDTH,HEIGHT,i2c)
oled.init_display()


moveX = machine.ADC(26)
moveY = machine.ADC(27)
button = machine.Pin(22,machine.Pin.IN, machine.Pin.PULL_UP)
SW=machine.Pin(20,machine.Pin.IN,machine.Pin.PULL_UP)  
rstep = RotaryIRQ(pin_num_dt=19, pin_num_clk=18, min_val=0, reverse=False, range_mode=RotaryIRQ.RANGE_UNBOUNDED)
step_old = rstep.value()
while True:  
   step_new = rstep.value()
if step_old != step_new:  
     step_old = step_new  
     
     angle=step_new/20*365
print('step =', step_new, "   Angle==", angle)
     
     oled.fill(0)
     oled.text("Angle", 0, 0)
     oled.text(str(angle), 0, 8)
     oled.line(64,32,64+int(32*math.sin(math.radians(angle))),32-int(30*math.cos(math.radians(angle))),1)
     oled.show()   
     utime.sleep(0.001)
if SW.value()==0 :
print("Switch Pressed. Selected step number is : ",step_new)
     oled.fill(0)
for k in range(10):
        oled.rect(64-k,32-k,k*2,k*2,1)
        oled.show()   
        utime.sleep(0.001)

동작 결과는 다음과 같다.

OLED에 표시되는 것과 별개로, PC 화면의 Shell에도 다음과 같은 입력값이 표기되도록 하였다.