Skip to content

Commit 56b694b

Browse files
committed
Calculate offset, col and row addr from width and height
1 parent cf820d5 commit 56b694b

File tree

3 files changed

+107
-66
lines changed

3 files changed

+107
-66
lines changed

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
setup(
88
name='micropython-ssd1327',
99
py_modules=['ssd1327'],
10-
version='1.1.0',
10+
version='1.1.1',
1111
description='MicroPython library for SSD1327 based OLED displays.',
1212
long_description='This library lets you update SSD1327 based 128x128 4-bit grayscale OLED displays.',
1313
keywords='ssd1327 oled micropython',

ssd1327.py

+44-34
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@
2424
SOFTWARE.
2525
"""
2626

27-
__version__ = '1.1.0'
27+
__version__ = '1.1.1'
2828

2929
from micropython import const
30-
import time
3130
import framebuf
3231

3332
# commands
@@ -56,14 +55,25 @@
5655
REG_CMD = const(0x80)
5756
REG_DATA = const(0x40)
5857

59-
6058
class SSD1327:
61-
def __init__(self, width, height, external_vcc):
59+
def __init__(self, width=128, height=128):
6260
self.width = width
6361
self.height = height
64-
self.external_vcc = external_vcc
6562
self.buffer = bytearray(self.width * self.height // 2)
6663
self.framebuf = framebuf.FrameBuffer(self.buffer, self.width, self.height, framebuf.GS4_HMSB)
64+
65+
self.col_addr = ((128 - self.width) // 4, 63 - ((128 - self.width) // 4))
66+
# 96x96 (8, 55)
67+
# 128x128 (0, 63)
68+
69+
self.row_addr = (0, self.height - 1)
70+
# 96x96 (0, 95)
71+
# 128x128 (0, 127)
72+
73+
self.offset = 128 - self.height
74+
# 96x96 32
75+
# 128x128 0
76+
6777
self.poweron()
6878
self.init_display()
6979

@@ -73,7 +83,7 @@ def init_display(self):
7383
SET_DISP, # Display off
7484
# Resolution and layout
7585
SET_DISP_START_LINE, 0x00,
76-
SET_DISP_OFFSET, 0x00, # Set vertical offset by COM from 0~127
86+
SET_DISP_OFFSET, self.offset, # Set vertical offset by COM from 0~127
7787
# Set re-map
7888
# Enable column address re-map
7989
# Disable nibble re-map
@@ -94,20 +104,13 @@ def init_display(self):
94104
SET_GRAYSCALE_LINEAR, # Use linear greyscale lookup table
95105
SET_CONTRAST, 0x7f, # Medium brightness
96106
SET_DISP_MODE, # Normal, not inverted
97-
# 96x96:
98-
# SET_ROW_ADDR, 0 95,
99-
# SET_COL_ADDR, 8, 55,
100-
# 128x128:
101-
# SET_ROW_ADDR, 0 127,
102-
# SET_COL_ADDR, 0, 63,
103-
SET_ROW_ADDR, 0x00, self.height - 1,
104-
SET_COL_ADDR, ((128 - self.width) // 4), 63 - ((128 - self.width) // 4),
105-
107+
SET_COL_ADDR, self.col_addr[0], self.col_addr[1],
108+
SET_ROW_ADDR, self.row_addr[0], self.row_addr[1],
106109
SET_SCROLL_DEACTIVATE,
107110
SET_DISP | 0x01): # Display on
108111
self.write_cmd(cmd)
109112
self.fill(0)
110-
self.show()
113+
self.write_data(self.buffer)
111114

112115
def poweroff(self):
113116
self.write_cmd(SET_FN_SELECT_A)
@@ -123,16 +126,24 @@ def contrast(self, contrast):
123126
self.write_cmd(SET_CONTRAST)
124127
self.write_cmd(contrast) # 0-255
125128

129+
def rotate(self, rotate):
130+
self.poweroff()
131+
self.write_cmd(SET_DISP_OFFSET)
132+
self.write_cmd(self.height if rotate else self.offset)
133+
self.write_cmd(SET_SEG_REMAP)
134+
self.write_cmd(0x42 if rotate else 0x51)
135+
self.poweron()
136+
126137
def invert(self, invert):
127138
self.write_cmd(SET_DISP_MODE | (invert & 1) << 1 | (invert & 1)) # 0xA4=Normal, 0xA7=Inverted
128139

129140
def show(self):
130141
self.write_cmd(SET_COL_ADDR)
131-
self.write_cmd((128 - self.width) // 4)
132-
self.write_cmd(63 - ((128 - self.width) // 4))
142+
self.write_cmd(self.col_addr[0])
143+
self.write_cmd(self.col_addr[1])
133144
self.write_cmd(SET_ROW_ADDR)
134-
self.write_cmd(0x00)
135-
self.write_cmd(self.height - 1)
145+
self.write_cmd(self.row_addr[0])
146+
self.write_cmd(self.row_addr[1])
136147
self.write_data(self.buffer)
137148

138149
def fill(self, col):
@@ -141,44 +152,43 @@ def fill(self, col):
141152
def pixel(self, x, y, col):
142153
self.framebuf.pixel(x, y, col)
143154

155+
def line(self, x1, y1, x2, y2, col):
156+
self.framebuf.line(x1, y1, x2, y2, col)
157+
144158
def scroll(self, dx, dy):
145159
self.framebuf.scroll(dx, dy)
146160
# software scroll
147161

148162
def text(self, string, x, y, col=15):
149163
self.framebuf.text(string, x, y, col)
150164

165+
def write_cmd(self):
166+
raise NotImplementedError
167+
168+
def write_data(self):
169+
raise NotImplementedError
170+
151171

152172
class SSD1327_I2C(SSD1327):
153-
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
173+
def __init__(self, width, height, i2c, addr=0x3c):
154174
self.i2c = i2c
155175
self.addr = addr
156176
self.cmd_arr = bytearray([REG_CMD, 0]) # Co=1, D/C#=0
157177
self.data_list = [bytes((REG_DATA,)), None]
158-
super().__init__(width, height, external_vcc)
178+
super().__init__(width, height)
159179

160180
def write_cmd(self, cmd):
161181
self.cmd_arr[1] = cmd
162182
self.i2c.writeto(self.addr, self.cmd_arr)
163183

164-
def write_data(self, buf):
165-
self.data_list[1] = buf
184+
def write_data(self, data_buf):
185+
self.data_list[1] = data_buf
166186
self.i2c.writevto(self.addr, self.data_list)
167187

168188

169189
class SEEED_OLED_96X96(SSD1327_I2C):
170190
def __init__(self, i2c):
171191
super().__init__(96, 96, i2c)
172-
self.write_cmd(SET_DISP_OFFSET)
173-
self.write_cmd(0x20) # Set vertical offset by COM from 0~127
174-
175-
def rotate(self, rotate):
176-
self.poweroff()
177-
self.write_cmd(SET_DISP_OFFSET)
178-
self.write_cmd(0x60 if rotate else 0x20) # 0x20=0 degrees, 0x60=180 degrees
179-
self.write_cmd(SET_SEG_REMAP)
180-
self.write_cmd(0x42 if rotate else 0x51) # 0x51=0 degrees, 0x42=180 degrees
181-
self.poweron()
182192

183193
def lookup(self, table):
184194
# GS0 has no pre-charge and current drive

ssd1327_examples.py

+62-31
Original file line numberDiff line numberDiff line change
@@ -45,47 +45,62 @@
4545
display.show()
4646

4747

48+
# MicroPython logo
49+
display.fill(0)
50+
x = (display.width - 69) // 2
51+
y = (display.height - 69) // 2
52+
display.framebuf.fill_rect(x+0, y+0, 69, 69, 15)
53+
display.framebuf.fill_rect(x+15, y+15, 3, 54, 0)
54+
display.framebuf.fill_rect(x+33, y+0, 3, 54, 0)
55+
display.framebuf.fill_rect(x+51, y+15, 3, 54, 0)
56+
display.framebuf.fill_rect(x+60, y+56, 4, 7, 0)
57+
display.show()
58+
59+
4860
# rotate 180 degrees
4961
display.rotate(True)
5062
display.show()
5163

5264
# rotate 0 degrees
53-
display.write_cmd(0xA2)
54-
display.write_cmd(0x20)
55-
display.write_cmd(0xA0)
65+
display.write_cmd(ssd1327.SET_DISP_OFFSET) # 0xA2
66+
display.write_cmd(128 - display.height)
67+
display.write_cmd(ssd1327.SET_SEG_REMAP) # 0xA0
5668
display.write_cmd(0x51)
5769
display.show()
5870

5971
# rotate 0 degrees (flip horizontal)
60-
display.write_cmd(0xA2)
61-
display.write_cmd(0x20)
62-
display.write_cmd(0xA0)
72+
display.write_cmd(ssd1327.SET_DISP_OFFSET) # 0xA2
73+
display.write_cmd(128 - display.height)
74+
display.write_cmd(ssd1327.SET_SEG_REMAP) # 0xA0
6375
display.write_cmd(0x52)
6476
display.show()
6577

6678
# rotate 180 degrees
67-
display.write_cmd(0xA2)
68-
display.write_cmd(0x60)
69-
display.write_cmd(0xA0)
79+
display.write_cmd(ssd1327.SET_DISP_OFFSET) # 0xA2
80+
display.write_cmd(display.height)
81+
display.write_cmd(ssd1327.SET_SEG_REMAP) # 0xA0
7082
display.write_cmd(0x42)
7183
display.show()
7284

7385
# rotate 180 degrees (flip horizontal)
74-
display.write_cmd(0xA2)
75-
display.write_cmd(0x60)
76-
display.write_cmd(0xA0)
86+
display.write_cmd(ssd1327.SET_DISP_OFFSET) # 0xA2
87+
display.write_cmd(display.height)
88+
display.write_cmd(ssd1327.SET_SEG_REMAP) # 0xA0
7789
display.write_cmd(0x41)
7890
display.show()
7991

8092
# rotate 0 degrees
8193
display.rotate(False)
8294
display.show()
8395

96+
8497
# scroll the framebuf down 16px
98+
# does not wrap around
8599
display.fill(0)
86-
display.text('Hello World', 0, 0, 15)
100+
for i in range(10):
101+
display.text('line {}'.format(i), 0, i*8, 15)
87102
display.show()
88-
display.scroll(0,16)
103+
display.scroll(0,16) # framebuf.scroll
89104
display.show()
90105

91106

@@ -157,48 +172,48 @@
157172
display.fill(0)
158173
x1 = 0
159174
y1 = 0
160-
y2 = 95
161-
for x2 in range(0,97,6):
175+
y2 = display.height - 1
176+
for x2 in range(0, display.width + 1, 8):
162177
display.framebuf.line(x1, y1, x2, y2, 15)
163178
display.show()
164-
x2 = 95
165-
for y2 in range(0,97,6):
179+
x2 = display.width - 1
180+
for y2 in range(0, display.height + 1, 8):
166181
display.framebuf.line(x1, y1, x2, y2, 15)
167182
display.show()
168183

169184
display.fill(0)
170-
x1 = 95
185+
x1 = display.width - 1
171186
y1 = 0
172-
y2 = 95
173-
for x2 in range(0,97,6):
187+
y2 = display.height - 1
188+
for x2 in range(0, display.width + 1, 8):
174189
display.framebuf.line(x1, y1, x2, y2, 15)
175190
display.show()
176191
x2 = 0
177-
for y2 in range(0,97,6):
192+
for y2 in range(0, display.height + 1, 8):
178193
display.framebuf.line(x1, y1, x2, y2, 15)
179194
display.show()
180195

181196
display.fill(0)
182197
x1 = 0
183-
y1 = 95
198+
y1 = display.height - 1
184199
y2 = 0
185-
for x2 in range(0,97,6):
200+
for x2 in range(0, display.width + 1, 8):
186201
display.framebuf.line(x1, y1, x2, y2, 15)
187202
display.show()
188-
x2 = 95
189-
for y2 in range(0,97,6):
203+
x2 = display.width - 1
204+
for y2 in range(0, display.height + 1, 8):
190205
display.framebuf.line(x1, y1, x2, y2, 15)
191206
display.show()
192207

193208
display.fill(0)
194-
x1 = 95
195-
y1 = 95
209+
x1 = display.width - 1
210+
y1 = display.height - 1
196211
y2 = 0
197-
for x2 in range(0,97,6):
212+
for x2 in range(0, display.width + 1, 8):
198213
display.framebuf.line(x1, y1, x2, y2, 15)
199214
display.show()
200215
x2 = 0
201-
for y2 in range(0,97,6):
216+
for y2 in range(0, display.height + 1, 8):
202217
display.framebuf.line(x1, y1, x2, y2, 15)
203218
display.show()
204219

@@ -265,7 +280,23 @@ def bitmap(data,x,y,w,h):
265280
display.write_cmd(y + h)
266281
display.write_data(data)
267282

268-
283+
# draw many smileys
269284
for y in range(0,6):
270285
for x in range(0,6):
271286
bitmap(data, x * 16, y * 16, 15, 15)
287+
288+
289+
# optical illusion - crooked lines?
290+
display.fill(15)
291+
sq = 12 # square size
292+
seq = 100 # this magic number gives repititions of sequence 0,4,8,4...
293+
for y in range(0, display.height, sq+1):
294+
offset = int(round(((seq & 3) / 3) * sq))
295+
seq >>= 2
296+
if seq == 0:
297+
seq = 100
298+
for x in range(0, display.width, sq*2):
299+
display.framebuf.fill_rect(x + offset, y, sq, sq, 0)
300+
display.framebuf.hline(0, y + sq, display.width, 6)
301+
display.show()
302+

0 commit comments

Comments
 (0)