77 https://www.micropython.org.cn
88
99'''
10-
11- cmd = [
12- [0xAE ],
13- [0xA4 ],
14- [0xD5 , 0xF0 ],
15- [0xA8 , 0x3F ],
16- [0xD3 , 0x00 ],
17- [0 | 0x0 ],
18- [0x8D , 0x14 ],
19- [0x20 , 0x00 ],
20- [0x21 , 0 , 127 ],
21- [0x22 , 0 , 63 ],
22- [0xa0 | 0x1 ],
23- [0xc8 ],
24- [0xDA , 0x12 ],
25- [0x81 , 0xCF ],
26- [0xd9 , 0xF1 ],
27- [0xDB , 0x40 ],
28- [0xA6 ],
29- [0xd6 , 0 ],
30- [0xaf ]
31- ]
10+ from micropython import const
11+
12+ # register definitions
13+ SET_CONTRAST = const (0x81 )
14+ SET_ENTIRE_ON = const (0xA4 )
15+ SET_NORM_INV = const (0xA6 )
16+ SET_DISP = const (0xAE )
17+ SET_MEM_ADDR = const (0x20 )
18+ SET_COL_ADDR = const (0x21 )
19+ SET_PAGE_ADDR = const (0x22 )
20+ SET_DISP_START_LINE = const (0x40 )
21+ SET_SEG_REMAP = const (0xA0 )
22+ SET_MUX_RATIO = const (0xA8 )
23+ SET_IREF_SELECT = const (0xAD )
24+ SET_COM_OUT_DIR = const (0xC0 )
25+ SET_DISP_OFFSET = const (0xD3 )
26+ SET_COM_PIN_CFG = const (0xDA )
27+ SET_DISP_CLK_DIV = const (0xD5 )
28+ SET_PRECHARGE = const (0xD9 )
29+ SET_VCOM_DESEL = const (0xDB )
30+ SET_CHARGE_PUMP = const (0x8D )
3231
3332from Font_6x8 import Font_6x8
3433from Font_8x16 import Font_8x16
4039Font_12_24 = const (3 )
4140Font_16_32 = const (4 )
4241
43- OLED_ADDR = 0x3C
44- screen = bytearray (1025 )
45- screen [0 ] = 0x40
42+ OLED_ADDR = const (0x3C )
4643
47- class OLED12864_I2C ():
48- def __init__ (self , i2c , ADDR = OLED_ADDR ):
44+ class OLED_I2C ():
45+ def __init__ (self , i2c , width = 128 , height = 64 , ADDR = OLED_ADDR , external_vcc = False ):
46+ self .temp = bytearray (2 )
47+ self .external_vcc = external_vcc
4948 self .px = 0
5049 self .py = 0
51- self .width = 128
52- self .height = 64
53- self .MAX_X = 127
54- self .MAX_Y = 63
50+ self .width = width
51+ self .height = height
52+ self .MAX_X = width - 1
53+ self .MAX_Y = height - 1
5554 self .i2c = i2c
55+ self .screen = bytearray (width * height // 8 + 1 )
56+ self .screen [0 ] = 0x40
5657 self ._DRAW = 1
5758 self ._sav = 0
5859 self .ADDR = ADDR
5960 self .Font (1 )
60- for c in cmd :
61- self .command (c )
61+ for cmd in (
62+ SET_DISP , # display off
63+ # address setting
64+ SET_MEM_ADDR ,
65+ 0x00 , # horizontal
66+ # resolution and layout
67+ SET_DISP_START_LINE , # start at line 0
68+ SET_SEG_REMAP | 0x01 , # column addr 127 mapped to SEG0
69+ SET_MUX_RATIO ,
70+ self .height - 1 ,
71+ SET_COM_OUT_DIR | 0x08 , # scan from COM[N] to COM0
72+ SET_DISP_OFFSET ,
73+ 0x00 ,
74+ SET_COM_PIN_CFG ,
75+ 0x02 if self .width > 2 * self .height else 0x12 ,
76+ # timing and driving scheme
77+ SET_DISP_CLK_DIV ,
78+ 0x80 ,
79+ SET_PRECHARGE ,
80+ 0x22 if self .external_vcc else 0xF1 ,
81+ SET_VCOM_DESEL ,
82+ 0x30 , # 0.83*Vcc
83+ # display
84+ SET_CONTRAST ,
85+ 0xFF , # maximum
86+ SET_ENTIRE_ON , # output follows RAM contents
87+ SET_NORM_INV , # not inverted
88+ SET_IREF_SELECT ,
89+ 0x30 , # enable internal IREF during display on
90+ # charge pump
91+ SET_CHARGE_PUMP ,
92+ 0x10 if self .external_vcc else 0x14 ,
93+ SET_DISP | 0x01 , # display on
94+ ): # on
95+ self .command (cmd )
6296 self .clear ()
6397
64- def command (self , c ):
65- self .i2c .writeto (self .ADDR , b'\x00 ' + bytearray (c ))
98+ def command (self , cmd ):
99+ self .temp [0 ] = 0x80 # Co=1, D/C#=0
100+ self .temp [1 ] = cmd
101+ self .i2c .writeto (self .ADDR , self .temp )
66102
67103 def set_pos (self , col = 0 , page = 0 ):
68- self .command ([ 0xb0 | page ] )
104+ self .command (0xb0 | page )
69105 c1 , c2 = col & 0x0F , col >> 4
70- self .command ([ 0x00 | c1 ] )
71- self .command ([ 0x10 | c2 ] )
106+ self .command (0x00 | c1 )
107+ self .command (0x10 | c2 )
72108
73109 def pixel (self , x , y , color = 1 ):
74110 if x < 0 or x > self .MAX_X or y < 0 or y > self .MAX_Y :
75111 return
76112 page , shift_page = divmod (y , 8 )
77113 ind = x + page * 128 + 1
78- b = screen [ind ] | (1 << shift_page ) if color else screen [ind ] & ~ (1 << shift_page )
79- screen [ind ] = b
114+ b = self . screen [ind ] | (1 << shift_page ) if color else self . screen [ind ] & ~ (1 << shift_page )
115+ self . screen [ind ] = b
80116 if self ._DRAW :
81117 self .set_pos (x , page )
82118 self .i2c .writeto (self .ADDR , bytearray ([0x40 , b ]))
83119
84120 def invert (self , v = 1 ):
85121 n = 0xa7 if v else 0xa6
86- self .command ([ n ] )
122+ self .command (n )
87123
88124 def on (self , v = 1 ):
89125 d = 0xAF if v else 0xAE
90- self .command ([ d ] )
126+ self .command (d )
91127
92128 def clear (self , c = 0 ):
93- for i in range (1 , 1025 ):
94- screen [i ] = 0
129+ for i in range (1 , len ( self . screen ) ):
130+ self . screen [i ] = 0
95131 self .draw ()
96132
97133 def draw (self ):
98134 if self ._DRAW :
99135 self .set_pos ()
100- self .i2c .writeto (self .ADDR , screen )
136+ self .i2c .writeto (self .ADDR , self . screen )
101137
102138 def zoom (self , z = 1 ):
103- d = 1 if z else 0
104- self .command ([ 0xD6 , d ] )
139+ self . command ( 0xD6 )
140+ self .command (1 if z else 0 )
105141
106142 def rotate (self , rotate = 1 ):
107- self .command ([ 0xC0 | ((rotate & 1 ) << 3 )] )
108- self .command ([ 0xA0 | (rotate & 1 )] )
143+ self .command (0xC0 | ((rotate & 1 ) << 3 ))
144+ self .command (0xA0 | (rotate & 1 ))
109145
110146 def line (self , x1 , y1 , x2 , y2 , c = 1 ):
111147 return
@@ -149,54 +185,56 @@ def font(self, FONT):
149185 def scroll (self ):
150186 self .px = 0
151187 self .py += 1
152- if self .py > 7 :
153- self .py = 7
154- for i in range (1 , 897 ):
155- screen [i ] = screen [i + 128 ]
156- for i in range (128 ):
157- screen [- i - 1 ] = 0
188+ if self .py > ( self . height // 8 - 1 ) :
189+ self .py = self . height // 8 - 1
190+ for i in range (1 , len ( self . screen ) - self . width ):
191+ self . screen [i ] = self . screen [i + self . width ]
192+ for i in range (self . width ):
193+ self . screen [- i - 1 ] = 0
158194 self .draw ()
159195
160196 def char_6x8 (self , x = 0 , y = 0 , ch = 32 , c = 1 ):
161197 try :
162- ind = x + y * 128 + 1
198+ ind = x + y * self . width + 1
163199 n = (min (127 , max (ord (ch ), 32 )) - 32 )* 5
164200 for i in range (5 ):
165- screen [ind + i ] = Font_6x8 [n + i ] if c else Font_6x8 [n + i ]^ 0xFF
166- screen [ind + 5 ] = 0 if c else 0xFF
201+ self . screen [ind + i ] = Font_6x8 [n + i ] if c else Font_6x8 [n + i ]^ 0xFF
202+ self . screen [ind + 5 ] = 0 if c else 0xFF
167203 self .set_pos (x , y )
168- self .i2c .writeto (self .ADDR , b'\x40 ' + screen [ind :ind + 6 ])
204+ self .i2c .writeto (self .ADDR , b'\x40 ' + self . screen [ind :ind + 6 ])
169205 except :
170206 return
171207
172208 def text_6x8 (self , x = 0 , y = 0 , s = '' , c = 1 , wrap = 0 ):
173209 for i in range (len (s )):
174210 self .char (x , y , s [i ], c )
175211 x += 6
176- if wrap and x > 120 :
212+ if wrap and ( x > self . width - 6 ) :
177213 x = 0
178214 y += 1
179215
180216 def print (self , s , c = 1 , cr = 1 ):
217+ if type (s ) != str :
218+ s = str (s )
181219 for i in range (len (s )):
182220 self .char_6x8 (self .px , self .py , s [i ], c )
183221 self .px += 6
184- if self .px > 120 :
222+ if self .px > self . width - 6 :
185223 self .scroll ()
186224 if cr :
187225 self .scroll ()
188226
189227 def char_8x16 (self , x = 0 , y = 0 , ch = 32 , c = 1 ):
190228 try :
191- ind = x + y * 128 + 1
229+ ind = x + y * self . width + 1
192230 n = (min (127 , max (ord (ch ), 32 )) - 32 )* 14
193231 for j in range (2 ):
194- ind = x + y * 128 + 1
232+ ind = x + y * self . width + 1
195233 for i in range (7 ):
196- screen [ind + i ] = Font_8x16 [n + i ] if c else Font_8x16 [n + i ]^ 0xFF
197- screen [ind + 7 ] = 0 if c else 0xFF
234+ self . screen [ind + i ] = Font_8x16 [n + i ] if c else Font_8x16 [n + i ]^ 0xFF
235+ self . screen [ind + 7 ] = 0 if c else 0xFF
198236 self .set_pos (x , y )
199- self .i2c .writeto (self .ADDR , b'\x40 ' + screen [ind :ind + 8 ])
237+ self .i2c .writeto (self .ADDR , b'\x40 ' + self . screen [ind :ind + 8 ])
200238 y += 1
201239 n += 7
202240 except :
@@ -206,19 +244,19 @@ def text_8x16(self, x=0, y=0, s='', c=1, wrap=0):
206244 for i in range (len (s )):
207245 self .char_8x16 (x , y , s [i ], c )
208246 x += 8
209- if wrap and x > 120 :
247+ if wrap and ( x > self . width - 8 ) :
210248 x = 0
211249 y += 2
212250
213251 def char_12x24 (self , x = 0 , y = 0 , ch = 32 , c = 1 ):
214252 try :
215253 n = (min (127 , max (ord (ch ), 32 )) - 32 )* 36
216254 for j in range (3 ):
217- ind = x + y * 128 + 1
255+ ind = x + y * self . width + 1
218256 for i in range (12 ):
219- screen [ind + i ] = Font_12x24 [n + i ] if c else Font_12x24 [n + i ]^ 0xFF
257+ self . screen [ind + i ] = Font_12x24 [n + i ] if c else Font_12x24 [n + i ]^ 0xFF
220258 self .set_pos (x , y )
221- self .i2c .writeto (self .ADDR , b'\x40 ' + screen [ind :ind + 12 ])
259+ self .i2c .writeto (self .ADDR , b'\x40 ' + self . screen [ind :ind + 12 ])
222260 y += 1
223261 n += 12
224262 except :
@@ -228,19 +266,19 @@ def text_12x24(self, x=0, y=0, s='', c=1, wrap=0):
228266 for i in range (len (s )):
229267 self .char_12x24 (x , y , s [i ], c )
230268 x += 12
231- if wrap and x > 116 :
269+ if wrap and ( x > self . width - 12 ) :
232270 x = 0
233271 y += 3
234272
235273 def char_16x32 (self , x = 0 , y = 0 , ch = 32 , c = 1 ):
236274 try :
237275 n = (min (127 , max (ord (ch ), 32 )) - 32 )* 64
238276 for j in range (4 ):
239- ind = x + y * 128 + 1
277+ ind = x + y * self . width + 1
240278 for i in range (16 ):
241- screen [ind + i ] = Font_16x32 [n + i ] if c else Font_16x32 [n + i ]^ 0xFF
279+ self . screen [ind + i ] = Font_16x32 [n + i ] if c else Font_16x32 [n + i ]^ 0xFF
242280 self .set_pos (x , y )
243- self .i2c .writeto (self .ADDR , b'\x40 ' + screen [ind :ind + 16 ])
281+ self .i2c .writeto (self .ADDR , b'\x40 ' + self . screen [ind :ind + 16 ])
244282 y += 1
245283 n += 16
246284 except :
@@ -250,7 +288,7 @@ def text_16x32(self, x=0, y=0, s='', c=1, wrap=0):
250288 for i in range (len (s )):
251289 self .char_16x32 (x , y , s [i ], c )
252290 x += 16
253- if wrap and x > 112 :
291+ if wrap and ( x > self . width - 16 ) :
254292 x = 0
255293 y += 4
256294
0 commit comments