Polivia Bot Python Raspberry Pi Pico プログラム ロボット制御 電子工作 高専3年生

【Poliviabot】【Raspberry Pi Pico】ロボット制御入門⑦I2C通信とSSD1306表示【Python】

本サイトでは様々な環境で気軽に本格的なロボット教育を行ってもらうべく、独自のロボット教材を開発しました。

現在、一般販売へ向けて準備をしております。

本Webページではβ版の先行体験をしていただく方向けに公開している資料になっております。

一般の方は販売をお待ちください。

前回はこちらです

1 この章の目的

この章では、PoliviaBot UMEの I2C(GP4/GP5) を使って、SSD1306(OLED) に文字を表示します。
Python初心者向けに「I2Cとは何か → 配線 → スキャン → 表示」まで順に進めます。

I2C通信とは?

I2C(アイ・スクエアド・シー)は、マイコンとセンサ/表示器をつなぐための通信方式です。特徴は次の通りです。

  • 2本の線だけで通信できる
    • SDA:データ線
    • SCL:クロック線(タイミング)
  • 1つのバスに複数の機器をつなげる
  • 各機器は I2Cアドレス(例:0x3C)で識別される

2 PoliviaBotのI2Cピン

あなたのピン仕様では以下です。

  • I2C0 SDA:GP4
  • I2C0 SCL:GP5

配線(SSD1306 OLED)

一般的なSSD1306(I2Cタイプ)は端子がこうなっています:

  • VCC(電源)
  • GND
  • SCL
  • SDA

接続は次の通り(※OLEDの電源は基本 3.3V推奨):

OLEDPico W
VCC3V3
GNDGND
SCLGP5
SDAGP4

3 I2Cスキャンで接続確認(最重要)

まず「見えているか」を確認します。これができれば半分成功です。

※ロボットの電源を入れてから実行してください。

from machine import Pin, I2C

i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)

devices = i2c.scan()
print("I2C devices:", devices)

# 16進数表示
print("I2C addresses:", [hex(d) for d in devices])

期待される結果

SSD1306は多くの場合、アドレスが 0x3C または 0x3D です。
例:['0x3c']

4 SSD1306ライブラリについて

MicroPythonでは、SSD1306用のドライバがよく使われます。

液晶ディスプレイに文字を表示させるのを1からコーディングするのは非常に複雑になってしまいますので、ここではmicropythonに搭載されているライブラリ「ssd1306」を活用しましょう。

まずThonnyの画面左上の「ツール」をクリックして開き、「パッケージを管理」をクリックします。

画面上部の検索バーに「ssd1306」と記入しEnterキーを押します。

画面右側にライブラリ名が表示されますのでクリックします。

中央下部の「インストール」をクリックします。

画面左側の<インストール>の項目に「ssd1306」が追加されていればインストールは完了です。

これでライブラリが使用できるようになりましたので、プログラムを書いていきましょう。

まずライブラリをインポートします。

今回はRaspberry Pi Pico WとLCDをI2C通信で接続しますので、machineライブラリの中からI2Cというライブラリもインポートしましょう。

from machine import Pin, I2C
import ssd1306
import time

5 文字を表示する

I2Cアドレスが 0x3C だった場合の例です。

from machine import Pin, I2C
import ssd1306
import time

# I2C初期化(PoliviaBot仕様)
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)

# OLED初期化(128x64が一般的)
oled = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C)

# 画面クリア
oled.fill(0)

# 文字を書く(x, y)
oled.text("PoliviaBot UME", 0, 0)
oled.text("I2C SSD1306 OK!", 0, 16)

# 画面反映(これが超重要)
oled.show()

while True:
    time.sleep(1)

重要ポイント

  • oled.text() は「文字をバッファに書くだけ」
  • oled.show()画面に反映される

※電池が減ってくるとうまく通信できない場合があります

6 複数行の表示と更新

画面を更新するときは毎回、

  1. oled.fill(0) で消す
  2. oled.text() で書く
  3. oled.show() で反映

という流れにするとわかりやすいです。

from machine import Pin, I2C
import ssd1306
import time

i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C)

count = 0

while True:
    oled.fill(0)
    oled.text("PoliviaBot", 0, 0)
    oled.text("Counter:", 0, 16)
    oled.text(str(count), 0, 32)
    oled.show()

    count += 1
    time.sleep(0.5)

課題 12

I2Cスキャン結果をOLEDに表示してください。

解答例はこちら
from machine import Pin, I2C
import ssd1306
import time

i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
devices = i2c.scan()

oled = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C)

oled.fill(0)
oled.text("I2C scan:", 0, 0)
oled.text(str([hex(d) for d in devices]), 0, 16)  # 長い場合は見切れます
oled.show()

while True:
    time.sleep(1)

課題13

超音波センサ(Trig=GP7, Echo=GP6)の距離をOLEDに表示してください。

  1. センサで**距離(数値)**を取得する
  2. その数値を**文字列(テキスト)**に変換する
  3. OLEDに表示して、デバッグできる状態を作る

LEDだけだと「近い/遠い」程度しか分かりませんが、OLEDに数値が出ると調整が一気に楽になります。

解答例はこちら
from machine import Pin, I2C
import ssd1306
import time

i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C)

# --- 超音波(Trig=GP7 / Echo=GP6)---
TRIG = Pin(7, Pin.OUT)
ECHO = Pin(6, Pin.IN)

SOUND_SPEED = 0.0343  # cm/us

def get_distance_cm(timeout_us=30000):
    # Trigパルス
    TRIG.value(0)
    time.sleep_us(2)
    TRIG.value(1)
    time.sleep_us(10)
    TRIG.value(0)

    # EchoがHIGHになるのを待つ(タイムアウト付き)
    t0 = time.ticks_us()
    while ECHO.value() == 0:
        if time.ticks_diff(time.ticks_us(), t0) > timeout_us:
            return None
    start = time.ticks_us()

    # EchoがLOWになるのを待つ(タイムアウト付き)
    while ECHO.value() == 1:
        if time.ticks_diff(time.ticks_us(), start) > timeout_us:
            return None
    end = time.ticks_us()

    duration = time.ticks_diff(end, start)  # us
    distance = (duration * SOUND_SPEED) / 2
    return distance

# --- メインループ ---
while True:
    d = get_distance_cm()

    oled.fill(0)
    oled.text("PoliviaBot UME", 0, 0)
    oled.text("Sonar:", 0, 16)

    if d is None:
        oled.text("Distance: ---", 0, 32)
    else:
        oled.text("{:5.1f} cm".format(d), 0, 32)

    oled.show()
    time.sleep(0.3)

次回はこちら

Follow me!

-Polivia Bot, Python, Raspberry Pi Pico, プログラム, ロボット制御, 電子工作, 高専3年生
-, , , , ,

PAGE TOP