前回(といっても3カ月も前ですが)は、PIRセンサをラズパイに接続し、何か検出したらスマホにお知らせ、というのをやってみました。PIRセンサはシンプルなものでGPIOで接続でした。今回はI2Cバスに接続するセンサを扱ってみたいと思います。こんどは大分以前の回で試してみたシャープ製測距センサです。ソフトウエア的には、MbedOS上のcppのプログラムをRaspbian上のPythonのプログラムに移植する形です。
※「IoT何をいまさら」投稿順Indexはこちら
I2Cバスそのものは電源、グラウンドをのぞけば、SCL, SDAの2本の信号線を接続するだけなので、ちょろいと甘くみて作業を始めたのですが、やってみれば疑問も多数。最初に疑問に思ったのが、
i2c-0 と i2c-1 どっち使ったらよいの?
という問題でした。前回につづき、結線が楽なので「ラズパイマガシン2019-6月号の付録基板(真面目に全部のせしていないやつ)」を使うことにした(冒頭の写真ご参照ください)ので、そちらに合わせる気でいるのですがね。どっちなんでしょうか?分からないとソフト書けないしね。
ま、手順に従い
raspi-configでI2Cをイネーブルにしてリブート後、どのようなデバイスが出来ているのかまず見てみました。
$ i2cdetect -l i2c-1 i2c bcm2835 I2C adapter I2C adapter
i2c-1が出来ていました。i2c-1の機能を調べてみると、以下のようでした。この範囲でソフトを書け、ということでしょう。
$ i2cdetect -F 1 Functionalities implemented by /dev/i2c-1: I2C yes SMBus Quick Command yes SMBus Send Byte yes SMBus Receive Byte yes SMBus Write Byte yes SMBus Read Byte yes SMBus Write Word yes SMBus Read Word yes SMBus Process Call yes SMBus Block Write yes SMBus Block Read no SMBus Block Process Call no SMBus PEC yes I2C Block Write yes I2C Block Read yes
付録基板の結線であれば、J11コネクタのピン3がSDA、ピン5がSCLです。I2C-1がこちらのピンに向いているならば、写真のように接続済のシャープ製測距センサ GP2Y0E03が反応する筈。
$ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
無事に反応が返ってきました。このことからPin3、Pin5に出ているI2CがI2C-1であることが確かめられました。また、アドレスは7ビット扱いで0x40(MbedOSでのドライバ上のアドレスは、最下位のR/Wビットを含めてであったので8ビット扱いで0x80としていた)であることを確認できました。
すると、i2C-0は、Pin27がSDA、Pin28がSCLの方になります。これをイネーブル化するためには、/boot/config.txtに
dtparm=i2c_vc=on
などと書き込んでからリブートすればデバイスi2c-0が使えるようになることが分かりました。なお、デフォルトで使えるピン3、ピン5の方は
dtparm=i2c_arm=on
です。この辺の設定の詳しいことは raspberrypi/linuxのページに説明がありました。ただ、読むとi2c-0を積極的に使わない理由も分かりました。引用させてもらうと、
i2c_vc interfering with Pi Camera
だそうです。当方では、実際 Pi Camera接続しているので、こちらは触らないようにしないと。
接続は出来たので、ST社のNucleoボード用にcppで書いたテストプログラムをPythonに移植して動かしてみました(当然ながら一発では動かなくて、バグフィックスいろいろでしたが)。その結果はこんな感じ。
$ python3 GP2Y0E03.py GP2Y0E03 test program. Shift bit(128cm mode=1)=1, MaxPulsewidth(default=7)7 127 [cm] 127 [cm] 127 [cm] 127 [cm] 127 [cm] 127 [cm] 127 [cm] 127 [cm] 127 [cm] 36 [cm] 127 [cm] 63 [cm] 3 [cm] 6 [cm] 29 [cm] 28 [cm]
1秒に1回、距離をcmで表示するようにして、センサの前で手を動かしてみたところ、まずまず距離を測っている感じ(MAX127cm)です。
次回は、移植で一番問題(時間使ってしまった)になったMbedOS上のI2Cインタフェース関数と、Python側のインタフェース関数の対応などを見ていきたいと思います。