七仔的博客

七仔的博客GithubPages分博

0%

使用MircoPython在ESP32的OLED屏幕上显示个小电视

是拿几根线组合出来的,随便画了画,作用相当于个Hello World

使用MircoPython在ESP32的OLED屏幕上显示个小电视

一、展示

是拿几根线组合出来的,随便画了画,作用相当于个Hello World

oled小电视

二、材料:

  • ESP32(使用MircoPython的固件)
  • 0.96寸OLED屏幕(4口)和杜邦线若干

三、ESP32和OLED屏幕的连接

ESP端 屏幕端

3V3 ———- VCC

GEN ———- GEN

D4 ———- SDA

D5 ———- SCL

四、源码

main.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from machine import I2C, Pin, RTC
from ssd1306 import SSD1306_I2C

i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=40000)
oled = SSD1306_I2C(128, 64, i2c)
rtc = RTC()
# 上面横线
oled.line(10, 10, 117, 10, 1)
# 右上角斜线
oled.line(117, 10, 127, 20, 1)
# 右边竖线
oled.line(127, 20, 127, 53, 1)
# 右下角斜线
oled.line(127, 53, 117, 63, 1)
# 下面横线
oled.line(10, 63, 117, 63, 1)
# 左下角斜线
oled.line(0, 53, 10, 63, 1)
# 左边竖线
oled.line(0, 20, 0, 53, 1)
# 左上角斜线
oled.line(10, 10, 0, 20, 1)
# 天线左
oled.line(32, 0, 42, 10, 1)
# 天线右边
oled.line(92, 0, 82, 10, 1)
# 眼睛左边
oled.line(42, 20, 22, 30, 1)
# 眼睛右边
oled.line(82, 20, 102, 30, 1)
# 嘴1
oled.line(42, 40, 51, 50, 1)
# 嘴2
oled.line(51, 50, 60, 40, 1)
# 嘴3
oled.line(60, 40, 69, 50, 1)
# 嘴4
oled.line(69, 50, 78, 40, 1)
oled.show()

ssd1306.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces

import time
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_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)


class SSD1306:
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
# Note the subclass must initialize self.framebuf to a framebuffer.
# This is necessary because the underlying data buffer is different
# between I2C and SPI implementations (I2C needs an extra byte).
self.poweron()
self.init_display()

def init_display(self):
for cmd in (
SET_DISP | 0x00, # off
# address setting
SET_MEM_ADDR, 0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE | 0x00,
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.height == 32 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
# charge pump
SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01): # on
self.write_cmd(cmd)
self.fill(0)
self.show()

def poweroff(self):
self.write_cmd(SET_DISP | 0x00)

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 show(self):
x0 = 0
x1 = self.width - 1
if self.width == 64:
# displays with width of 64 pixels are shifted by 32
x0 += 32
x1 += 32
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_framebuf()

# 填充画面 0为空 1为亮
def fill(self, col):
self.framebuf.fill(col)

# 填充一个像素在X,YE
def pixel(self, x, y, col):
self.framebuf.pixel(x, y, col)

# 滚动
def scroll(self, dx, dy):
self.framebuf.scroll(dx, dy)

# 文本
def text(self, string, x, y, col=1):
self.framebuf.text(string, x, y, col)

def line(self, x1, y1, x2, y2, col=1):
self.framebuf.line(x1, y1, x2, y2, col)

def line(self, x1, y1, x2, y2, col=1):
self.framebuf.line(x1, y1, x2, y2, col)


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)
# Add an extra byte to the data buffer to hold an I2C data/command byte
# to use hardware-compatible I2C transactions. A memoryview of the
# buffer is used to mask this byte from the framebuffer operations
# (without a major memory hit as memoryview doesn't copy to a separate
# buffer).
self.buffer = bytearray(((height // 8) * width) + 1)
self.buffer[0] = 0x40 # Set first byte of data buffer to Co=0, D/C=1
self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], width, height)
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_framebuf(self):
# Blast out the frame buffer using a single I2C transaction to support
# hardware I2C interfaces.
self.i2c.writeto(self.addr, self.buffer)

def poweron(self):
pass


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
self.buffer = bytearray((height // 8) * width)
self.framebuf = framebuf.FrameBuffer1(self.buffer, width, height)
super().__init__(width, height, external_vcc)

def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.low()
self.cs.low()
self.spi.write(bytearray([cmd]))
self.cs.high()

def write_framebuf(self):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.high()
self.cs.low()
self.spi.write(self.buffer)
self.cs.high()

def poweron(self):
self.res.high()
time.sleep_ms(1)
self.res.low()
time.sleep_ms(10)
self.res.high()

此为博主副博客,留言请去主博客,转载请注明出处:https://www.baby7blog.com/myBlog/102.html

欢迎关注我的其它发布渠道