目录
简介
我重新写了一个驱动,增加了一些功能,由于我的硬件是128*64oled单色I2C,我只适配了我的硬件。如果你的硬件和我相同,你可以使用我的ssd1306驱动.
我的oled似乎不是ssd1306驱动芯片,而是ssd1315驱动芯片,不过两者差别很小,仅在滚动那块有些许出入
更新时间:2024年12月18日
代码
import framebuf
class SSD1306():
def __init__(self,i2c, addr=0x3c, external_vcc=False):
self.external_vcc = external_vcc
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
# buffer需要8 * 128的显示字节加1字节命令
self.buffer = bytearray(8 * 128 + 1)
self.buffer[0] = 0x40 # Co=0, D/C=1
self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], 128, 64)
self.init_display()
def init_display(self):
for cmd in (
0xae, # 熄屏
0x20, 0x00, # 水平寻址
0x40, # 显示起始行地址
0xa1, # 正常列扫描
0xa8, 63, # 复用率
0xc8, # 正常行扫描
0xd3, 0x00, #设置COM偏移量,即屏幕像上偏移的行数
0xda, 0x12, #使用备选引脚配置,并禁用左右反置
0xd5, 0x80, # 设置分频因子与振荡频率
0xd9, 0x22 if self.external_vcc else 0xf1,
0xdb, 0x30, # 设置vcomh电压为0.83*Vcc
0x81, 0xff, # 亮度最大
0xa4, # 使用GDDRAM中的数据显示
0xa6, # 设置GDDRAM中的0对应于像素点的暗
# 关闭电荷泵
0x8d, 0x10 if self.external_vcc else 0x14,
0x2e, # 禁止滚动
0xaf): #开屏
self.write_cmd(cmd)
self.fill(0)
self.show()
# 中文到字节的转化函数
def cn_to_byte(self,cn:str)->bytearray:
cn_to_byte_dict={
'蓝':bytearray(b'\x04\x04\xe4\x04\x0f\xf4\x04\x04\xf4\x44\xcf\x44\x44\x44\x04\x00\x40\x40\x7d\x44\x44\x7d\x44\x45\x44\x7c\x44\x45\x7c\x40\x40\x00'),
'牙':bytearray(b'\x00\x00\xc2\xb2\x82\x82\x82\x82\x82\xfe\x82\x82\x82\x82\x80\x00\x00\x20\x20\x10\x08\x04\x02\x41\x80\x7f\x00\x00\x00\x00\x00\x00'),
'模':bytearray(b'\x10\x10\xd0\xff\x90\x14\xe4\xaf\xa4\xa4\xa4\xaf\xe4\x04\x00\x00\x04\x03\x00\xff\x00\x89\x4b\x2a\x1a\x0e\x1a\x2a\x4b\x88\x80\x00'),
'式':bytearray(b'\x10\x10\x90\x90\x90\x90\x90\x10\x10\xff\x10\x10\x11\x16\x10\x00\x00\x20\x60\x20\x3f\x10\x10\x10\x00\x03\x0c\x10\x20\x40\xf8\x00'),
'离':bytearray(b'\x04\x04\x04\xf4\x84\xd4\xa5\xa6\xa4\xd4\x84\xf4\x04\x04\x04\x00\x00\xfe\x02\x02\x12\x3a\x16\x13\x12\x1a\x32\x42\x82\x7e\x00\x00'),
'线':bytearray(b'\x20\x30\xac\x63\x20\x18\x80\x90\x90\xff\x90\x49\x4a\x48\x40\x00\x22\x67\x22\x12\x12\x12\x40\x40\x20\x13\x0c\x14\x22\x41\xf8\x00'),
'设':bytearray(b'\x40\x40\x42\xcc\x00\x40\xa0\x9e\x82\x82\x82\x9e\xa0\x20\x20\x00\x00\x00\x00\x3f\x90\x88\x40\x43\x2c\x10\x28\x46\x41\x80\x80\x00'),
'置':bytearray(b'\x00\x17\x15\xd5\x55\x57\x55\x7d\x55\x57\x55\xd5\x15\x17\x00\x00\x40\x40\x40\x7f\x55\x55\x55\x55\x55\x55\x55\x7f\x40\x40\x40\x00'),
'版':bytearray(b'\x00\xfe\x20\x20\x3f\x20\x00\xfc\x24\xe4\x24\x22\x23\xe2\x00\x00\x80\x7f\x01\x01\xff\x80\x60\x1f\x80\x41\x26\x18\x26\x41\x80\x00'),
'本':bytearray(b'\x00\x10\x10\x10\x10\xd0\x30\xff\x30\xd0\x10\x10\x10\x10\x00\x00\x10\x08\x04\x02\x09\x08\x08\xff\x08\x08\x09\x02\x04\x08\x10\x00'),
'连':bytearray(b'\x40\x40\x42\xcc\x00\x04\x44\x64\x5c\x47\xf4\x44\x44\x44\x04\x00\x00\x40\x20\x1f\x20\x44\x44\x44\x44\x44\x7f\x44\x44\x44\x44\x00'),
'接':bytearray(b'\x10\x10\x10\xff\x10\x50\x44\x54\x65\xc6\x44\x64\x54\x44\x40\x00\x04\x44\x82\x7f\x01\x82\x82\x4a\x56\x23\x22\x52\x4e\x82\x02\x00'),
'使':bytearray(b'\x80\x60\xf8\x07\x04\xe4\x24\x24\x24\xff\x24\x24\x24\xe4\x04\x00\x00\x00\xff\x00\x80\x81\x45\x29\x11\x2f\x41\x41\x81\x81\x80\x00'),
'用':bytearray(b'\x00\x00\xfe\x22\x22\x22\x22\xfe\x22\x22\x22\x22\xfe\x00\x00\x00\x80\x60\x1f\x02\x02\x02\x02\x7f\x02\x02\x42\x82\x7f\x00\x00\x00'),
'说':bytearray(b'\x40\x40\x42\xcc\x00\x00\xf1\x16\x10\x10\x18\x14\xf3\x00\x00\x00\x00\x00\x00\x3f\x90\x48\x21\x19\x07\x01\x3f\x41\x41\x40\x70\x00'),
'明':bytearray(b'\x00\xfc\x44\x44\x44\xfc\x00\x00\xfe\x22\x22\x22\x22\xfe\x00\x00\x00\x0f\x04\x04\x04\x8f\x40\x30\x0f\x02\x02\x42\x82\x7f\x00\x00'),
'开':bytearray(b'\x80\x82\x82\x82\xfe\x82\x82\x82\x82\x82\xfe\x82\x82\x82\x80\x00\x00\x80\x40\x30\x0f\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00'),
'始':bytearray(b'\x10\x10\xf0\x1f\x10\xf0\x00\x40\xe0\x58\x47\x40\x50\x60\xc0\x00\x40\x22\x15\x08\x16\x21\x00\x00\xfe\x42\x42\x42\x42\xfe\x00\x00'),
'校':bytearray(b'\x10\x10\xd0\xff\x90\x10\x80\x48\x28\x09\x0e\x08\x28\x48\x88\x00\x04\x03\x00\xff\x00\x01\x80\x80\x43\x2c\x10\x2c\x43\x80\x80\x00'),
'准':bytearray(b'\x00\x02\x0c\xe0\x40\x20\xf8\x4f\x48\x49\xfe\x48\x48\x48\x08\x00\x04\x04\x7f\x00\x00\x00\xff\x22\x22\x22\x3f\x22\x22\x22\x20\x00'),
'滴':bytearray(b'\x10\x60\x02\x8c\x00\xe4\x24\xac\xb5\xe6\xb4\xac\x24\xe4\x00\x00\x04\x04\x7e\x01\x00\xff\x00\x1e\x12\x13\x12\x5e\x80\x7f\x00\x00'),
'定':bytearray(b'\x10\x0c\x44\x44\x44\x44\x45\xc6\x44\x44\x44\x44\x44\x14\x0c\x00\x80\x40\x20\x1e\x20\x40\x40\x7f\x44\x44\x44\x44\x44\x40\x40\x00'),
'检':bytearray(b'\x10\x10\xd0\xff\x90\x50\x20\x50\x4c\x43\x4c\x50\x20\x40\x40\x00\x04\x03\x00\xff\x00\x41\x44\x58\x41\x4e\x60\x58\x47\x40\x40\x00'),
'查':bytearray(b'\x40\x44\x24\xa4\x94\x8c\x84\xff\x84\x8c\x94\xa4\x24\x44\x40\x00\x40\x40\x40\x5f\x4a\x4a\x4a\x4a\x4a\x4a\x4a\x5f\x40\x40\x40\x00'),
'更':bytearray(b'\x02\x02\xf2\x92\x92\x92\x92\xfe\x92\x92\x92\x92\xf2\x02\x02\x00\x80\x80\x87\x4c\x54\x24\x34\x4f\x44\x44\x84\x84\x87\x80\x80\x00'),
'新':bytearray(b'\x40\x44\x54\x65\xc6\x64\x54\x44\x00\xfc\x44\x44\xc4\x42\x40\x00\x20\x12\x4a\x82\x7f\x02\x0a\x92\x60\x1f\x00\x00\xff\x00\x00\x00'),
'速':bytearray(b'\x40\x40\x42\xcc\x00\x04\xf4\x94\x94\xff\x94\x94\xf4\x04\x00\x00\x00\x40\x20\x1f\x20\x48\x44\x42\x41\x5f\x41\x42\x44\x48\x40\x00'),
'度':bytearray(b'\x00\x00\xfc\x24\x24\x24\xfc\x25\x26\x24\xfc\x24\x24\x24\x04\x00\x40\x30\x8f\x80\x84\x4c\x55\x25\x25\x25\x55\x4c\x80\x80\x80\x00'),
'中':bytearray(b'\x00\x00\xf0\x10\x10\x10\x10\xff\x10\x10\x10\x10\xf0\x00\x00\x00\x00\x00\x0f\x04\x04\x04\x04\xff\x04\x04\x04\x04\x0f\x00\x00\x00'),
'打':bytearray(b'\x10\x10\x10\xff\x10\x90\x04\x04\x04\x04\xfc\x04\x04\x04\x04\x00\x04\x44\x82\x7f\x01\x00\x00\x00\x40\x80\x7f\x00\x00\x00\x00\x00'),
'小':bytearray(b'\x00\x00\x00\xe0\x00\x00\x00\xff\x00\x00\x00\x20\x40\x80\x00\x00\x08\x04\x03\x00\x00\x40\x80\x7f\x00\x00\x00\x00\x00\x01\x0e\x00'),
'程':bytearray(b'\x24\x24\xa4\xfe\x23\x22\x00\x3e\x22\x22\x22\x22\x22\x3e\x00\x00\x08\x06\x01\xff\x01\x06\x40\x49\x49\x49\x7f\x49\x49\x49\x41\x00'),
'序':bytearray(b'\x00\x00\xfc\x04\x04\x04\x14\x15\x56\x94\x54\x34\x14\x04\x04\x00\x40\x30\x0f\x00\x01\x01\x01\x41\x81\x7f\x01\x01\x01\x05\x03\x00'),
'自':bytearray(b'\x00\x00\x00\xf8\x88\x8c\x8a\x89\x88\x88\x88\xf8\x00\x00\x00\x00\x00\x00\x00\xff\x44\x44\x44\x44\x44\x44\x44\xff\x00\x00\x00\x00'),
'动':bytearray(b'\x40\x44\xc4\x44\x44\x44\x40\x10\x10\xff\x10\x10\x10\xf0\x00\x00\x10\x3c\x13\x10\x14\xb8\x40\x30\x0e\x01\x40\x80\x40\x3f\x00\x00'),
'仪':bytearray(b'\x00\x80\x60\xf8\x07\x00\x1c\xe0\x01\x06\x00\xe0\x1e\x00\x00\x00\x01\x00\x00\xff\x00\x80\x40\x20\x13\x0c\x13\x20\x40\x80\x80\x00'),
'名':bytearray(b'\x00\x20\x20\x10\x08\x14\x67\x84\x44\x24\x14\x0c\x00\x00\x00\x00\x04\x04\x04\x02\xfe\x43\x43\x42\x42\x42\x42\x42\xfe\x00\x00\x00'),
'泵':bytearray(b'\x42\x42\x22\x12\xfa\x96\x92\x92\x92\x92\x92\xf2\x02\x02\x02\x00\x40\x44\x24\x14\x0c\x44\x80\x7f\x04\x08\x10\x28\x24\x42\x40\x00')
}
return cn_to_byte_dict[cn]
def poweroff(self):
self.write_cmd(0xae)#熄屏
#亮度,0x00-0xff
def contrast(self, contrast):
self.write_cmd(0x81)
self.write_cmd(contrast)
#正反相显示,输入1则反相,默认正相
def invert(self, invert=0):
self.write_cmd(0xa6 | invert)
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_framebuf(self):
self.i2c.writeto(self.addr, self.buffer)
def show(self):
self.write_cmd(0x21) # 告诉GDDRAM列数
self.write_cmd(0) # 列数从0-127
self.write_cmd(127)
self.write_cmd(0x22) # 告诉GDDRAM行数
self.write_cmd(0) # 页数从0-7
self.write_cmd(7)
self.write_framebuf() # 写入1bit地址和1024bit数据
def fill(self, c):
self.framebuf.fill(c)
def pic(self,buf:bytearray,w:int,h:int,x:int,y:int):
buf=framebuf.FrameBuffer(buf,w,h,framebuf.MONO_VLSB)
self.framebuf.blit(buf,x,y)
def pixel(self, x, y, c=1):
self.framebuf.pixel(x, y, c)
#设置水平滚动,参数:滚动区域(滚动起始页,滚动结束页),滚动方向(默认向左,填0向右),滚动速度(0-7)
def h_scroll(self,start=0,end=7,d=1,speed=0):
self.write_cmd(0x2e) # 关闭滚动
self.write_cmd(0x26+d) # 向左
self.write_cmd(0x00)
self.write_cmd(start) # 起始页
self.write_cmd(speed) # 滚动帧率
self.write_cmd(end) # 结束页
self.write_cmd(0x00)
self.write_cmd(0xff)
self.write_cmd(0x2f) # 开启滚动
# 默认开启竖直向上滚动与水平向右滚动
def scroll(self,vScrollOn=0,vStart=0,vEnd=63,vSpeed=1,hScrollOn=1,direction=0,hSpeed=0,hScrollStartPage=0,hScrollEndPage=7,
hScrollStartColumn=0,hScrollEndColumn=127):
if vScrollOn:
self.write_cmd(0x2e)# 关闭滚动
self.write_cmd(0xa3)#设置竖直滚动命令
self.write_cmd(vStart)#竖直滚动开始行
self.write_cmd(vEnd)#竖直滚动结束行
self.write_cmd(0x29+direction)#水平滚动方向向右
self.write_cmd(hScrollOn) # 0,关闭水平滚动,1开启
self.write_cmd(hScrollStartPage)# 水平滚动起始页
self.write_cmd(hSpeed)#设置滚动速度0-7
self.write_cmd(hScrollEndPage)# 水平滚动结束页
self.write_cmd(vSpeed) # 每一帧的垂直偏移量
self.write_cmd(hScrollStartColumn)#水平滚动区域的起始列
self.write_cmd(hScrollEndColumn)#水平滚动区域的结束列
self.write_cmd(0x2f)# 开启滚动
# 中英文文本
def text(self,s,x,y):
start_positon=x
for t in s:
if ord(t)<128:
self.framebuf.text(t,start_positon,y+4)
start_positon+=8
else:
self.framebuf.blit(framebuf.FrameBuffer(self.cn_to_byte(t),16,16,framebuf.MONO_VLSB),start_positon,y)
start_positon+=16
# 英文文本
def en_text(self,s,x,y,c=1):
self.framebuf.text(s,x,y,c)
# 中文文本
def cn_text(self,s,x,y):
for i,t in enumerate(s):
buf=framebuf.FrameBuffer(self.cn_to_byte(t),16,16,framebuf.MONO_VLSB)
self.framebuf.blit(buf,x+i*16,y)
def cube(self,x,y,l):
self.rect(x,y,l,l)
self.rect(x+int(0.5*l),int(y-0.5*l),l,l)
self.line(x,y,int(x+0.5*l),int(y-0.5*l))
self.line(x+l-1,y,int(x+1.5*l-1),int(y-0.5*l))
self.line(x-1,y+l,int(x+0.5*l),int(y+0.5*l-1))
self.line(x+l-1,y+l-1,int(x+1.5*l-1),int(y+0.5*l-1))
#画水平直线
def hline(self,x,y,w,c=1):
self.framebuf.hline(x,y,w,c)
#画竖直直线
def vline(self,x,y,h,c=1):
self.framebuf.vline(x,y,h,c)
#画任意直线
def line(self,x1,y1,x2,y2,c=1):
self.framebuf.line(x1,y1,x2,y2,c)
#画矩形,参数:起始左上角坐标,长宽,颜色默认为亮,是否填充
def rect(self,x,y,w,h,c=1,f=False):
self.framebuf.rect(x,y,w,h,c,f)
#画椭圆,参数:起始圆心坐标,x半径,y半径,颜色默认为亮,是否填充,显示象限(0-15的数字)
def ellipse(self,x,y,xr,yr,c=1,f=False,m=15):
self.framebuf.ellipse(x,y,xr,yr,c,f,m)
if __name__=='__main__':
from machine import Pin,SoftI2C
i2c=SoftI2C(scl=Pin(5),sda=Pin(4))
o=SSD1306(i2c)
o.ellipse(30,30,20,10)
o.show()
或者使用如下占用存储空间更少的代码
import framebuf
class SSD1306():
def __init__(self,i2c, addr=0x3c, external_vcc=False):
self.external_vcc = external_vcc
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
self.buffer = bytearray(8 * 128 + 1)
self.buffer[0] = 0x40 # Co=0, D/C=1
self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], 128, 64)
self.init_display()
def init_display(self):
for cmd in (0xae,0x20, 0x00,0x40,0xa1,0xa8, 63,0xc8,0xd3, 0x00,0xda, 0x12,0xd5, 0x80,0xd9, 0x22 if self.external_vcc else 0xf1,0xdb, 0x30,0x81, 0xff,0xa4,0xa6,0x8d, 0x10 if self.external_vcc else 0x14,0x2e,0xaf):
self.write_cmd(cmd)
self.fill(0)
self.show()
def cn_to_byte(self,cn:str)->bytearray:
cn_to_byte_dict={
'蓝':bytearray(b'\x04\x04\xe4\x04\x0f\xf4\x04\x04\xf4\x44\xcf\x44\x44\x44\x04\x00\x40\x40\x7d\x44\x44\x7d\x44\x45\x44\x7c\x44\x45\x7c\x40\x40\x00'),
'牙':bytearray(b'\x00\x00\xc2\xb2\x82\x82\x82\x82\x82\xfe\x82\x82\x82\x82\x80\x00\x00\x20\x20\x10\x08\x04\x02\x41\x80\x7f\x00\x00\x00\x00\x00\x00'),
'模':bytearray(b'\x10\x10\xd0\xff\x90\x14\xe4\xaf\xa4\xa4\xa4\xaf\xe4\x04\x00\x00\x04\x03\x00\xff\x00\x89\x4b\x2a\x1a\x0e\x1a\x2a\x4b\x88\x80\x00'),
'式':bytearray(b'\x10\x10\x90\x90\x90\x90\x90\x10\x10\xff\x10\x10\x11\x16\x10\x00\x00\x20\x60\x20\x3f\x10\x10\x10\x00\x03\x0c\x10\x20\x40\xf8\x00'),
'离':bytearray(b'\x04\x04\x04\xf4\x84\xd4\xa5\xa6\xa4\xd4\x84\xf4\x04\x04\x04\x00\x00\xfe\x02\x02\x12\x3a\x16\x13\x12\x1a\x32\x42\x82\x7e\x00\x00'),
'线':bytearray(b'\x20\x30\xac\x63\x20\x18\x80\x90\x90\xff\x90\x49\x4a\x48\x40\x00\x22\x67\x22\x12\x12\x12\x40\x40\x20\x13\x0c\x14\x22\x41\xf8\x00'),
'设':bytearray(b'\x40\x40\x42\xcc\x00\x40\xa0\x9e\x82\x82\x82\x9e\xa0\x20\x20\x00\x00\x00\x00\x3f\x90\x88\x40\x43\x2c\x10\x28\x46\x41\x80\x80\x00'),
'置':bytearray(b'\x00\x17\x15\xd5\x55\x57\x55\x7d\x55\x57\x55\xd5\x15\x17\x00\x00\x40\x40\x40\x7f\x55\x55\x55\x55\x55\x55\x55\x7f\x40\x40\x40\x00'),
'版':bytearray(b'\x00\xfe\x20\x20\x3f\x20\x00\xfc\x24\xe4\x24\x22\x23\xe2\x00\x00\x80\x7f\x01\x01\xff\x80\x60\x1f\x80\x41\x26\x18\x26\x41\x80\x00'),
'本':bytearray(b'\x00\x10\x10\x10\x10\xd0\x30\xff\x30\xd0\x10\x10\x10\x10\x00\x00\x10\x08\x04\x02\x09\x08\x08\xff\x08\x08\x09\x02\x04\x08\x10\x00'),
'连':bytearray(b'\x40\x40\x42\xcc\x00\x04\x44\x64\x5c\x47\xf4\x44\x44\x44\x04\x00\x00\x40\x20\x1f\x20\x44\x44\x44\x44\x44\x7f\x44\x44\x44\x44\x00'),
'接':bytearray(b'\x10\x10\x10\xff\x10\x50\x44\x54\x65\xc6\x44\x64\x54\x44\x40\x00\x04\x44\x82\x7f\x01\x82\x82\x4a\x56\x23\x22\x52\x4e\x82\x02\x00'),
'使':bytearray(b'\x80\x60\xf8\x07\x04\xe4\x24\x24\x24\xff\x24\x24\x24\xe4\x04\x00\x00\x00\xff\x00\x80\x81\x45\x29\x11\x2f\x41\x41\x81\x81\x80\x00'),
'用':bytearray(b'\x00\x00\xfe\x22\x22\x22\x22\xfe\x22\x22\x22\x22\xfe\x00\x00\x00\x80\x60\x1f\x02\x02\x02\x02\x7f\x02\x02\x42\x82\x7f\x00\x00\x00'),
'说':bytearray(b'\x40\x40\x42\xcc\x00\x00\xf1\x16\x10\x10\x18\x14\xf3\x00\x00\x00\x00\x00\x00\x3f\x90\x48\x21\x19\x07\x01\x3f\x41\x41\x40\x70\x00'),
'明':bytearray(b'\x00\xfc\x44\x44\x44\xfc\x00\x00\xfe\x22\x22\x22\x22\xfe\x00\x00\x00\x0f\x04\x04\x04\x8f\x40\x30\x0f\x02\x02\x42\x82\x7f\x00\x00'),
'开':bytearray(b'\x80\x82\x82\x82\xfe\x82\x82\x82\x82\x82\xfe\x82\x82\x82\x80\x00\x00\x80\x40\x30\x0f\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00'),
'始':bytearray(b'\x10\x10\xf0\x1f\x10\xf0\x00\x40\xe0\x58\x47\x40\x50\x60\xc0\x00\x40\x22\x15\x08\x16\x21\x00\x00\xfe\x42\x42\x42\x42\xfe\x00\x00'),
'校':bytearray(b'\x10\x10\xd0\xff\x90\x10\x80\x48\x28\x09\x0e\x08\x28\x48\x88\x00\x04\x03\x00\xff\x00\x01\x80\x80\x43\x2c\x10\x2c\x43\x80\x80\x00'),
'准':bytearray(b'\x00\x02\x0c\xe0\x40\x20\xf8\x4f\x48\x49\xfe\x48\x48\x48\x08\x00\x04\x04\x7f\x00\x00\x00\xff\x22\x22\x22\x3f\x22\x22\x22\x20\x00'),
'滴':bytearray(b'\x10\x60\x02\x8c\x00\xe4\x24\xac\xb5\xe6\xb4\xac\x24\xe4\x00\x00\x04\x04\x7e\x01\x00\xff\x00\x1e\x12\x13\x12\x5e\x80\x7f\x00\x00'),
'定':bytearray(b'\x10\x0c\x44\x44\x44\x44\x45\xc6\x44\x44\x44\x44\x44\x14\x0c\x00\x80\x40\x20\x1e\x20\x40\x40\x7f\x44\x44\x44\x44\x44\x40\x40\x00'),
'检':bytearray(b'\x10\x10\xd0\xff\x90\x50\x20\x50\x4c\x43\x4c\x50\x20\x40\x40\x00\x04\x03\x00\xff\x00\x41\x44\x58\x41\x4e\x60\x58\x47\x40\x40\x00'),
'查':bytearray(b'\x40\x44\x24\xa4\x94\x8c\x84\xff\x84\x8c\x94\xa4\x24\x44\x40\x00\x40\x40\x40\x5f\x4a\x4a\x4a\x4a\x4a\x4a\x4a\x5f\x40\x40\x40\x00'),
'更':bytearray(b'\x02\x02\xf2\x92\x92\x92\x92\xfe\x92\x92\x92\x92\xf2\x02\x02\x00\x80\x80\x87\x4c\x54\x24\x34\x4f\x44\x44\x84\x84\x87\x80\x80\x00'),
'新':bytearray(b'\x40\x44\x54\x65\xc6\x64\x54\x44\x00\xfc\x44\x44\xc4\x42\x40\x00\x20\x12\x4a\x82\x7f\x02\x0a\x92\x60\x1f\x00\x00\xff\x00\x00\x00'),
'速':bytearray(b'\x40\x40\x42\xcc\x00\x04\xf4\x94\x94\xff\x94\x94\xf4\x04\x00\x00\x00\x40\x20\x1f\x20\x48\x44\x42\x41\x5f\x41\x42\x44\x48\x40\x00'),
'度':bytearray(b'\x00\x00\xfc\x24\x24\x24\xfc\x25\x26\x24\xfc\x24\x24\x24\x04\x00\x40\x30\x8f\x80\x84\x4c\x55\x25\x25\x25\x55\x4c\x80\x80\x80\x00'),
'中':bytearray(b'\x00\x00\xf0\x10\x10\x10\x10\xff\x10\x10\x10\x10\xf0\x00\x00\x00\x00\x00\x0f\x04\x04\x04\x04\xff\x04\x04\x04\x04\x0f\x00\x00\x00'),
'打':bytearray(b'\x10\x10\x10\xff\x10\x90\x04\x04\x04\x04\xfc\x04\x04\x04\x04\x00\x04\x44\x82\x7f\x01\x00\x00\x00\x40\x80\x7f\x00\x00\x00\x00\x00'),
'小':bytearray(b'\x00\x00\x00\xe0\x00\x00\x00\xff\x00\x00\x00\x20\x40\x80\x00\x00\x08\x04\x03\x00\x00\x40\x80\x7f\x00\x00\x00\x00\x00\x01\x0e\x00'),
'程':bytearray(b'\x24\x24\xa4\xfe\x23\x22\x00\x3e\x22\x22\x22\x22\x22\x3e\x00\x00\x08\x06\x01\xff\x01\x06\x40\x49\x49\x49\x7f\x49\x49\x49\x41\x00'),
'序':bytearray(b'\x00\x00\xfc\x04\x04\x04\x14\x15\x56\x94\x54\x34\x14\x04\x04\x00\x40\x30\x0f\x00\x01\x01\x01\x41\x81\x7f\x01\x01\x01\x05\x03\x00'),
'自':bytearray(b'\x00\x00\x00\xf8\x88\x8c\x8a\x89\x88\x88\x88\xf8\x00\x00\x00\x00\x00\x00\x00\xff\x44\x44\x44\x44\x44\x44\x44\xff\x00\x00\x00\x00'),
'动':bytearray(b'\x40\x44\xc4\x44\x44\x44\x40\x10\x10\xff\x10\x10\x10\xf0\x00\x00\x10\x3c\x13\x10\x14\xb8\x40\x30\x0e\x01\x40\x80\x40\x3f\x00\x00'),
'仪':bytearray(b'\x00\x80\x60\xf8\x07\x00\x1c\xe0\x01\x06\x00\xe0\x1e\x00\x00\x00\x01\x00\x00\xff\x00\x80\x40\x20\x13\x0c\x13\x20\x40\x80\x80\x00'),
'名':bytearray(b'\x00\x20\x20\x10\x08\x14\x67\x84\x44\x24\x14\x0c\x00\x00\x00\x00\x04\x04\x04\x02\xfe\x43\x43\x42\x42\x42\x42\x42\xfe\x00\x00\x00'),
'泵':bytearray(b'\x42\x42\x22\x12\xfa\x96\x92\x92\x92\x92\x92\xf2\x02\x02\x02\x00\x40\x44\x24\x14\x0c\x44\x80\x7f\x04\x08\x10\x28\x24\x42\x40\x00')
}
return cn_to_byte_dict[cn]
def poweroff(self):
self.write_cmd(0xae)#熄屏
def contrast(self, contrast):
self.write_cmd(0x81)
self.write_cmd(contrast)
def invert(self, invert=0):
self.write_cmd(0xa6 | invert)
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_framebuf(self):
self.i2c.writeto(self.addr, self.buffer)
def show(self):
self.write_cmd(0x21) # 告诉GDDRAM列数
self.write_cmd(0) # 列数从0-127
self.write_cmd(127)
self.write_cmd(0x22) # 告诉GDDRAM行数
self.write_cmd(0) # 页数从0-7
self.write_cmd(7)
self.write_framebuf() # 写入1bit地址和1024bit数据
def fill(self, c):
self.framebuf.fill(c)
def pic(self,buf:bytearray,w:int,h:int,x:int,y:int):
buf=framebuf.FrameBuffer(buf,w,h,framebuf.MONO_VLSB)
self.framebuf.blit(buf,x,y)
def pixel(self, x, y, c=1):
self.framebuf.pixel(x, y, c)
def h_scroll(self,start=0,end=7,d=1,speed=0):
self.write_cmd(0x2e) # 关闭滚动
self.write_cmd(0x26+d) # 向左
self.write_cmd(0x00)
self.write_cmd(start) # 起始页
self.write_cmd(speed) # 滚动帧率
self.write_cmd(end) # 结束页
self.write_cmd(0x00)
self.write_cmd(0xff)
self.write_cmd(0x2f) # 开启滚动
def scroll(self,vScrollOn=0,vStart=0,vEnd=63,vSpeed=1,hScrollOn=1,direction=0,hSpeed=0,hScrollStartPage=0,hScrollEndPage=7,hScrollStartColumn=0,hScrollEndColumn=127):
if vScrollOn:
self.write_cmd(0x2e)# 关闭滚动
self.write_cmd(0xa3)#设置竖直滚动命令
self.write_cmd(vStart)#竖直滚动开始行
self.write_cmd(vEnd)#竖直滚动结束行
self.write_cmd(0x29+direction)#水平滚动方向向右
self.write_cmd(hScrollOn) # 0,关闭水平滚动,1开启
self.write_cmd(hScrollStartPage)# 水平滚动起始页
self.write_cmd(hSpeed)#设置滚动速度0-7
self.write_cmd(hScrollEndPage)# 水平滚动结束页
self.write_cmd(vSpeed) # 每一帧的垂直偏移量
self.write_cmd(hScrollStartColumn)#水平滚动区域的起始列
self.write_cmd(hScrollEndColumn)#水平滚动区域的结束列
self.write_cmd(0x2f)# 开启滚动
def text(self,s,x,y):
start_positon=x
for t in s:
if ord(t)<128:
self.framebuf.text(t,start_positon,y+4)
start_positon+=8
else:
self.framebuf.blit(framebuf.FrameBuffer(self.cn_to_byte(t),16,16,framebuf.MONO_VLSB),start_positon,y)
start_positon+=16
def en_text(self,s,x,y,c=1):
self.framebuf.text(s,x,y,c)
def cn_text(self,s,x,y):
for i,t in enumerate(s):
buf=framebuf.FrameBuffer(self.cn_to_byte(t),16,16,framebuf.MONO_VLSB)
self.framebuf.blit(buf,x+i*16,y)
def cube(self,x,y,l):
self.rect(x,y,l,l)
self.rect(x+int(0.5*l),int(y-0.5*l),l,l)
self.line(x,y,int(x+0.5*l),int(y-0.5*l))
self.line(x+l-1,y,int(x+1.5*l-1),int(y-0.5*l))
self.line(x-1,y+l,int(x+0.5*l),int(y+0.5*l-1))
self.line(x+l-1,y+l-1,int(x+1.5*l-1),int(y+0.5*l-1))
def hline(self,x,y,w,c=1):
self.framebuf.hline(x,y,w,c)
def vline(self,x,y,h,c=1):
self.framebuf.vline(x,y,h,c)
def line(self,x1,y1,x2,y2,c=1):
self.framebuf.line(x1,y1,x2,y2,c)
def rect(self,x,y,w,h,c=1,f=False):
self.framebuf.rect(x,y,w,h,c,f)
def ellipse(self,x,y,xr,yr,c=1,f=False,m=15):
self.framebuf.ellipse(x,y,xr,yr,c,f,m)
if __name__=='__main__':
from machine import Pin,I2C
o=SSD1306(I2C(0,scl=Pin(5),sda=Pin(4)))
o.ellipse(30,30,20,10)
o.show()
功能
显示ASCII字符
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
oled.en_text('hello world',0,0)
oled.show()
显示中文字符
本代码只添加了少数字符,适配我的应用场景,你可以自行取模添加,取模方式为纵向,低位在上,从左往右按列扫描,再从下8行开始反复。以字节的形式存储。
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
oled.cn_text('蓝牙',0,0)
oled.show()
显示中英文混合字符
from machine import Pin,I2C
from ssd1306 import SSD1306
oled=SSD1306(I2C(0,scl=Pin(15),sda=Pin(16)))
oled.text('hello蓝牙hello',0,0)
oled.show()
显示任意图片
from machine import Pin,I2C
from ssd1306 import SSD1306
oled=SSD1306(I2C(0,scl=Pin(15),sda=Pin(16)))
x=bytearray(b'\xf8\x06\x02\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xf9\xf9\x19\x31\x61\xc1\x81\x01\x01\x01\x01\x01\x01\x01\x02\x06\xf8\xff\x00\x00\x00\x00\x00\x00\x00\x06\x0c\x18\x30\x60\xc0\x80\xff\xff\xc0\x60\x30\x18\x0d\x07\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x60\x30\x18\x0c\x06\x03\x01\xff\xff\x03\x06\x0c\x18\xb0\xe0\x40\x00\x00\x00\x00\x00\x00\x00\xff\x1f\x60\x40\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x9f\x9f\x98\x8c\x86\x83\x81\x80\x80\x80\x80\x80\x80\x80\x40\x60\x1f')
# bytearray类型编码的图片 图片宽度 图片长度 左上角定位坐标x 左上角定位坐标y
oled.pic(x,32,32,48,16)
oled.show()
画任意直线
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
oled.line(0,2,50,60)
oled.show()
画横线
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
oled.hline(2,30,80)
oled.show()
画竖线
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
oled.vline(20,0,40)
oled.show()
画矩形
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
#左上角x,y坐标,长,宽
oled.rect(20,0,40,20)
oled.show()
画椭圆
众所周知,圆也是椭圆的一种
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
参数,中心点x,y坐标,x轴向半径,y轴向半径,f=True为填充,默认不填充
oled.ellipse(20,30,10,20)
oled.ellipse(60,20,10,20,f=True)
oled.show()
还有一个参数非常奇怪,不常用,自己改数字(范围0-15)体会
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
oled.ellipse(60,20,10,20,m=5)
oled.show()
画立方体
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
#左前顶面的xy坐标,边长
oled.cube(10,10,20)
oled.show()
画点阵图
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
pic=[0x04,0x06,0xFF,0x97,0x57,0x37,0x16,0x04]
#8*8点阵数据,图像左上角xy坐标。16*16,32*32的也一样,只不过改函数名oled.p16()而已
oled.p8(pic,30,30)
oled.show()
翻转
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
pic1=[0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x0F,0x00,0x00,0x00,
0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0xF0,0x00,0x00,0x00]
pic2=[0x00,0x7F,0x40,0x48,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x48,0x40,0x7F,0x00,0x00,
0x00,0xFF,0x02,0x12,0x12,0x12,0x12,0xF2,0x12,0x52,0x32,0x12,0x02,0xFF,0x00,0x00]
oled.p16(pic1,0,0)
oled.p16(pic2,16,0)
oled.show()
#以中心竖直轴翻转,填1则正常显示
oled.vv(0)
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
pic1=[0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x0F,0x00,0x00,0x00,
0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0xF0,0x00,0x00,0x00]
pic2=[0x00,0x7F,0x40,0x48,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x48,0x40,0x7F,0x00,0x00,
0x00,0xFF,0x02,0x12,0x12,0x12,0x12,0xF2,0x12,0x52,0x32,0x12,0x02,0xFF,0x00,0x00]
oled.p16(pic1,0,0)
oled.p16(pic2,16,0)
oled.show()
#以中心水平轴翻转
oled.hv(0)
反相
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
pic1=[0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x0F,0x00,0x00,0x00,
0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0xF0,0x00,0x00,0x00]
pic2=[0x00,0x7F,0x40,0x48,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x48,0x40,0x7F,0x00,0x00,
0x00,0xFF,0x02,0x12,0x12,0x12,0x12,0xF2,0x12,0x52,0x32,0x12,0x02,0xFF,0x00,0x00]
oled.p16(pic1,0,0)
oled.p16(pic2,16,0)
oled.show()
#默认不反相,即默认0
oled.invert(1)
滚动
横向滚动
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
pic1=[0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x0F,0x00,0x00,0x00,
0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0xF0,0x00,0x00,0x00]
pic2=[0x00,0x7F,0x40,0x48,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x48,0x40,0x7F,0x00,0x00,
0x00,0xFF,0x02,0x12,0x12,0x12,0x12,0xF2,0x12,0x52,0x32,0x12,0x02,0xFF,0x00,0x00]
oled.p16(pic1,0,0)
oled.p16(pic2,16,0)
oled.show()
#默认整个页面一起滚动
#参数:
#滚动起始页,滚动结束页
#滚动方向(默认向左,填0向右)
#滚动速度(0-7,默认0,不一定数字越大速度越大)
oled.h_scroll()
oled横滚
纵向滚动
目前我只能实现向上滚,还有点bug
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
pic1=[0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x0F,0x00,0x00,0x00,
0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0xF0,0x00,0x00,0x00]
pic2=[0x00,0x7F,0x40,0x48,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x48,0x40,0x7F,0x00,0x00,
0x00,0xFF,0x02,0x12,0x12,0x12,0x12,0xF2,0x12,0x52,0x32,0x12,0x02,0xFF,0x00,0x00]
oled.p16(pic1,0,0)
oled.p16(pic2,16,0)
oled.show()
oled.scroll(hScrollOn=0)
oled纵滚
奇葩滚动
这个函数比较复杂可实现斜着动,不同区域各动各的,有点bug
from ssd1306 import SSD1306_I2C
from machine import Pin,I2C
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
pic1=[0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x0F,0x00,0x00,0x00,
0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0xF0,0x00,0x00,0x00]
pic2=[0x00,0x7F,0x40,0x48,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x48,0x40,0x7F,0x00,0x00,
0x00,0xFF,0x02,0x12,0x12,0x12,0x12,0xF2,0x12,0x52,0x32,0x12,0x02,0xFF,0x00,0x00]
oled.p16(pic1,0,0)
oled.p16(pic2,16,0)
oled.show()
#10个参数。均有默认值
#vScrollOn,是否开启竖直滚动(默认0,关闭竖直滚动;置1开启)
#vStart,竖直滚动开始行
#vEnd,竖直滚动结束行
#vSpeed,竖直滚动速度,数字越大越快
#hScrollOn,是否开启横向滚动(默认开启,置0关闭)
#direction,横滚方向(默认向右,置1向左)
#hSpeed,横滚速度(0-7)
#hScrollStartPage,水平滚动起始页默认0
#hScrollEndPage,水平滚动结束页默认7
#hScrollStartColumn,水平滚动区域的起始列,默认0
#hScrollEndColumn,#水平滚动区域的结束列,默认127
oled.scroll()
oled滚滚滚