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