下の図はRaspberry PiのI2C端子にTF Mini Plusを接続した様子です.0x12のところにTF Mini Plusがあるようです.ここまではいい感じです.

この後,I2C経由で距離を得るための方法について調べたところ,こちらのフォーラムにたどり着きました.この中に書かれていた下記プログラムで距離が得られそうです.
# For TFmini Plus
from smbus2 import SMBus, i2c_msg
import time
import random
# To get the addresses of detected devices type:
# sudo i2cdetect -y 1 or 0
# I2C bus number. For a raspberry pi 3
# this should be 1, older raspberry pi's
# this could be 0
I2CBUS = 1
# LiDAR Address
ADDRESS = 0x12
# min and max are in centimeters
SIM_MIN = 90.17 # centimeters
SIM_MAX = 92.71 # centimeters
class TFMiniPlus:
def __init__(self, i2c_address=ADDRESS, bus=None, simulate=False, sim_min=SIM_MIN, sim_max=SIM_MAX):
self.addr = i2c_address
self.sim_min = sim_min
self.sim_max = sim_max
self.simulate = simulate
if not simulate:
if bus is None:
self.bus = SMBus(I2CBUS) # Initialize I2C
else:
self.bus = bus
# end if
# end if
# end __init__
# Write a single command
def write_cmd(self, cmd):
self.bus.write_byte(self.addr, cmd)
time.sleep(0.0001)
# end write_cmd
# Write a command and argument
def write_cmd_arg(self, cmd, data):
self.bus.write_byte_data(self.addr, cmd, data)
time.sleep(0.0001)
# end wripte_cmd_arg
# Write a block of data
def write_block_data(self, cmd, data):
self.bus.write_i2c_block_data(self.addr, cmd, data)
time.sleep(0.0001)
# end write_block_data
# Read a single byte
def read(self):
return self.bus.read_byte(self.addr)
# end read
def read_data(self, cmd):
return self.bus.read_byte_data(self.addr, cmd)
# end read_data
# Read a block of data
def read_block_data(self, cmd):
# return self.bus.read_block_data(self.addr, cmd)
return self.bus.read_i2c_block_data(self.addr, cmd, 0)
# end read_block_data
def get_reading(self):
# get the first timestamp
ts1 = time.time()
if not self.simulate:
# block object to store the readings
block = list()
# returns a dictionary with the reading data
COMMAND = [0x5A, 0x05, 0x00, 0x01, 0x60]
# writes the command block to the device,
# expecting the reading back
self.write_block_data(0x00, COMMAND)
# sleep a short time waiting for the device
time.sleep(0.01)
# loop through and get the return data back
for a_byte in range(0, 9):
byte = self.read()
block.insert(a_byte, byte)
# end for
# check the headers
if block[0] == 0x59 and block[1] == 0x59:
#print("printing python3 compatible part")
distance = block[2] + block[3]*256
strength = block[4] + block[5]*256
temperature = block[6] + block[7]*256
temperature = (temperature/8) - 256
# end if
if block[0] == "Y" and block[1] == "Y":
distL = int(block[2].encode("hex"), 16)
distH = int(block[3].encode("hex"), 16)
stL = int(block[4].encode("hex"), 16)
stH = int(block[5].encode("hex"), 16)
distance = distL + distH*256
strength = stL + stH*256
tempL = int(block[6].encode("hex"), 16)
tempH = int(block[7].encode("hex"), 16)
temperature = tempL + tempH*256
temperature = (temperature/8) - 256
# end if
else:
distance = random.uniform(self.sim_min, self.sim_max)
strength = 300.0
temperature = 80.0
# end if
# gets the second timestamp and the difference
ts2 = time.time()
ttr = ts2 - ts1
data_block = {
"distance" : distance,
"strength" : strength,
"temperature" : temperature,
"ttr" : ttr
}
return data_block
# end class
tf = TFMiniPlus()
print(tf.get_reading())
実行すると,距離や温度などが得られることを確認できました.あとはこれをPICのC言語へ落とし込めばというところです.
コマンドラインi2c***でどうにかならんか検討したところ,次のようにすればi2cdump -y 1 0x12動作しました.
i2cset -y 1 0x12 0x5A 0x05 0x00 0x01 0x60 i i2cdump -y 1 0x12
0x5A 0x05 0x00 0x01 0x60は,データシートによるとI2Cのときにデータを取得するために用いられるコマンドの様です.そのコマンドを送ったのち,値を取りに行けばよいみたいです.上の例ではi2cdumpを使いましたが,i2cgetで1バイトずつ取得しても大丈夫でした.
