OLED
OLED
This page is to Setup and Config ESP32
Hardware and Software
Hardware : ESP32, Oled SSD1306
Software : MicroPython
Notes
How to Create Icon for Oled
Copy Free Icon from Gogole https://www.flaticon.com/free-icon/rain_365921
Open on Gimp
Save as .c header format and open on Text Editor
Copy Hex Code to .py file
Connect Hardware by I2C
from machine import Pin,I2C
import ssd1306
i2c = I2C(scl=Pin(15), sda=Pin(14), freq=100000)
lcd=ssd1306.SSD1306_I2C(128,64,i2c)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Driver SSD1306
Examples
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces from micropython import const import framebuf # register definitions SET_CONTRAST = const(0x81) SET_ENTIRE_ON = const(0xa4) SET_NORM_INV = const(0xa6) SET_DISP = const(0xae) SET_MEM_ADDR = const(0x20) SET_COL_ADDR = const(0x21) SET_PAGE_ADDR = const(0x22) SET_DISP_START_LINE = const(0x40) SET_SEG_REMAP = const(0xa0) SET_MUX_RATIO = const(0xa8) SET_COM_OUT_DIR = const(0xc0) SET_DISP_OFFSET = const(0xd3) SET_COM_PIN_CFG = const(0xda) SET_DISP_CLK_DIV = const(0xd5) SET_PRECHARGE = const(0xd9) SET_VCOM_DESEL = const(0xdb) SET_CHARGE_PUMP = const(0x8d) # Subclassing FrameBuffer provides support for graphics primitives # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html class SSD1306(framebuf.FrameBuffer): def __init__(self, width, height, external_vcc): self.width = width self.height = height self.external_vcc = external_vcc self.pages = self.height // 8 self.buffer = bytearray(self.pages * self.width) super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB) self.init_display() def init_display(self): for cmd in ( SET_DISP | 0x00, # off # address setting SET_MEM_ADDR, 0x00, # horizontal # resolution and layout SET_DISP_START_LINE | 0x00, SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 SET_MUX_RATIO, self.height - 1, SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 SET_DISP_OFFSET, 0x00, SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12, # timing and driving scheme SET_DISP_CLK_DIV, 0x80, SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1, SET_VCOM_DESEL, 0x30, # 0.83*Vcc # display SET_CONTRAST, 0xff, # maximum SET_ENTIRE_ON, # output follows RAM contents SET_NORM_INV, # not inverted # charge pump SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14, SET_DISP | 0x01): # on self.write_cmd(cmd) self.fill(0) self.show() def poweroff(self): self.write_cmd(SET_DISP | 0x00) def poweron(self): self.write_cmd(SET_DISP | 0x01) def contrast(self, contrast): self.write_cmd(SET_CONTRAST) self.write_cmd(contrast) def invert(self, invert): self.write_cmd(SET_NORM_INV | (invert & 1)) def show(self): x0 = 0 x1 = self.width - 1 if self.width == 64: # displays with width of 64 pixels are shifted by 32 x0 += 32 x1 += 32 self.write_cmd(SET_COL_ADDR) self.write_cmd(x0) self.write_cmd(x1) self.write_cmd(SET_PAGE_ADDR) self.write_cmd(0) self.write_cmd(self.pages - 1) self.write_data(self.buffer) class SSD1306_I2C(SSD1306): def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False): self.i2c = i2c self.addr = addr self.temp = bytearray(2) super().__init__(width, height, external_vcc) def write_cmd(self, cmd): self.temp[0] = 0x80 # Co=1, D/C#=0 self.temp[1] = cmd self.i2c.writeto(self.addr, self.temp) def write_data(self, buf): self.temp[0] = self.addr << 1 self.temp[1] = 0x40 # Co=0, D/C#=1 self.i2c.start() self.i2c.write(self.temp) self.i2c.write(buf) self.i2c.stop() class SSD1306_SPI(SSD1306): def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): self.rate = 10 * 1024 * 1024 dc.init(dc.OUT, value=0) res.init(res.OUT, value=0) cs.init(cs.OUT, value=1) self.spi = spi self.dc = dc self.res = res self.cs = cs import time self.res(1) time.sleep_ms(1) self.res(0) time.sleep_ms(10) self.res(1) super().__init__(width, height, external_vcc) def write_cmd(self, cmd): self.spi.init(baudrate=self.rate, polarity=0, phase=0) self.cs(1) self.dc(0) self.cs(0) self.spi.write(bytearray([cmd])) self.cs(1) def write_data(self, buf): self.spi.init(baudrate=self.rate, polarity=0, phase=0) self.cs(1) self.dc(1) self.cs(0) self.spi.write(buf) self.cs(1)
from machine import Pin,I2C import ssd1306 i2c = I2C(scl=Pin(15), sda=Pin(14), freq=100000) lcd=ssd1306.SSD1306_I2C(128,64,i2c) iconwineglass = [ 0x00, 0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0xc0, 0x60, 0x18, 0x00, 0x40, 0x00, 0x08, 0x00, 0x30, 0x18, 0x06, 0x00, 0x20, 0x18, 0x06, 0x00, 0xc0, 0x60, 0x18, 0x00, 0x80, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, 0x03, 0x00, 0x00, 0x3f, 0x03, 0x00, 0x00, 0x3f, 0x03, 0x00, 0x00, 0xc3, 0x03, 0x00, 0x00, 0xc3, 0x03, 0x00, 0x00, 0xc3, 0x03, 0x00, 0x00, 0xc3, 0x03, 0x00, 0x00, 0xc3, 0x03, 0x00, 0x00, 0xc3, 0x03, 0x00, 0x00, 0x3f, 0x03, 0x00, 0x00, 0x3f, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xe0, 0x00, 0x08, 0x00, 0x40, 0x00, 0x30, 0x00, 0x18, 0x00, 0x20, 0x00, 0x10, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x80, 0xff, 0x07, 0x00 ] testgamp = [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x60, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00 ] testicon = [ 0xc0, 0x03, 0x20, 0x04, 0x10, 0x08, 0x10, 0x08, 0x1c, 0x38, 0x22, 0x44, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0xfc, 0x3f, 0x00, 0x00, 0x12, 0x81, 0x89, 0x44, 0x44, 0x22, 0x22, 0x11 ] testicon2 = [ 0x80, 0x0f, 0x40, 0x10, 0x60, 0x30, 0x90, 0x48, 0x08, 0x80, 0xc8, 0x83, 0x20, 0x84, 0x10, 0x48, 0x10, 0x08, 0x1c, 0x38, 0x22, 0x44, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0xfc, 0x3f ] def printBits(value): ret = [9,9,9,9, 9,9,9,9] for x in range(0,8): temp = value & 0x0001 # mask all but bit 0 if temp == 0x0001: #print("Bit ", x, " = 1") ret[x] = 1 else: #print("Bit ", x, " = 0") ret[x] = 0 value = value >> 1 # shift right repeat test return ret def showIcon(iconShow, xgap=0, ygap=0): for y, row in enumerate(iconShow): #for y, row in enumerate(icontest): for x, c in enumerate(row): retbin = printBits(c) #print("Y / X :", y,"/",x," -- retbin ", retbin, "=", c) for o in range(8): if retbin[o] == 0: #lcd.pixel((x * 8) + (7-o) + xgap , y + ygap, 0) lcd.pixel((x * 8) + (7-o) + xgap , y + ygap, 0) #pass else: #pass #lcd.pixel((x * 8) + (7-o) + xgap, y + ygap, 1) lcd.pixel((x * 8) + (7-o) + xgap, y + ygap, 1) # def showIcon2(iconShow, imagewidth, xgap=0, ygap=0): posx = 0 posy = 0 for x, c in enumerate(iconShow): retbin = printBits(c) #print(x, "Y / X :", posy,"/",posx," -- retbin ", retbin, "=", c) for o in range(8): lcd.pixel((posx) + xgap , posy + ygap, retbin[o]) posx = posx + 1 if (posx > (imagewidth-1)): posx = 0 posy = posy + 1 charStr = "Tell me WINE" lcd.text(charStr, int((128-(len(charStr)*8))/2), 4) lcd.rect(0, 0, 127, 15, 1) lcd.rect(0, 16, 127, 48, 1) showIcon2( iconwineglass, 32, 4, 20) showIcon2( testicon2, 16, 50, 24) showIcon2( testicon, 16, 55, 44) showIcon2( testgamp, 32, 90, 20) lcd.show() #display pix