LoginSignup
8
7

More than 3 years have passed since last update.

micropythonでOLED (SSD1306) I2C編

Last updated at Posted at 2017-12-16

この記事はMicroPython Advent Calendar 2017の13日目の投稿です。昨日は ken5owataさん投稿のmicropythonでADコンバータでした。

13日目が空いてしまったので小ネタで埋めます。

8日目の投稿にken5owataさんのmicropythonでOLED (SSD1306)がありました。ssd1306 の OLED には I2C で接続するものもあります。今回はAmazonで800円ぐらいで入手したものを使ってみます。

IMG_4243.JPG

SSD1306用ドライバの入手と転送

使うSSD1306用ドライバはSPI版のときと同じものです。githubから拾ってきてampyツールで転送しておきます。

micropython/ssd1306.py at master · micropython/micropython · GitHub

$ ampy -p /dev/tty.usbserial-DN01APO0 ssd1306.py

※上記はMacに EDSr Developer 32 ボードを繋いだときの ampy コマンドの例です。

配線

ESP32 と SSD1306 を接続します。 今回は以下のように配線しました。

SSD1306 ESP32
VCC 3v3
GND GND
SCL IO4
SDA IO5

動かしてみる

MicroPython からの使いかたは SPI の場合とほぼ同じで、SSD1306_SPI の代わりに SSD1306_I2C を使います。8日目のSPIの場合と同じように文字を表示するには以下のようにします。

>>> from machine import Pin, I2C
>>> from ssd1306 import SSD1306_I2C
>>> i2c = I2C(scl=Pin(4), sda=Pin(5))
>>> oled = SSD1306_I2C(128, 64, i2c)
>>> oled.text('MicroPython', 0, 0)
>>> oled.show()
>>> oled.text('Advent Calender', 0, 10)
>>> oled.show()
>>> oled.text('13 days', 0, 20)
>>> oled.show()

IMG_4244.JPG

これだけだと面白くないので、このサイトの 3D Cube プログラムを MicroPython に移植してみました。

IMG_4256.MOV.gif

# 3D CUBE MicroPython version with ESP32 and ssd1306 OLED 

from machine import Pin, I2C
from micropython import const
from time import sleep_ms
from math import sin, cos
from ssd1306 import SSD1306_I2C

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

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))

i2c = I2C(scl=Pin(4), sda=Pin(5))
oled = SSD1306_I2C(X * 2, Y * 2, i2c)

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)  # cross
        oled.line(int(f[0][0]), int(f[0][1]), int(f[2][0]), int(f[2][1]), 1)  # cross
        oled.text('3D CUBE', 0, 0)
        oled.show()  # display
        sleep_ms(1)

MicroPython でも十分な速さで cube が回転します。

8
7
2

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
8
7