Display oled com esp32 e lego mindstorms!
- Eduardo Brennand Paranhos
- 17 de nov. de 2024
- 5 min de leitura
Neste post, veremos como integrar um display oled com o lego mindstorms 51515. O processo é bastante simples e descomplicado.
Inicialmente, vá para firmware.antonsmindstorms.com e instale o software em destaque na imagem a seguir:

Em seguida, conecte o seu display e salve a biblioteca dele como ssd1306.py:
#MicroPython SSD1306 OLED driver, I2C and SPI interfaces created by Adafruit
import time
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)
class SSD1306:
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
# Note the subclass must initialize self.framebuf to a framebuffer.
# This is necessary because the underlying data buffer is different
# between I2C and SPI implementations (I2C needs an extra byte).
self.poweron()
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 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_framebuf()
def fill(self, col):
self.framebuf.fill(col)
def pixel(self, x, y, col):
self.framebuf.pixel(x, y, col)
def scroll(self, dx, dy):
self.framebuf.scroll(dx, dy)
def text(self, string, x, y, col=1):
self.framebuf.text(string, x, y, col)
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)
# Add an extra byte to the data buffer to hold an I2C data/command byte
# to use hardware-compatible I2C transactions. A memoryview of the
# buffer is used to mask this byte from the framebuffer operations
# (without a major memory hit as memoryview doesn't copy to a separate
# buffer).
self.buffer = bytearray(((height // 8) * width) + 1)
self.buffer[0] = 0x40 # Set first byte of data buffer to Co=0, D/C=1
self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], width, height)
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_framebuf(self):
# Blast out the frame buffer using a single I2C transaction to support
# hardware I2C interfaces.
self.i2c.writeto(self.addr, self.buffer)
def poweron(self):
pass
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
self.buffer = bytearray((height // 8) * width)
self.framebuf = framebuf.FrameBuffer1(self.buffer, width, height)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.low()
self.cs.low()
self.spi.write(bytearray([cmd]))
self.cs.high()
def write_framebuf(self):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.high()
self.cs.low()
self.spi.write(self.buffer)
self.cs.high()
def poweron(self):
self.res.high()
time.sleep_ms(1)
self.res.low()
time.sleep_ms(10)
self.res.high()
Depois disso, rode o código do projeto como main.py:
"""
Example code for driving a ssd1306 i2c OLED screen.
"""
from machine import I2C, Pin
import ssd1306
from uartremote import *
class Oled:
def __init__(self,width=128,height=64):
i2c=I2C(scl=Pin(4),sda=Pin(5))
self.oled=ssd1306.SSD1306_I2C(width, height, i2c)
for i in range(40):
self.oled.fill(0)
self.oled.text("Readyl!",10,i+5)
self.oled.show()
def text(self,txt,x,y):
self.oled.text(txt,x,y)
def show(self):
self.oled.show()
def fill(self,f):
self.oled.fill(f)
def line(self,x1,y1,x2,y2,color):
self.oled.line(x1,y1,x2,y2,color)
def pixel(self,x1,y1,color):
self.oled.pixel(x1,y1,color)
# initialize UartRemote library
u=UartRemote()
# initialize Oled instance
oled=Oled()
# define different commands
u.add_command(oled.__init__,name='oledi')
u.add_command(oled.text,name='oledt')
u.add_command(oled.show,name="oleds")
u.add_command(oled.fill,name="oledf")
u.add_command(oled.line,name="oledl")
u.add_command(oled.pixel,name="oledp")
# wait for a command in an endless loop
u.loop()
Por fim, conecte seu esp na porta B do hub lego e rode o programa a seguir:
# Before you can run this, you need to install mpy-robot-tools
# Run this script once in the MINDSTORMS app to install: https://github.com/antonvh/mpy-robot-tools/blob/master/Installer/install_mpy_robot_tools.py
# Be patient when it runs!
from mindstorms import Motor
from projects.uartremote import *
from time import sleep_ms
import time
class Oled:
def init(self,uartremote,width=128,height=64):
self.uartremote=uartremote
uartremote.call("oledi","BB",width,height)
def fill(self,color):
return(self.uartremote.call("oledf","B",color))
def text(self,txt,x,y):
s="%ds"%len(txt)
return(self.uartremote.call("oledt",s+"BB",txt,x,y))
def line(self,x1,y1,x2,y2,color):
self.uartremote.call("oledl","5B",x1,y1,x2,y2,color)
def pixel(self,x1,y1,color):
self.uartremote.call("oledp","3B",x1,y1,color)
def show(self):
return(self.uartremote.call("oleds"))
ur=UartRemote("B") # connect ESP to port A
ur.flush() # remove everything from rx buffer
print(ur.call('echo','repr',"Echo test is working"))
oled=Oled(ur)
# scroll text
while True:
oled.fill(0)
oled.text("lego falando!",10,20)
sleep_ms(500)
oled.fill(0)
sleep_ms(500)
Caso não tenha a biblioteca uartremote instalada no hub, instale-a:
import ubinascii, uos, machine,uhashlib
from ubinascii import hexlify
b64="""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
"""
def calc_hash(b):
return hexlify(uhashlib.sha256(b).digest()).decode()
# this is the hash of the compiled uartremote.mpy
hash_gen='ccd6ded68ef70594b9c8100d69c3f09e4eff80fefc400633a1aeb94965568c12'
uartremote=ubinascii.a2b_base64(b64)
hash_initial=calc_hash(uartremote)
try: # remove any old versions of uartremote library
uos.remove('/projects/uartremote.py')
uos.remove('/projects/uartremote.mpy')
except OSError:
pass
print('writing uartremote.mpy to folder /projects')
with open('/projects/uartremote.mpy','wb') as f:
f.write(uartremote)
print('Finished writing uartremote.mpy.')
print('Checking hash.')
uartremote_check=open('/projects/uartremote.mpy','rb').read()
hash_check=calc_hash(uartremote_check)
print('Hash generated: ',hash_gen)
error=False
if hash_initial != hash_gen:
print('Failed hash of base64 input : '+hash_initial)
error=True
if hash_check != hash_gen:
print('Failed hash of .mpy on SPIKE: '+hash_check)
error=True
if not error:
print('Uartremote library written succesfully. Resetting....')
machine.reset()
else:
print('Failure in Uartremote library!')
Seu projeto agora está pronto!
Comments