from machine import Pin, I2C
import time
import framebuf
class SSD1306_I2C(framebuf.FrameBuffer):
def __init__(self, width, height, i2c, addr=0x3C):
self.width = width
self.height = height
self.i2c = i2c
self.addr = addr
self.buffer = bytearray(self.height * self.width // 8)
super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
self.init_display()
def write_cmd(self, cmd):
self.i2c.writeto(self.addr, b'\x00' + bytearray([cmd]))
def init_display(self):
for cmd in (
0xAE, 0x20, 0x00, 0x40, 0xA1, 0xC8, 0xA8, 0x3F,
0xD3, 0x00, 0xDA, 0x12, 0x81, 0x7F, 0xA4, 0xA6,
0xD5, 0x80, 0x8D, 0x14, 0xAF
):
self.write_cmd(cmd)
self.fill(0)
self.show()
def show(self):
self.write_cmd(0x21)
self.write_cmd(0)
self.write_cmd(self.width - 1)
self.write_cmd(0x22)
self.write_cmd(0)
self.write_cmd(self.height // 8 - 1)
self.i2c.writeto(self.addr, b'\x40' + self.buffer)
def draw_crab(oled):
oled.fill(0)
body_points = [
(40, 30), (55, 20), (73, 20),
(88, 30), (73, 40), (55, 40)
]
for i in range(len(body_points)):
x1, y1 = body_points[i]
x2, y2 = body_points[(i + 1) % len(body_points)]
oled.line(x1, y1, x2, y2, 1)
claw_left = [(25, 25), (15, 15), (10, 25), (20, 30)]
for i in range(len(claw_left) - 1):
x1, y1 = claw_left[i]
x2, y2 = claw_left[i + 1]
oled.line(x1, y1, x2, y2, 1)
claw_right = [(103, 25), (113, 15), (118, 25), (108, 30)]
for i in range(len(claw_right) - 1):
x1, y1 = claw_right[i]
x2, y2 = claw_right[i + 1]
oled.line(x1, y1, x2, y2, 1)
legs_left = [
(50, 40, 40, 50),
(45, 38, 35, 48),
(60, 42, 50, 52)
]
for x1, y1, x2, y2 in legs_left:
oled.line(x1, y1, x2, y2, 1)
legs_right = [
(68, 40, 78, 50),
(73, 38, 83, 48),
(63, 42, 73, 52)
]
for x1, y1, x2, y2 in legs_right:
oled.line(x1, y1, x2, y2, 1)
oled.pixel(58, 18, 1)
oled.pixel(70, 18, 1)
oled.line(58, 18, 58, 22, 1)
oled.line(70, 18, 70, 22, 1)
oled.show()
def main():
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)
while True:
draw_crab(oled)
time.sleep(1)
main()