🦜
【Raspberry Pi Pico W】I2Cの使い方(micropython×Thonny)
1. はじめに
個人的にI2Cでよく使うモジュールのサンプルコードを一か所にまとめときました
1.1 この記事について
- Raspberry Pi Pico W(以下、Pico)でI2Cを使ったサンプルプログラムを記載する
- 細かい解説というより、備忘録とプログラム+回路図のサンプル重視
- 入門・解説というより備忘録に近い
1.2 対象読者
- Picoを使ったことがある
- Thonnyを使ってPicoにプログラムを書き込み・実行ができる
- プログラム言語(特にmicropython)が多少読める、書ける
1.3 動作環境
- PC
- OS:Windows 11 Home
- プログラミング環境:Thonny(v4.1.4)
- Raspberry Pi Pico W
- ファームウェア:micropython v1.24
2. I2Cについて
2.1 概要
- 1つのデータ送伝路を使って、1ビットずつ送信する、シリアル通信方式の1つ
- 2本の信号線(SDA,SCL)ですべてのデータの送受信が行えるため、配線が少なくなる
- 同一線上に複数のデバイスがある場合でも、個々のデバイスを7bitのアドレスで識別することが可能
よりI2Cについて知りたい方は...
以下のリンクの説明が図説などあって分かりやすいので、一読してみてください。
よく分かる! シリアル通信基礎講座 _ 組込み技術ラボ I2C通信
実際のモジュール紹介(一例)
I2Cで使用可能な製品達(うちにあったもの)
4線(Vcc, GND, SDA, SCL)で通信可能だが、モジュール特融の便利機能のため、Pin数は多いものもある。
それらの使い方については、各製品のデータシートを参照のこと
2.2 picoでI2Cを使用できるpinについて
- 以下の図の水色でI2Cと記載されているpinなら使用可能
- デフォルトでは、GP4がSDA, GP5がSCLとなっている
https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html
2.3 machine.I2Cクラスについて
micropythonにはI2Cのクラスが存在するため、それを使うとよい
以下のコードでは、I2Cの通信線でつながっているデバイスのアドレス一覧を表示できる
from machine import Pin, I2C
i2c = I2C(0) # 未指定だとsda=Pin(4), scl=Pin(5)
address_list = i2c.scan() # 認識されているデバイスのアドレスのリストを返す
print(address_list) # 10進数でアドレスを表示(list)
print([hex(x) for x in address_list]) # デバイスのアドレスを16進数表記で表示
実行結果(例)
OLED(128x64)とBMP280を繋いだ場合だと、以下のような結果となる
細かいメソッドなどを知りたい人は...
こちらをどうぞ!!
クラス I2C -- 2線式シリアルプロトコル
3. 実際に使ってみる
- ThonnyのManage Package経由で導入できるものは少ない
- ない場合は、先人たちのGithubのサンプルを利用できるとよい
- それでもない場合は、デバイスのデータシートをよく読み、自力で実装すべし
3.1 有機ELディスプレイに文字を出力する(OLED)
- OLED(有機ELディスプレイ)上に文字や図形を描画することができる
- ライブラリ(ssd1306)がThonny上でインストール可能!
- デバイスは、I2C用の他にSPI用のものもあるため、間違えないように注意!
3.1.1 回路図+配線図(Fritzing)
3.1.2 プログラム例
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
i2c = I2C(0, sda=Pin(4), scl=Pin(5)) # インスタンスを生成
display = SSD1306_I2C(128, 64, i2c)
display.fill(0)
display.fill_rect(0, 0, 32, 32, 1)
display.fill_rect(2, 2, 28, 28, 0)
display.vline(9, 8, 22, 1)
display.vline(16, 2, 22, 1)
display.vline(23, 8, 22, 1)
display.fill_rect(26, 24, 2, 4, 1)
display.text('MicroPython', 40, 0, 1)
display.text('SSD1306', 40, 12, 1)
display.text('OLED 128x64', 40, 24, 1)
display.show()
下記のプログラムを参考にしました。
3.1.3 ライブラリ
「ssd1306.py」を使用します
Thonnyの上部メニュー[Tools]->[Manage packages]->ssd1306で検索->「ssd1306」を選択->【Install】でOK
3.2 気圧をセンシングする(BMP280)
BMP280では温度(℃)・気圧(Pa)を計測できます
3.2.1 回路図+配線図(Fritzing)
3.2.2 プログラム例
コメントアウトを外せば温度も取得できます
from machine import Pin, I2C
from bmp280 import BMP280
from time import sleep_ms
i2c = I2C(0, sda=Pin(4), scl=Pin(5)) # インスタンスを生成
bmp = BMP280(i2c)
while True:
read_pressure = bmp.pressure # 圧力値(Pa)を読み取る
print(f"{read_pressure=}")
# read_temp = bmp.temperature # 温度を読み取る
# print(f"{read_temp=}")
sleep_ms(100)
3.2.3 使用ライブラリ
下記のgithubの「bmp280.py」を使用させていただきました
3.3 物体との距離を計測する(VL53L0X)
3.3.1 回路図+配線図(Fritzing)
3.3.2 プログラム例
from machine import Pin, I2C
from vl53l0x import VL53L0X
from time import sleep_ms
i2c = I2C(0, sda=Pin(4), scl=Pin(5)) # インスタンスを生成
vl53 = VL53L0X(i2c)
while True:
distance = vl53.range # 距離を計測(mm)
print(f"Distance(mm)={distance}")
sleep_ms(1000)
3.3.3 ライブラリ
下記のgithubの「vl53l0x.py」を使用させていただきました
3.4 加速度・角速度を計測する(MPU6500)
3.4.1 回路図+配線図(Fritzing)
3.4.2 プログラム例
コメントアウトを外すと、角速度の他に加速度や温度センサ値を取得できます
from machine import Pin, I2C
from mpu6500 import MPU6500
from time import sleep_ms
i2c = I2C(0, sda=Pin(4), scl=Pin(5)) # インスタンスを生成
mpu6500 = MPU6500(i2c)
while True:
# ax, ay, az = mpu6500.acceleration
gx, gy, gz = mpu6500.gyro
# temp = mpu6500.temperature
# print(f"{ax=} {ay=} {az=}")
print(f"{gx=} {gy=} {gz=}")
# print(f"{temp=}")
sleep_ms(100)
3.4.3 ライブラリ
下記のgithubの「mpu6500.py」を使用させていただきました
3.5 色をセンシングする(TCS34725)
RGBCなどを計測できます
3.5.1 回路図+配線図(Fritzing)
3.5.2 プログラム例
from machine import Pin, I2C
from tcs34725 import TCS34725, html_rgb
from time import sleep_ms
i2c = I2C(0, sda=Pin(4), scl=Pin(5)) # インスタンスを生成
tcs = TCS34725(i2c)
while True:
# temp, lux = tcs.read() # temperature_and_lux
# print(f"{temp=} {lux=}")
data = tcs.read(raw=True)
r, g, b = html_rgb(data) # rgb値に変換
print(f"{r=} {g=} {b=}")
sleep_ms(1000)
3.5.3 ライブラリ
下記のgithubの「tcs34725.py」を使用させていただきました
4. まとめ
- I2Cでいろいろなセンサモジュールを簡単に使うことができる
- 先人たちのGithubを活用させていただくことで、簡単に使える
- それでも見つからなければ、センサモジュールのデータシートで使い方を確認し、I2Cクラスのメソッドを活用して使う
Discussion