Youtubeでも活動中

チャンネル登録してくれたら喜びます。
リンクはフリーです。共有・拡散は大歓迎!

このボタンで簡単にチャンネル登録!
PR

RaspberryPiPicoとRaspberryPiでI2Cを使うときに気を付けること

raspberryPi-raspberrypipico-i2c-eyecatch

以前から紹介しているI2C通信を使用したIOエキスパンダー[MCP23017]

について、RaspberryPiPicoでも使えるようにしてみました。

やっぱり出力できるピンの数は少ないより、多いほうが良いですよね!

基本的な使い方はRaspberryPiと一緒ですが、

I2Cのアドレス関係にちょっとクセがあったのでちょっとご紹介します。

この記事を読むことでわかること

自己紹介

東証一部上場企業でサラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

2022年5月に転職。現役バリバリの技術者です。
現在は超大手企業の新規事業分野で装置の研究・開発をしています。

Youtubeチャンネルにさまざまな動画を上げています

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

IOエキスパンダー【MCP23017】

今回使用するIOエキスパンダーは、

IO点数を増やすのによく使われるICです。

RaspberryPiPicoと「I2C通信」と呼ばれる通信方式で通信します。

兄弟機種で、MCP23S17という「SPI通信」を使用するICもあります。

今回は「I2C通信」でうごくMCP23017だけを紹介します。

RaspberryPiだったらMCP23017はどう使う??

以前のわたしの記事で紹介していますが、

RaspberryPiPicoではなく、RaspberryPiでMCP23017を使用する場合は、

こちらをご覧ください。

この記事で配線からPythonのプログラムなどすべて解説しています。

細かい方式の話などは、↑↑↑

以前の記事を参考にしてください。

今回の記事は、RaspberryPiPicoで使う場合に、ちょっと引っかかりそうなところ

について解説します。

RaspberryPiPicoとMCP23017の配線

まずは配線方法からご紹介します。

配線が終わっていないとここからの話に進めません。

というわけでこんな感じで配線してみましょう。

mcp23017_1_raspberryPico
SDA0とSCL0にMCP23017を接続する。

今回は、GP8にSDAとGP9にSCLが割り当てられているので

それを使用しています。

RaspberryPiで使うときと違うところ

さて、本題ですが、RaspberryPiはLinuxベースのOSが入っているのは、

あなたもご存じかと思います。

RaspberryPiPicoはOSが入っていないマイコンボードですね。

RaspberryPiと違うところ①I2Cアドレス

RaspberryPiとまず違うところが、I2Cアドレスの調べ方(確認の仕方)です。

RaspberryPiの場合、LXターミナルで、i2cdetectなんて打てば

画面上にこんな感じで表示されます。

RaspberryPii2cdetect
RaspberryPiでi2cdetectを打ち込んだ結果画面

では、RaspberryPiPicoはOSが入っていないので、

Pythonで確認用のソースを書いてあげる必要があります。

早速コードをこちらに書いておきます。

こちらのコードをThonnyでもVSCodeでもなんでもいいので、

RaspberryPiPicoにつないだ状態で実行してみましょう。

import machine
import time
sda_pin=machine.Pin(8)
scl_pin=machine.Pin(9)
i2c=machine.I2C(0,sda=sda_pin, scl=scl_pin, freq=400000)
print(i2c.scan())

ここで重要なのが、i2c.scan()です。

machineライブラリの中に、i2cのアドレスをスキャンする便利なものがあるので

こちらを使用しているのですが、

この場合の出力結果というと….

[32]

はい。32と表示されます。

以前のこちらの記事をご覧いただいていれば、

違和感を感じますよね??

そうです。今回の配線方法だと、20と出てくれないと困りますよね?

ただ、安心してください。

32で合っています。

なぜかというと、このi2c.scan()は、10進数でアドレスを返します。

つまり、0d32

16進数に直すと、0x20

というわけで、ちゃんとアドレスは0x20と認識されています。

10進数で帰ってくるとは思ってもいなかったので、

MCP23017が壊れていないか?などいろいろ調べてタイムロスしました…笑

RaspberryPiと違うところ②I2Cバスの数

いやいや、いきなりI2Cバスってなんだよって話ですよね。

I2Cバスですが、イメージとしてはUSBハブみたいなものです。

I2C自体、アドレスが複数ありますが、

その複数のアドレスが別チャンネルであるって話です。

具体的な話を例にすると、

こちらのようにRaspberryPiのデータシート上だと、

SDA,SCLのセットはGPIO2とGPIO3の実質1セットだけです。

raspberryPidatasheet
RaspberryPiのデータシートより

ではRaspberryPiPicoはどうかというと….

raspberrypipico-pin
raspberryPiPicoのピン配置。水色がI2C関連のピン

よく見てもらうと、I2C0とI2C1という2種類のI2Cが存在します。

つまり、おなじ0x20というアドレスでも、

I2C0とI2C1で別々のモジュールが接続できるということです。

ちょっとやってみましょう。

まず、配線をこのように変えてみます。

mcp23017_raspberryPico
SDA1とSCL1にMCP23017を接続する。

変更したところは、RaspberryPiPicoのGPピンを

GP08⇒GP06

GP09⇒GP07

です。先ほどのピンの割り付けを見てもらうと、

GP08:I2C0 SDA

GP09:I2C0 SCL

GP06:I2C1 SDA

GP07:I2C1 SCL

となっています。ですから単純にI2C0を使用していたのを、

I2C1に変更しています。

先ほど示したi2c.scan()をしてみましょう。

すると、

ValueError: bad SCL pin

こんな風にエラーがでます。

では、どうやって認識させるかというと….

import machine
import time
sda_pin=machine.Pin(6)
scl_pin=machine.Pin(7)
i2c=machine.I2C(1,sda=sda_pin, scl=scl_pin, freq=400000)#引数の1つ目を1に変更
print(i2c.scan())

これだけで[32]と表示されます。

そう。つまりI2C1を指定してscanすれば認識できるということ。

I2C0とI2C1はもちろん別物ですから、

例としてMCP23017を挙げると、

アドレスを変えて8個接続可能です。

ただそれはI2Cのバスが1つの時に限った話で、

バスが2つならば倍の数接続可能です。

つまり、I2C0に8個、I2C1に8個接続可能なので、

なんと最大16*16で256点増加させることが可能ということです。

さらにSPI通信も2系統あるので、MCP23S17も併用すると….

というわけでで現実問題つなぐ人はいないくらい増やせます。

まとめ

今回はRaspberryPiとRaspberryPiPicoで異なるところについてご紹介しました。

RaspberryPiのほうがなぜI2Cのバスが1つしかないのかに関しては謎ですが、

RaspberryPiPicoはしっかり2つバスが明記されているので

たくさんI2C通信したい場合は便利という話ですね。

また、わたしはMCP23017のアドレスの決め方を調べていたので、

i2c.scan()のときに32と出て違和感があったのですが、

初めて使用するi2cモジュールの場合は必ずi2c.scan()の結果が10進数であることに

注意しましょう。そのまま0x32なんてやると動きません….

コメント

タイトルとURLをコピーしました