Raspberry Pi3 のi2cピンに,距離センサーであるSRF02という超音波センサーを接続して,超音波が当たった物体までの距離を読み取ることを考えます.
SRF02は,そのレジスタの中に距離情報を格納しているので,その値を何らかの方法で読み取れば良いことになります.C言語などでも読み取れますが,ここではPythonで読み取ってみます.
pigpioというライブラリを用いるので,このPythonスクリプトを実行する前に,pigpioを実行することが前提です.
$ sudo pigpiod
#上位レジスタ0x02 と下位レジスタ0x03を読み込んで距離値に変換する
Beaglebone Black(BBB)につないで使っていた時には,仕様書通りC言語で読めていました.ラズパイ3につないで,pigpio と Pythonで読み取ろうとすると,どうやらBBBとレジスタからのデータの取り出し方が違うようです.
同じやり方で距離に変換してやると,実際の距離とは異なる値になってしまいました.
そこで,
レジスタOx02, 0x03の値を10進数表示して,距離を変えながら調べてみました.
15〜600cmを読み取れるようにした関数が下記です.
#srf02.py
import pigpio
h = pi.i2c_open(BUS, SRF02_I2C_ADDR)
def srf02_read(h):
# レジスタ 0x02, 0x03 の値を読み取る
high = pi.i2c_read_word_data(h,0x02)
low = pi.i2c_read_word_data(h,0x03)
low_low=int(bin(low&0b1111111),2) # lowの下位7bitを抜き出して10進に変換
# 0-128cmの値が入る.
low_high=int(bin(low>>15),2) # lowを15bit右にシフトして10進に変換
# 128-255cmの時に0b1になる
high_low=int(bin(high&0b11),2) # highの下位2bitを抜き出す
# 256cm:0b01, 512cm:0b10
dist =high_low*255+low_high*128+low_low
return dist
実際にこの関数は15cm -- 600cmまでの範囲の距離をほぼ正確に返してくれます.
16cm以下と600cm以上の距離では,このセンサーの性能上正確に距離を測定することができない仕様です.
なぜ,BBBのI2Cと異なるのかは謎ですが,
2byteのデータを格納する順番,つまりインディアンの問題とか,clock streachの問題が有るのかもしれません.
参考URL
http://www.hobbytronics.co.uk/raspberry-pi-i2c-clock-stretching
#2機の超音波センサー間での干渉効果実験
スチレンボードの壁に,
上の写真の様に2機のSRF02を近づけて,それぞれ距離を測定実験してみました.
SRF02間の間隔が10cm程度と,比較的近いので,お互いに干渉し合う可能性があります.
壁までの距離が30cm前後と比較的近いと,超音波による相互干渉による距離読み取りのノイズはほとんど見受けられませんでした.
むしろ,距離が100cmほどに離れると,数秒に一回,かけ離れた距離が観測されるようです.
参考になれば,幸いです.