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

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

手順概要
---
1. [AE-BMX055](http://akizukidenshi.com/catalog/g/gK-13010/)とJetson TK1の配線
2. i2c-toolsのインストール
3. [BMX055.py](https://github.com/ControlEverythingCommunity/BMX055/blob/master/Python/BMX055.py)のソーコード修正と実行

配線
---
配線はいたって簡単で、Jetson TK1のJ3A1コネクタとAE-BMX055を以下のように接続します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253656/9395feaf-1688-f787-79c0-b880e48ee391.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](https://qiita-image-store.s3.amazonaws.com/0/253656/9049cf35-632e-eff6-e6b5-bc93f268b438.png)
出典:[http://akizukidenshi.com/download/ds/akizuki/AE-BMX055_20180403.pdf]

#### AE-BMX055回路図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253656/72c37012-2ce1-f2d2-5ff0-3eba99327d78.png)
出典:[http://akizukidenshi.com/download/ds/akizuki/AE-BMX055_20180403.pdf]

####　Jetson TK1 ピン回路図
![J3A1_I2C-highlighted.png](https://qiita-image-store.s3.amazonaws.com/0/253656/904a96f8-b1f1-71ff-a8b6-224eccd6e285.png)
出典:[eLinux](https://elinux.org/Jetson/I2C)

#### Jetson TK1 ピン配置図
![pins.png](https://qiita-image-store.s3.amazonaws.com/0/253656/f77fd981-4241-2cbe-660a-65713a136142.png)
出典: http://platypus-boats.readthedocs.io/en/latest/source/jetson/peripheral/imu.html

#### Jetson TK1とBMX055接続図


i2c-toolsの設定
---

1. i2c-toolsをインストールします

```bash
$ sudo apt install i2c-tools
```
2. i2c接続の確認

```bash
$ 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をつけないとパーミッションエラーになるので注意してください。

```bash
$ 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](https://github.com/ControlEverythingCommunity/BMX055/blob/master/Python/BMX055.py)
の設定にて動作しますが、今回のJetson-TK1で利用しているi2c-port番号が0番であるのと、
秋月電子のAE-BMX055でJP1~JP3ジャンパピン設定に伴いアドレスの変更が必要になります。
以下は、オリジナルのプログラムから、i2c-port番号とセンサのアドレスの変更、10[ms]毎のデータ表示
を行うように変更しています。

```python
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という名前で保存した場合、

```bash
$ sudo python bmx055.py
```
というようにsudoをつけて、プログラムを実行する必要があります。