Python
Linux
JetsonTK1

9軸ジャイロセンサをJetson TK1で使う。

目的

AE-BMX055 9軸ジャイロセンサをJetson TK1に接続する方法の1例を紹介します。

手順概要

  1. AE-BMX055とJetson TK1の配線
  2. i2c-toolsのインストール
  3. BMX055.pyのソーコード修正と実行

配線

配線はいたって簡単で、Jetson TK1のJ3A1コネクタとAE-BMX055を以下のように接続します。
image.png

注意点
上図の配線を行う場合は、AE-BMX055のJP8を半田でショートさせてください。

Jetson TK1のI2C出力ポートや、AE-BMX055のJE6, JE7, JE8のオープンショートを切り替えることで
様々な配線のバリエーションが考えられますが、一例として上記のように設定しています。
ちなみに, AE-BMX055のI2Cアドレスも数通り選択することができますが、JP1, JP2, JP3がオープンである、
購入したままの構成の場合は, 0x19アドレスに加速度の値, 0x69アドレスにジャイロの値, 0x13アドレスに磁気センサの値が設定されます。

参考までに、AE-BMX055とJetson TK1のピン配置図を転載します。

AE-BMX055図

image.png
出典:[http://akizukidenshi.com/download/ds/akizuki/AE-BMX055_20180403.pdf]

AE-BMX055回路図

image.png
出典:[http://akizukidenshi.com/download/ds/akizuki/AE-BMX055_20180403.pdf]

 Jetson TK1 ピン回路図

J3A1_I2C-highlighted.png
出典:eLinux

Jetson TK1 ピン配置図

pins.png
出典: http://platypus-boats.readthedocs.io/en/latest/source/jetson/peripheral/imu.html

Jetson TK1とBMX055接続図

i2c-toolsの設定

  1. i2c-toolsをインストールします
$ sudo apt install i2c-tools
  1. i2c接続の確認
$ sudo i2cdetect -r 0
WRNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0 using read byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- 13 -- -- -- -- -- 19 -- -- UU -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- 
50: -- -- -- -- -- -- 56 -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --             

上記のような出力が出ると成功です。
今回はJetson-tk1はGEN1-I2Cに接続しているためポート番号0で(-r 0)と指定します。
そして、JP1, JP2, JP3が購入時のままオープンである場合は、加速度センサのアドレス(0x19)
ジャイロセンサのアドレス(0x69), 磁気センサのアドレス(0x13)が上記のように出力結果に現れます。
sudoをつけないとパーミッションエラーになるので注意してください。

$ sudo i2cdump -y -r 0 0x19
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: fa 20 c1 c9 31 fa 01 23 12 00 00 00 00 ff 81 03    ? ??1??#?.....??
10: 0f 00 00 00 00 ff 00 00 00 00 00 00 ff ff 00 ff    ?...............
20: 05 00 09 30 81 0f c0 00 14 14 04 0a 18 48 08 11    ?.?0???.?????H??
30: 00 ff 00 f4 00 00 10 00 00 00 00 00 00 ff 00 d9    ...?..?........?
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
80: fa 20 21 c9 91 f9 71 23 12 00 00 00 00 ff 81 03    ? !???q#?.....??
90: 0f 00 00 00 00 ff 00 00 00 00 00 00 ff ff 00 ff    ?...............
a0: 05 00 09 30 81 0f c0 00 14 14 04 0a 18 48 08 11    ?.?0???.?????H??
b0: 00 ff 00 f4 00 00 10 00 00 00 00 00 00 ff 00 91    ...?..?........?
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

また、上記のようにi2cdumpで指定のi2cポートとアドレスに値が来ているか簡単にチェックすることができます。
ここでは、何らかの値が受信されている程度の確認をします。
具体的なデータはpythonスクリプトを用いて確認をしています。

BMX055.pyの修正と実行

BMX055のデータをpythonプログラムにて読み取ります。
基本的にはオリジナルのBMX055.py
の設定にて動作しますが、今回のJetson-TK1で利用しているi2c-port番号が0番であるのと、
秋月電子のAE-BMX055でJP1~JP3ジャンパピン設定に伴いアドレスの変更が必要になります。
以下は、オリジナルのプログラムから、i2c-port番号とセンサのアドレスの変更、10[ms]毎のデータ表示
を行うように変更しています。

import smbus
import time

# Get I2C bus
bus = smbus.SMBus(0) #

# BMX055 Accl address, 0x19
# Select PMU_Range register, 0x0F(15)
#       0x03(03)    Range = +/- 2g
bus.write_byte_data(0x19, 0x0F, 0x03)
# BMX055 Accl address, 0x19
# Select PMU_BW register, 0x10(16)
#       0x08(08)    Bandwidth = 7.81 Hz
bus.write_byte_data(0x19, 0x10, 0x08)
# BMX055 Accl address, 0x19
# Select PMU_LPW register, 0x11(17)
#       0x00(00)    Normal mode, Sleep duration = 0.5ms
bus.write_byte_data(0x19, 0x11, 0x00)

time.sleep(0.5)

# BMX055 Gyro address, 0x69
# Select Range register, 0x0F(15)
#       0x04(04)    Full scale = +/- 125 degree/s
bus.write_byte_data(0x69, 0x0F, 0x04)
# BMX055 Gyro address, 0x69
# Select Bandwidth register, 0x10(16)
#       0x07(07)    ODR = 100 Hz
bus.write_byte_data(0x69, 0x10, 0x07)
# BMX055 Gyro address, 0x69
# Select LPM1 register, 0x11(17)
#       0x00(00)    Normal mode, Sleep duration = 2ms
bus.write_byte_data(0x69, 0x11, 0x00)

time.sleep(0.5)

# BMX055 Mag address, 0x13
# Select Mag register, 0x4B(75)
#       0x83(121)   Soft reset
bus.write_byte_data(0x13, 0x4B, 0x83)
# BMX055 Mag address, 0x13
# Select Mag register, 0x4C(76)
#       0x00(00)    Normal Mode, ODR = 10 Hz
bus.write_byte_data(0x13, 0x4C, 0x00)
# BMX055 Mag address, 0x13
# Select Mag register, 0x4E(78)
#       0x84(122)   X, Y, Z-Axis enabled
bus.write_byte_data(0x13, 0x4E, 0x84)
# BMX055 Mag address, 0x13
# Select Mag register, 0x51(81)
#       0x04(04)    No. of Repetitions for X-Y Axis = 9
bus.write_byte_data(0x13, 0x51, 0x04)
# BMX055 Mag address, 0x13
# Select Mag register, 0x52(82)
#       0x0F(15)    No. of Repetitions for Z-Axis = 15
bus.write_byte_data(0x13, 0x52, 0x0F)

time.sleep(0.5)



# Output data to screen
while True:
    # BMX055 Accl address, 0x19(24)
    # Read data back from 0x02(02), 6 bytes
    # xAccl LSB, xAccl MSB, yAccl LSB, yAccl MSB, zAccl LSB, zAccl MSB
    data = bus.read_i2c_block_data(0x19, 0x02, 6)
    # Convert the data to 12-bits
    xAccl = ((data[1] * 256) + (data[0] & 0xF0)) / 16
    if xAccl > 2047 :
        xAccl -= 4096
    yAccl = ((data[3] * 256) + (data[2] & 0xF0)) / 16
    if yAccl > 2047 :
        yAccl -= 4096
    zAccl = ((data[5] * 256) + (data[4] & 0xF0)) / 16
    if zAccl > 2047 :
        zAccl -= 4096

    # BMX055 Gyro address, 0x69(104)
    # Read data back from 0x02(02), 6 bytes
    # xGyro LSB, xGyro MSB, yGyro LSB, yGyro MSB, zGyro LSB, zGyro MSB
    data = bus.read_i2c_block_data(0x69, 0x02, 6)
    # Convert the data
    xGyro = data[1] * 256 + data[0]
    if xGyro > 32767 :
        xGyro -= 65536
    yGyro = data[3] * 256 + data[2]
    if yGyro > 32767 :
        yGyro -= 65536
    zGyro = data[5] * 256 + data[4]
    if zGyro > 32767 :
        zGyro -= 65536

    # BMX055 Mag address, 0x13(16)
    # Read data back from 0x42(66), 6 bytes
    # X-Axis LSB, X-Axis MSB, Y-Axis LSB, Y-Axis MSB, Z-Axis LSB, Z-Axis MSB
    data = bus.read_i2c_block_data(0x13, 0x42, 6)

    # Convert the data
    xMag = ((data[1] * 256) + (data[0] & 0xF8)) / 8
    if xMag > 4095 :
        xMag -= 8192
    yMag = ((data[3] * 256) + (data[2] & 0xF8)) / 8
    if yMag > 4095 :
        yMag -= 8192
    zMag = ((data[5] * 256) + (data[4] & 0xFE)) / 2
    if zMag > 16383 :
        zMag -= 32768

    print "Acceleration in X-Axis : %d" %xAccl
    print "Acceleration in Y-Axis : %d" %yAccl
    print "Acceleration in Z-Axis : %d" %zAccl
    print "X-Axis of Rotation : %d" %xGyro
    print "Y-Axis of Rotation : %d" %yGyro
    print "Z-Axis of Rotation : %d" %zGyro
    print "Magnetic field in X-Axis : %d" %xMag
    print "Magnetic field in Y-Axis : %d" %yMag
    print "Magnetic field in Z-Axis : %d" %zMag
    time.sleep(0.01)

上記プログラムをbmx055.pyという名前で保存した場合、

$ sudo python bmx055.py

というようにsudoをつけて、プログラムを実行する必要があります。