B+にシャープの赤外線距離センサー(GP2Y0A02YK)を接続して距離を測定するプログラムを作成した時の備忘録。この赤外線距離センサーはアナログ信号を返すのでラズパイで直接処理をする事ができないので、アナログ信号をデジタル信号に変換するADコンバーター(MPC3208)を使っている。記事後半でADコンバーターからの電圧を取得するまでのロジックについて説明している。同様の内容の動画を記事の最後にリンクを張っている。ADコンバーター等の説明は動画の方が分かりやすいかも知れないので確認してみて欲しい。今回の記事で使用した赤外線距離センサーのスペックは以下の通り型番、外観GP2Y0A02YK測定可能距離20cm~150cm出力アナログ出力(電圧)RaspberryPiで扱うにはADコンバーターが必要なのでMCP3208を用意した平均消費電流33mA電源電圧4.5~5.5VRaspberryPiの2番ピン(5V)に接続した上記の他に10cm~80cmの測定が可能なGP2Y0A21も一緒に購入したのでそのうちに試してみようと思っている。Coreに接続してリアルタイムの測定結果をクラウドにパブリッシュ(アップロード)することもできる。Coreとの接続はこちらの記事を参考にしてほしい。接続方法GP2Y0A02YKの出力はアナログなのでADコンバーター(MCP3208)経由でRaspberryPiに接続する。GP2Y0A02YKに標準で付属しているリード線は何故かVcc(5V)が黒、GNDが茶色、Vo(output)は白なので注意が必要。事前にSPIを有効にする。インターフェースタブでSPIを有効にして「OK」で保存後にRaspberryPiを再起動する。spidevのインストール以下のコマンドでspidevをインストールした。距離の計算方法についてGP2Y0A02YKは赤外線で測定した距離を電圧で出力するので電圧から距離を算出する必要がある。GP2Y0A02YKのデータシートの3ページ目に電圧と距離の関係を表すグラフが載っていた。縦軸が電圧で横軸が距離(cm)で距離が遠くなるにつれて電圧が低くなっているのだが線形(直線)ではないので単純に電圧の何らかの係数を掛けて算出できるわけではない。※1次関数で表すことができない。近似曲線を算出しようとしたのだがExcelだと簡単に近似曲線が算出できるようなのだが残念ながらExcelは持っていない。そのうちに誰かに借りて試してみようとは思っているがまずは別の方法で出来ないかを検討してみる。見ると10cm単位では(ほぼ)直線なので電圧によって傾きを変えれば近似値を1次関数で計算できそうなので、その方法でいくことにした。上記の例だと2.55v~2vの時は20cm~30cmの間で直線(1次関数)で近似できる。以下、2v~1.55vの時は30cm~40cmの間で・・・と続く。原始的だけど、グラフをA4用紙に印刷してさしがねで値を測定した。作ったのが24~38行目の配列。元となる距離の4つの要素からなっている。ADコンバータから取得した電圧がFrom、Toの範囲内の行を検索して、マッチした行の3.変換率と4.元となる距離を取得する。50行目の計算式で距離を算出する。1.3vー1.25v=0.05v0.05v×0.33cm/v(変換率)×100=1.65cm50cm(元となる距離)ー1.65cm=48.35cm(測定したい距離)と計算した。スマートな方法があるとは思うのでご存知の方はコメントくださいMCP3208ADコンバータ(MCP3208)から電圧を取得するロジックについての備忘録。取得した値を電圧に変換する(12bitなので4095で割る)1行目はRaspberryPiからMCP3208にチャンネルを指定する信号を送っている。2行目はMCP3208からRaspberryPiで電圧を12bitで受け取っている。3行目は2行目で受けた値を電圧に変換している1行目の解説まずはMCP3208のデータシートを参照。14ページの表5-2がMCP3208の構成ビット。上記の表5-2よりCH0の時は0b1000、CH1は0b1001・・・と指定する事が分かる。次に16ページの図6-1(spiモード0,0)のDinを見ると8ビットづつ3セットでチャンネルを指定することが分かる。D0のビットを生成して>>2で後半の2ビット(D1、D0)を削除、更に+0b100で1セット目の8ビット(0b00000110)を作成している。次に(0b1000+ch)までは先程と同様。(0b1000+ch)&0b00111(0b1000+ch)&0b0011で後半2ビットの論理積(AND演算)で前半の2ビット(SINGLE/DIFF、D2)を0にして、<<6で左に6ビットシフトして2セット目の8ビット(0b01000000)を作成している。3セット目の8ビットは無視されるビットなのでとりあえず0をセットした。2行目の解説Doutはraw[0]、raw[1]、raw[2]に8ビットづつセットされるのでraw[0]は不要、raw[1]の後半4ビットとraw[2]の8ビットだけを使用する。raw[1]の後半4ビットとraw[2]の8ビットをつなげて合計12ビットを作りたい。SPIのバージョンアップによりこの指定をしないと動かない!この行が無いと正しい電圧が取得されなかった。実際の計測値との比較RaspberryPiの箱を置いて実際に計測をしてみた。計測を3回行い平均と比較したときの結果は以下の通り。-0.95%およそ3%以内の誤差の範囲に収まっているが、3回の計測の中でも多少のばらつきがある事が分かる。対象物との距離が長くなるとばらつきが増すようにも感じた。対象物をRaspberryPiの箱から別のモノに変えた所、微妙に測定結果が変わった。対象物の材質や色によっても違いが出てくるのだと思う。GP2Y0A02YKの個体差も多少はあるのかも知れない。常に同じ材質のモノとの距離を測定するのであれば前述の配列表の値を変えてやれば、より誤差の少ない測定が可能になる。動画についてこの記事の内容をYoutubeで解説している。ADコンバーターの説明は動画の方が理解しやすいと思うので上記の説明で良く分からない人は見て欲しい。同じような事をやりたい人の参考になればと思ってブログにしてます。Services)、WordPress、RaspberryPiに関するブログを書いています。GENERALに合格しています。分かりやすい様に書いているつもりですが質問があればメニューの「ご質問がある方」か記事一番下にあるコメントにお願いします。役に立ったのであればコメントもらえると嬉しいです。間違いがあればご指摘いただけるとありがたいです。コメントをキャンセルメールアドレスが公開されることはありません。