Raspberry Pi Pico を使ってみた [5] – Micro Python で I2C 通信


Raspberry Pi Pico の I2C
RP2040 には、2チャンネルの独立した I2C コントローラ(I2C0 / I2c1)を持っており、Raspberry Pi Pico では GP[0] ~ GP[27] の各端子から利用可能になっています. 今回はこの機能を使って、デジタル温度センサと EEPROM の読み書きを試してみました.

デジタル温度センサ TMP102 モジュールを接続する

TMP102 モジュール
TMP102 デバイスは、 TI社製の高精度デジタル温度センサです.12ビットの ADC を内蔵し、最小で 0.0625°Cの分解能があり、較正や外部部品による信号コンディショニングなしで ±0.5°Cの精度を実現します.
ここでは、この温度センサ IC と周辺部品(I2C プルアップ抵抗等)を実装した SparkFun 製のモジュールを使って Raspberry pi pico と接続してみます.
TMP102 モジュール
ハードウェア接続
下に Raspberry Pi Pico の I/O 端子と TMP102 モジュール間の配線を示します.I2C のプルアップ抵抗等の必要部品はモジュール基板上に実装されていますので、I2C と電源・GND 端子をそれぞれ接続するだけです. I2C のスレーブアドレスはモジュール基板上のジャンパ設定で変更できますが、デフォルトでは 0x48 となっています.
回路

実体接続
ソフトウェア(Micro Python コード)
これまでと同様、Micro Python を使用します. MicroPython ライブラリのドキュメントを参照し、2線式シリアルプロトコル(I2C)に使う I2C クラスの使用例を確認しながらコーディングしていきます.
# I2C の設定(GP0 端子を SDA, GP1 端子を SCL として使用、クロック 100kHz)
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)

# I2C デバイスのアドレスをスキャン
addr = i2c.scan()

# スレーブアドレス 0x48 のデバイスから 2バイトを読み出す
data = i2c.readfrom(0x48, 2)

# スレーブアドレス 0x50 の メモリアドレス 0x02 から 2バイトを書き込む
i2c.writeto_mem(0x50, 0x02, b'\x10')

# スレーブアドレス 0x50 の メモリアドレス 0x08 からはじまる 3バイトを読み込む
i2c.readfrom_mem(0x50, 0x08, 3)
from machine import Pin, I2C
import time

i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)

addr = i2c.scan()
print( "address is :" + str(addr) )

for i in range(100):
        data = []
        data = i2c.readfrom(0x48, 2)
        intdata = int.from_bytes(data, 'big')
        tmp = intdata >> 4
        print(tmp * 0.0625)
        time.sleep(1)
実行結果
実行結果と I2C 読み出し時の波形を下に示します.
実行結果
下記波形の D0 は SCL、D1 は SDAを、一番下の I2C は取得した波形のデコード結果を示しており、スレーブアドレスの 0x48 から 2バイトのデータが正しく読み出せていることが分かります.
Pulse View 波形

EEPROM を接続する

続いては I2C インターフェースのシリアル EEPROM との接続を試してみます.使用するデバイスは ROHM 社製 BR24L32 デバイスです. (下の写真はピッチ変換基板に実装した状態です)
BR24L32
ハードウェア接続
下に Raspberry Pi Pico の I/O 端子と BR24L32 間の配線を示します.I2C と電源・GND 端子のほか、書込み保護制御用の /WP を Raspberry Pi Pico の GP2 に接続します. I2C スレーブアドレス選択用のピン A0 ~ A2 は GND に接続しており、スレーブアドレスは 0x50 となっています.
回路

実体接続

ソフトウェア(Micro Python コード)
i2c.writeto_mem と i2c.readfrom_mem 関数を使用してメモリアドレスを指定した書き込み、読み出しを行います.
from machine import Pin, I2C
import time

i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)
wp = Pin(2, Pin.OUT)

addr = i2c.scan()
print( "address is :" + str(addr) )

buff = bytearray(8)
buff = bytes([0x00, 0x11, 0x22, 0x44, 0x88, 0x55, 0xAA, 0xFF])
#buff = bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])

wp.value(0)

# メモリアドレス 0x0F00 から 8バイト読み出し
data_r = i2c.readfrom_mem(int(addr[0]), 0x0F00, 8, addrsize=16)
time.sleep_ms(5)

for i in range(8):
    print(hex(data_r[i]))

# メモリアドレス 0x0F00 から 8バイト書き込み
i2c.writeto_mem(int(addr[0]), 0x0F00, buff, addrsize=16)
time.sleep_ms(5)
print("----------")

# メモリアドレス 0x0F00 から 8バイト読み出し
data_r = i2c.readfrom_mem(int(addr[0]), 0x0F00, 8, addrsize=16)
time.sleep_ms(5)

for i in range(8):
    print(hex(data_r[i]))

実行結果
実行結果
書き込み時、読み出し時それぞれの波形を示します.
Pulse View 波形(Write)
Pulse View 波形(Read)

参考

TI社 高精度デジタル温度センサ TMP102
SparkFun TMP102 モジュール
MicroPython ライブラリのドキュメント
ROHM BR24

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です