안녕하세요 땜블리 입니다.
라즈베리파이 피코 베이직 트레이닝 보드를 이용한 OLED제어를 진행 하겠습니다.
베이직 트레이닝 보드는 아래에서 확인이 가능합니다.
1) OLED 제어 구동 원리
(1) 동작설명
OLED(유기 발광 다이오드)는 유기 화합물 층으로 이루어진 LED 반도체 소자 중 하나입니다.
128x64 OLED 디스플레이는 단순한 도트 매트릭스 그래픽 디스플레이입니다.
128 개의 열과 64 개의 행이있어 총 128x64 = 8192 픽셀을 표시합니다.
이 픽셀의 LED를 켜고 끄면 모든 모양의 그래픽 이미지를 표시 할 수 있습니다.
2) OLED 기본 문구 출력 제어
(1) 동작설명
ssd1306 드라이버를 사용하여 OLED에 Text를 표시 합니다.
i2c = I2C(1,scl=Pin(15), sda=Pin(14)) I2C pin 설정
oled = ssd1306.SSD1306_I2C(128,64,i2c,0x3c) OLED pin 설정
oled.fill(1) 화면을 흰색으로 채웁니다.
oled.fill(0) 화면을 검정색으로 채웁니다.
oled.show() 화면을 보여 줍니다.
oled.text("picoSensorBoard",0,0) 0,0좌표에 picoSensorBoard 를 표시 합니다.
(2) 코드작성
ssd1306.py
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
from micropython import const
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xA4)
SET_NORM_INV = const(0xA6)
SET_DISP = const(0xAE)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xA0)
SET_MUX_RATIO = const(0xA8)
SET_IREF_SELECT = const(0xAD)
SET_COM_OUT_DIR = const(0xC0)
SET_DISP_OFFSET = const(0xD3)
SET_COM_PIN_CFG = const(0xDA)
SET_DISP_CLK_DIV = const(0xD5)
SET_PRECHARGE = const(0xD9)
SET_VCOM_DESEL = const(0xDB)
SET_CHARGE_PUMP = const(0x8D)
# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
self.buffer = bytearray(self.pages * self.width)
super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
self.init_display()
def init_display(self):
for cmd in (
SET_DISP, # display off
# address setting
SET_MEM_ADDR,
0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE, # start at line 0
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO,
self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET,
0x00,
SET_COM_PIN_CFG,
0x02 if self.width > 2 * self.height else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV,
0x80,
SET_PRECHARGE,
0x22 if self.external_vcc else 0xF1,
SET_VCOM_DESEL,
0x30, # 0.83*Vcc
# display
SET_CONTRAST,
0xFF, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
SET_IREF_SELECT,
0x30, # enable internal IREF during display on
# charge pump
SET_CHARGE_PUMP,
0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01, # display on
): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP)
def poweron(self):
self.write_cmd(SET_DISP | 0x01)
def contrast(self, contrast):
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def invert(self, invert):
self.write_cmd(SET_NORM_INV | (invert & 1))
def rotate(self, rotate):
self.write_cmd(SET_COM_OUT_DIR | ((rotate & 1) << 3))
self.write_cmd(SET_SEG_REMAP | (rotate & 1))
def show(self):
x0 = 0
x1 = self.width - 1
if self.width != 128:
# narrow displays use centred columns
col_offset = (128 - self.width) // 2
x0 += col_offset
x1 += col_offset
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_data(self.buffer)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
self.write_list = [b"\x40", None] # Co=0, D/C#=1
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_data(self, buf):
self.write_list[1] = buf
self.i2c.writevto(self.addr, self.write_list)
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
self.rate = 10 * 1024 * 1024
dc.init(dc.OUT, value=0)
res.init(res.OUT, value=0)
cs.init(cs.OUT, value=1)
self.spi = spi
self.dc = dc
self.res = res
self.cs = cs
import time
self.res(1)
time.sleep_ms(1)
self.res(0)
time.sleep_ms(10)
self.res(1)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, buf):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(buf)
self.cs(1)
main.py
import oledText
oledText.py
from machine import UART, Pin, I2C, ADC, PWM,SPI
from time import sleep
import ssd1306
import dht
i2c = I2C(1,scl=Pin(15), sda=Pin(14))#I2C설정
oled = ssd1306.SSD1306_I2C(128,64,i2c,0x3c)#OLED설정
uart0 = UART(0, baudrate=115200, bits=8, parity=None, stop=1, tx=Pin(16), rx=Pin(17))# UART 설정
uart0.write("pico sensorBoard Test\n")
oled.fill(1)
oled.show()
sleep(1)
oled.fill(0)
oled.show()
sleep(1)
while True:
oled.fill(0)
oled.text("picoSensorBoard",0,0)
oled.text("picoS/Board",10,15)
oled.text("picoS/Board",20,30)
oled.text("picoS/Board",30,45)
oled.show()
sleep(0.5)
(3) 동작결과
3) OLED에 현재 온도/습도, CdS/가변저항 데이터 출력 제어
(1) 코드작성
dht.py
import sys
if sys.platform.startswith("esp"):
from esp import dht_readinto
elif sys.platform == "mimxrt":
from mimxrt import dht_readinto
elif sys.platform == "rp2":
from rp2 import dht_readinto
elif sys.platform == "pyboard":
from pyb import dht_readinto
else:
from machine import dht_readinto
class DHTBase:
def __init__(self, pin):
self.pin = pin
self.buf = bytearray(5)
def measure(self):
buf = self.buf
dht_readinto(self.pin, buf)
if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xFF != buf[4]:
raise Exception("checksum error")
class DHT11(DHTBase):
def humidity(self):
return self.buf[0]
def temperature(self):
return self.buf[2]
class DHT22(DHTBase):
def humidity(self):
return (self.buf[0] << 8 | self.buf[1]) * 0.1
def temperature(self):
t = ((self.buf[2] & 0x7F) << 8 | self.buf[3]) * 0.1
if self.buf[2] & 0x80:
t = -t
return t
ssd1306.py
상단 참조
main.py
import oledT_H
oledT_H.py
from machine import UART, Pin, I2C, ADC, PWM,SPI
from time import sleep
import ssd1306
import dht
led1 = Pin(2,Pin.OUT)
led2 = Pin(3,Pin.OUT)
CdS_adc = ADC(Pin(27))
vr_adc = ADC(Pin(26))
i2c = I2C(1,scl=Pin(15), sda=Pin(14))#I2C설정
oled = ssd1306.SSD1306_I2C(128,64,i2c,0x3c)#OLED설정
dhtIn = Pin(7,Pin.IN) # 온/습도 센서 설정
dhtOut = dht.DHT11(dhtIn)# 온/습도 센서 설정
uart0 = UART(0, baudrate=115200, bits=8, parity=None, stop=1, tx=Pin(16), rx=Pin(17))# UART 설정
uart0.write("pico sensorBoard Test\n")
oled.fill(1)
oled.show()
led1.value(0)
led2.value(0)
sleep(1)
oled.fill(0)
oled.show()
led1.value(1)
led2.value(1)
sleep(1)
temp=0
humi=0
def tempHumiSensor():
global temp, humi
dhtOut.measure()
temp = dhtOut.temperature()
humi = dhtOut.humidity()
sleep(0.5)
VRData=0
def adcInput(ch):
global VRData
if ch ==0: #VR
VRData = vr_adc.read_u16()
VRDataV = (3.3/65535) * VRData
VRDataV = round(VRDataV,2)
return VRDataV
elif ch ==1: #CdS
CdSData = CdS_adc.read_u16()
CdSDataV = (3.3/65535) * CdSData
CdSDataV = round(CdSDataV,2)
return CdSDataV
while True:
tempHumiSensor()
print('Temperature = {}C Humidity = {}%'.format(temp,humi))
print('VR Volt = {}V CdS Volt = {}V\n'.format(adcInput(0),adcInput(1)))
oled.fill(0)
oled.text("Temp(C) : ",0,0)
oled.text(str(temp),80,0)
oled.text("Humi(%) : ",0,12)
oled.text(str(humi),80,12)
oled.text("CdS(V) : ",0,24)
oled.text(str(adcInput(1)),80,24)
oled.text("VR(V) : ",0,36)
oled.text(str(adcInput(0)),80,36)
oled.show()
sleep(0.5)
(3) 동작결과
온습도 데이터와 CDS ,VR 값이 OLED에 표시 됩니다.
'라즈베리파이_피코_피코 W > 마이크로파이썬' 카테고리의 다른 글
12. 라즈베리파이 피코 서보모터 (0) | 2023.03.06 |
---|---|
11. 라즈베리파이 피코 블루투스/SDCARD (2) | 2023.03.05 |
09. 라즈베리파이 피코 DHT11제어 (0) | 2023.03.03 |
08. 라즈베리파이 피코 릴레이제어 (0) | 2023.03.02 |
07.라즈베리파이 피코 WS2812 (0) | 2023.03.01 |
댓글