以前から紹介しているI2C通信を使用したIOエキスパンダー[MCP23017]
について、RaspberryPiPicoでも使えるようにしてみました。
やっぱり出力できるピンの数は少ないより、多いほうが良いですよね!
基本的な使い方はRaspberryPiと一緒ですが、
I2Cのアドレス関係にちょっとクセがあったのでちょっとご紹介します。
Youtubeチャンネルにさまざまな動画を上げています。
↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓
IOエキスパンダー【MCP23017】
今回使用するIOエキスパンダーは、
IO点数を増やすのによく使われるICです。
RaspberryPiPicoと「I2C通信」と呼ばれる通信方式で通信します。
兄弟機種で、MCP23S17という「SPI通信」を使用するICもあります。
今回は「I2C通信」でうごくMCP23017だけを紹介します。
RaspberryPiだったらMCP23017はどう使う??
以前のわたしの記事で紹介していますが、
RaspberryPiPicoではなく、RaspberryPiでMCP23017を使用する場合は、
こちらをご覧ください。
この記事で配線からPythonのプログラムなどすべて解説しています。
細かい方式の話などは、↑↑↑
以前の記事を参考にしてください。
今回の記事は、RaspberryPiPicoで使う場合に、ちょっと引っかかりそうなところ
について解説します。
RaspberryPiPicoとMCP23017の配線
まずは配線方法からご紹介します。
配線が終わっていないとここからの話に進めません。
というわけでこんな感じで配線してみましょう。
今回は、GP8にSDAとGP9にSCLが割り当てられているので
それを使用しています。
RaspberryPiで使うときと違うところ
さて、本題ですが、RaspberryPiはLinuxベースのOSが入っているのは、
あなたもご存じかと思います。
RaspberryPiPicoはOSが入っていないマイコンボードですね。
RaspberryPiと違うところ①I2Cアドレス
RaspberryPiとまず違うところが、I2Cアドレスの調べ方(確認の仕方)です。
RaspberryPiの場合、LXターミナルで、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セットだけです。
ではRaspberryPiPicoはどうかというと….
よく見てもらうと、I2C0とI2C1という2種類のI2Cが存在します。
つまり、おなじ0x20というアドレスでも、
I2C0とI2C1で別々のモジュールが接続できるということです。
ちょっとやってみましょう。
まず、配線をこのように変えてみます。
変更したところは、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なんてやると動きません….
コメント