LoginSignup
2
1

More than 1 year has passed since last update.

micro:bit v2 の MicroPython で OLED を使う(ssd1306モジュール修正編)

Last updated at Posted at 2021-12-09

micro:bit Advent Calendar 20217日目の続きです。

今回は、ssd1306モジュールを7日目に作成した MicroPython で使えるようにしてみます。

I2C API の相違

ssd1306モジュールは machine.I2C モジュールの利用を前提にしていますが、micro:bit にはこのモジュールが無く、I2C の利用には microbit.i2cを使います。両者のAPIは多少違っているので、ssd1306モジュールを micro:bit 用に書き換える必要があります。具体的には以下のように書き換えてみました。

--- micropython/drivers/display/ssd1306.py  2021-11-27 19:36:01.000000000 +0900
+++ ssd1306.py  2021-12-10 00:29:43.000000000 +0900
@@ -114,17 +114,16 @@
         self.i2c = i2c
         self.addr = addr
         self.temp = bytearray(2)
-        self.write_list = [b"\x40", None]  # Co=0, D/C#=1
         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)
+        self.i2c.write(self.addr, self.temp)

     def write_data(self, buf):
-        self.write_list[1] = buf
-        self.i2c.writevto(self.addr, self.write_list)
+        data = b'\x40' + bytes(buf)
+        self.i2c.write(self.addr, data)


 class SSD1306_SPI(SSD1306):

mpremoteを使って、micro:bit に転送しておきます。

$ mpremote cp ssd1306.py :ssd1306.py

これで ssd1306 モジュールが micro:bit でも使えるようになりました。

動かしてみる

試しに 3D CUBE のアニメーションを動かしてみます。

I2C インタフェースの OLED と micro:bit のピンとは以下のように配線します。

OLED micro:bit
VCC 3V
GND GND
SCL 19 (SCL)
SDA 20 (SDA)
# 3D CUBE MicroPython version with micro:bit and ssd1306 OLED 

from microbit import i2c, sleep
from math import sin, cos
from ssd1306 import SSD1306_I2C


X = const(64)
Y = const(32)

oled = SSD1306_I2C(X * 2, Y * 2, i2c)

f = [[0.0 for _ in range(3)] for _ in range(8)]
cube = ((-20,-20, 20), (20,-20, 20), (20,20, 20), (-20,20, 20),
        (-20,-20,-20), (20,-20,-20), (20,20,-20), (-20,20,-20))

while True:
    for angle in range(0, 361, 3):  # 0 to 360 deg 3step
        for i in range(8):
            r  = angle * 0.0174532  # 1 degree
            x1 = cube[i][2] * sin(r) + cube[i][0] * cos(r)  # rotate Y
            ya = cube[i][1]
            z1 = cube[i][2] * cos(r) - cube[i][0] * sin(r)
            x2 = x1
            y2 = ya * cos(r) - z1 * sin(r)  # rotate X
            z2 = ya * sin(r) + z1 * cos(r)
            x3 = x2 * cos(r) - y2 * sin(r)  # rotate Z
            y3 = x2 * sin(r) + y2 * cos(r)
            z3 = z2
            x3 = x3 + X
            y3 = y3 + Y
            f[i][0] = x3  # store new values
            f[i][1] = y3
            f[i][2] = z3
        oled.fill(0)  # clear
        oled.line(int(f[0][0]), int(f[0][1]), int(f[1][0]), int(f[1][1]), 1)
        oled.line(int(f[1][0]), int(f[1][1]), int(f[2][0]), int(f[2][1]), 1)
        oled.line(int(f[2][0]), int(f[2][1]), int(f[3][0]), int(f[3][1]), 1)
        oled.line(int(f[3][0]), int(f[3][1]), int(f[0][0]), int(f[0][1]), 1)
        oled.line(int(f[4][0]), int(f[4][1]), int(f[5][0]), int(f[5][1]), 1)
        oled.line(int(f[5][0]), int(f[5][1]), int(f[6][0]), int(f[6][1]), 1)
        oled.line(int(f[6][0]), int(f[6][1]), int(f[7][0]), int(f[7][1]), 1)
        oled.line(int(f[7][0]), int(f[7][1]), int(f[4][0]), int(f[4][1]), 1)
        oled.line(int(f[0][0]), int(f[0][1]), int(f[4][0]), int(f[4][1]), 1)
        oled.line(int(f[1][0]), int(f[1][1]), int(f[5][0]), int(f[5][1]), 1)
        oled.line(int(f[2][0]), int(f[2][1]), int(f[6][0]), int(f[6][1]), 1)
        oled.line(int(f[3][0]), int(f[3][1]), int(f[7][0]), int(f[7][1]), 1)
        oled.line(int(f[1][0]), int(f[1][1]), int(f[3][0]), int(f[3][1]), 1)
        oled.line(int(f[0][0]), int(f[0][1]), int(f[2][0]), int(f[2][1]), 1)
        oled.text('3D CUBE', 0, 0)
        oled.show()  # display
        sleep(1)

めでたく動きました。

$ mpremote cp main.py :main.py

unnamed.jpg

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1