128 x 32 OLED Display
Revision as of 09:24, 14 June 2024 by Mayersven (talk | contribs) (Mayersven moved page SSD1306 Display to 128 x 32 OLED Display without leaving a redirect)
How to control it in MicroPython
The main.py shows the current time on the screen.
1 # main.py displaying the current time
2 from machine import Pin, SoftI2C
3 import ssd1306
4 from time import sleep
5 import utime
6
7 # Initialize I2C interface with the correct pins for your setup
8 i2c = SoftI2C(scl=Pin(13), sda=Pin(12))
9
10 # Initialize SSD1306 OLED display
11 oled_width = 128
12 oled_height = 32 # Adjusted for 128x32 OLED display
13 oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
14
15 while True:
16 # Clear the display
17 oled.fill(0)
18
19 # Get the current time
20 current_time = utime.localtime()
21 time_str = '{:02}:{:02}:{:02}'.format(current_time[3], current_time[4], current_time[5])
22
23 # Display the current time
24 oled.text('Current Time:', 0, 0) # first line
25 oled.text(time_str, 0, 10) # second line
26 #oled.text("EMPTY", 0, 20) #third line
27
28 # Update the display
29 oled.show()
30
31 # Wait for a bit before updating again
32 sleep(1)
ssd1306.py
1 # ssd1306.py - MicroPython SSD1306 OLED driver, I2C and SPI interfaces
2
3 from micropython import const
4 import framebuf
5
6 # register definitions
7 SET_CONTRAST = const(0x81)
8 SET_ENTIRE_ON = const(0xa4)
9 SET_NORM_INV = const(0xa6)
10 SET_DISP = const(0xae)
11 SET_MEM_ADDR = const(0x20)
12 SET_COL_ADDR = const(0x21)
13 SET_PAGE_ADDR = const(0x22)
14 SET_DISP_START_LINE = const(0x40)
15 SET_SEG_REMAP = const(0xa0)
16 SET_MUX_RATIO = const(0xa8)
17 SET_COM_OUT_DIR = const(0xc0)
18 SET_DISP_OFFSET = const(0xd3)
19 SET_COM_PIN_CFG = const(0xda)
20 SET_DISP_CLK_DIV = const(0xd5)
21 SET_PRECHARGE = const(0xd9)
22 SET_VCOM_DESEL = const(0xdb)
23 SET_CHARGE_PUMP = const(0x8d)
24
25 # Subclassing FrameBuffer provides support to the graphics primitives
26 class SSD1306(framebuf.FrameBuffer):
27
28 def __init__(self, width, height, external_vcc):
29 self.width = width
30 self.height = height
31 self.external_vcc = external_vcc
32 self.pages = self.height // 8
33 self.buffer = bytearray(self.pages * self.width)
34 super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
35 self.init_display()
36
37 def init_display(self):
38 for cmd in (
39 SET_DISP | 0x00, # display off
40 # address setting
41 SET_MEM_ADDR, 0x00, # horizontal
42 # resolution and layout
43 SET_DISP_START_LINE | 0x00,
44 SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
45 SET_MUX_RATIO, self.height - 1,
46 SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
47 SET_DISP_OFFSET, 0x00,
48 SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
49 # timing and driving scheme
50 SET_DISP_CLK_DIV, 0x80,
51 SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
52 SET_VCOM_DESEL, 0x30, # 0.83*Vcc
53 # display
54 SET_CONTRAST, 0xff, # maximum
55 SET_ENTIRE_ON, # output follows RAM contents
56 SET_NORM_INV, # not inverted
57 # charge pump
58 SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
59 SET_DISP | 0x01): # display on
60 self.write_cmd(cmd)
61 self.fill(0)
62 self.show()
63
64 def poweroff(self):
65 self.write_cmd(SET_DISP | 0x00)
66
67 def poweron(self):
68 self.write_cmd(SET_DISP | 0x01)
69
70 def contrast(self, contrast):
71 self.write_cmd(SET_CONTRAST)
72 self.write_cmd(contrast)
73
74 def invert(self, invert):
75 self.write_cmd(SET_NORM_INV | (invert & 1))
76
77 def show(self):
78 xpos0 = 0
79 xpos1 = self.width - 1
80 self.write_cmd(SET_COL_ADDR)
81 self.write_cmd(xpos0)
82 self.write_cmd(xpos1)
83 self.write_cmd(SET_PAGE_ADDR)
84 self.write_cmd(0)
85 self.write_cmd(self.pages - 1)
86 self.write_data(self.buffer)
87
88 def write_cmd(self, cmd):
89 raise NotImplementedError
90
91 def write_data(self, buf):
92 raise NotImplementedError
93
94 class SSD1306_I2C(SSD1306):
95
96 def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
97 self.i2c = i2c
98 self.addr = addr
99 self.temp = bytearray(2)
100 self.write_list = [b'\x40', None] # Co=0, D/C#=1
101 super().__init__(width, height, external_vcc)
102
103 def write_cmd(self, cmd):
104 self.temp[0] = 0x80 # Co=1, D/C#=0
105 self.temp[1] = cmd
106 self.i2c.writeto(self.addr, self.temp)
107
108 def write_data(self, buf):
109 self.write_list[1] = buf
110 self.i2c.writevto(self.addr, self.write_list)