1+ from micropython import const
2+ import framebuf
3+
4+
5+ SH1107_I2C_address = const (0x3C )
6+
7+
8+ SH1107_SET_LOWER_COLUMN_ADDRESS = const (0x00 )
9+ SH1107_SET_UPPER_COLUMN_ADDRESS = const (0x10 )
10+ SH1107_SET_PAGE_MEMORY_ADDRESSING_MODE = const (0x20 )
11+ SH1107_SET_VERTICAL_MEMORY_ADDRESSING_MODE = const (0x21 )
12+ SH1107_SET_CONSTRAST_CONTROL = const (0x81 )
13+ SH1107_SET_DC_DC_OFF_MODE = const (0x8A )
14+ SH1107_SET_DC_DC_ON_MODE = const (0x8B )
15+ SH1107_SET_SEGMENT_REMAP_NORMAL = const (0xA0 )
16+ SH1107_SET_SEGMENT_REMAP_REVERSE = const (0xA1 )
17+ SH1107_SET_ENTIRE_DISPLAY_OFF = const (0xA4 )
18+ SH1107_SET_ENTIRE_DISPLAY_ON = const (0xA5 )
19+ SH1107_SET_NORMAL_DISPLAY = const (0xA6 )
20+ SH1107_SET_REVERSE_DISPLAY = const (0xA7 )
21+ SH1107_SET_MULTIPLEX_RATIO = const (0xA8 )
22+ SH1107_SET_DC_DC_CONTROL_MODE = const (0xAD )
23+ SH1107_DISPLAY_OFF = const (0xAE )
24+ SH1107_DISPLAY_ON = const (0xAF )
25+ SH1107_SET_PAGE_ADDRESS = const (0xB0 )
26+ SH1107_SET_COMMON_OUTPUT_SCAN_DIRECTION = const (0xC0 )
27+ SH1107_SET_DISPLAY_OFFSET = const (0xD3 )
28+ SH1107_SET_DISPLAY_CLOCK_FREQUENCY = const (0xD5 )
29+ SH1107_SET_PRECHARGE_DISCHARGE_PERIOD = const (0xD9 )
30+ SH1107_SET_VCOM_DESELECT_LEVEL = const (0xDB )
31+ SH1107_SET_DISPLAY_START_LINE = const (0xDC )
32+
33+
34+ disp_width = const (128 )
35+ disp_height = const (64 )
36+ disp_pages = const ((disp_height >> 3 ))
37+
38+
39+ class OLED (framebuf .FrameBuffer ):
40+
41+ def __init__ (self , _i2c , _i2c_address = SH1107_I2C_address ):
42+ self .width = disp_width
43+ self .height = disp_height
44+ self .pages = disp_pages
45+
46+ self .line_bytes = (self .width >> 3 )
47+ size = (self .width * self .pages )
48+ self .curr_buffer = bytearray (b'\x00 ' * size )
49+ self .prev_buffer = bytearray (b'\xFF ' * size )
50+
51+ self .write_list = [b"\x40 " , None ]
52+ self .temp = bytearray (0x02 )
53+
54+ self .WHITE = 1
55+ self .BLACK = 0
56+
57+ self .i2c = _i2c
58+ self .i2c_addr = _i2c_address
59+
60+ super ().__init__ (self .curr_buffer , self .width , self .height , framebuf .MONO_HMSB )
61+ self .init_display ()
62+
63+
64+ def write_command (self , cmd ):
65+ self .temp [0 ] = 0x80
66+ self .temp [1 ] = cmd
67+ self .i2c .writeto (self .i2c_addr , self .temp )
68+
69+
70+ def write_data (self , data_buffer ):
71+ self .write_list [1 ] = data_buffer
72+ self .i2c .writevto (self .i2c_addr , self .write_list )
73+
74+
75+ def init_display (self ):
76+ self .write_command (SH1107_DISPLAY_OFF )
77+
78+ self .write_command (SH1107_SET_LOWER_COLUMN_ADDRESS )
79+ self .write_command (SH1107_SET_UPPER_COLUMN_ADDRESS )
80+
81+ self .write_command (SH1107_SET_PAGE_ADDRESS )
82+
83+ self .write_command (SH1107_SET_DISPLAY_START_LINE )
84+ self .write_command (0x00 )
85+ self .write_command (SH1107_SET_CONSTRAST_CONTROL )
86+ self .write_command (0x44 )
87+ self .write_command (SH1107_SET_VERTICAL_MEMORY_ADDRESSING_MODE )
88+
89+ self .write_command (SH1107_SET_SEGMENT_REMAP_REVERSE )
90+ self .write_command (SH1107_SET_COMMON_OUTPUT_SCAN_DIRECTION )
91+ self .write_command (SH1107_SET_ENTIRE_DISPLAY_OFF )
92+
93+ self .write_command (SH1107_SET_NORMAL_DISPLAY )
94+ self .write_command (SH1107_SET_MULTIPLEX_RATIO )
95+ self .write_command (0x7F )
96+
97+ self .write_command (SH1107_SET_DISPLAY_OFFSET )
98+ self .write_command (0x60 )
99+
100+ self .write_command (SH1107_SET_DISPLAY_CLOCK_FREQUENCY )
101+ self .write_command (0x81 )
102+
103+ self .write_command (SH1107_SET_PRECHARGE_DISCHARGE_PERIOD )
104+ self .write_command (0x22 )
105+
106+ self .write_command (SH1107_SET_VCOM_DESELECT_LEVEL )
107+ self .write_command (0x35 )
108+
109+ self .write_command (SH1107_SET_DC_DC_CONTROL_MODE )
110+ self .write_command (SH1107_SET_DC_DC_OFF_MODE )
111+ self .write_command (SH1107_DISPLAY_ON )
112+
113+
114+ def modify_buf (self , offs , width ):
115+ ptr = offs
116+ width += offs
117+ while (ptr < width ):
118+ while ((ptr < width ) and (self .curr_buffer [ptr : (ptr + 0x08 )] == self .prev_buffer [ptr : (ptr + 0x08 )])):
119+ ptr += 0x08
120+
121+ if (ptr < width ):
122+ first = ptr
123+ ptr += 0x08
124+ while ((ptr < width ) and (self .curr_buffer [ptr : (ptr + 0x08 )] != self .prev_buffer [ptr : (ptr + 0x08 )])):
125+ ptr += 0x08
126+
127+ yield first , ptr
128+ ptr += 0x08
129+
130+
131+ def show (self ):
132+ for col in range (self .height ):
133+ noffs = (col * self .line_bytes )
134+ for page1 , page2 in self .modify_buf (noffs , self .line_bytes ):
135+ self .write_command (SH1107_SET_PAGE_ADDRESS | (page1 - noffs ))
136+ self .write_command (SH1107_SET_LOWER_COLUMN_ADDRESS | (col & 0x0F ))
137+ self .write_command (SH1107_SET_UPPER_COLUMN_ADDRESS | ((col & 0x70 ) >> 0x04 ))
138+ self .write_data (self .curr_buffer [page1 : page2 ])
0 commit comments