Raspberry Pi でシャープ測距モジュール GP2Y0E03を使ってみよう
北本です。今回はC#ではなく、2ヶ月ほど間が空いてしまいましたが、Raspberry Piの話題に戻ります。
前回、シャープ測距モジュール GP2Y0E03とラズパイでI2C通信を行おうとしました。しかし、「i2cdetect -y 1」コマンドを実行しても測距モジュールが検出されず、「dmesg | grep i2c」コマンドを実行してもbcm2708_i2cが検出されませんでした。
そんなところに光明を与えたのが弊社國松のブログ投稿でした。詳細は当該記事を参照していただくこととしますが、I2Cが使えなかったのはカーネルのバージョンが原因で、bcm2708モジュールをダウンロードして上書きすることで解決しました。
身内ではありますが、この記事に助けられた者がここにいます。きっと他の誰かの役に立つ情報のはずです。私も誰かの役に立つものを投稿できるよう目指していきたいものですね。
前述の手順を踏むことで、dmesg | grep i2c」コマンドでbcm2708_i2cを検出することには成功しました。しかし、「i2cdetect -y 1」コマンドでのGP2Y0E03の検出がまだできません。それは初歩的なミスが原因でした。接続するピンを間違えていた、その一言に尽きます。
前回記事に書いていた
端子⑥ SCL …… 5ピンに接続
端子⑦ SDA …… 3ピンに接続
これを、5ピン(GPIO3)、3ピン(GPIO2)ではなく、29ピン(GPIO5)、5ピン(GPIO3)に接続してしまっていたのが根源でした。要するにGPIOの番号とピンの番号を混同してしまっていたわけです。接続を修正することで、無事0x40アドレスにGP2Y0E03を検出することができました。
では、実際にセンサが機能しているのを確かめてみます。実行するのは以下のコードです(wiringPiのインストールが必要です)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <wiringPi.h> #include <wiringPiI2C.h> #include <stdio.h> int main(void){ int fd = wiringPiI2CSetup(0x40); int upper = 0; // 上位8ビット(11~4) int lower = 0; // 下位4ビット(3~0) int value = 0; int count = 0; while(count < 100){ upper = wiringPiI2CReadReg8(fd, 0x5E); lower = wiringPiI2CReadReg8(fd, 0x5F); value = upper << 4 | lower; printf("%d(%x)\n", value, value); delay(1000); // 1000ミリ秒待機 count++; } return 0; } |
1秒ごとにセンサの測距値を標準出力し、それを100回実行で終了するプログラムです。
まず、wiringPiI2CSetup関数でGP2Y0E03のアドレス0x40を設定します。
そして、wiringPiI2CReadReg8で値の読み出しをします。GP2Y0E03のアプリケーションノートP16(リンク先のPDFを参照)を参照するとレジスタのアドレス0x5Eに測距値の上位8ビット(11~4)、アドレス0x5Fに下位4ビット(3~0)が格納されていることがわかります。
これら上位ビット、下位ビットを演算して12ビット分の値に纏め、printfで標準出力します。
実際に動かしてみた時の映像です。小さくて見づらいですが、センサーに手を近付けたり離したりするのに合わせて出力される値が変化しているのがおわかりいただけるでしょうか?
このように無事測距モジュールを使えるようになったわけですが、残された疑問もひとつ。
SCL、SDA接続箇所の波形をオシロスコープで見てみたのですが、まともな波形が観測できなかったのです。オシロスコープの使い方を誤っているのかそれとも?この辺りもできれば解決しておきたいところです。