トップ

Rasperry Pi Pico W のMicropython で I2CのLSM9DS1モジュールを制御する

ブレッドボードで、Rasperry Pi Pico WとAE-LSM9DS1-I2Cを接続してアドレス確認

入手(2024年4月)したモージュール「AE-LSM9DS1-I2Cを秋月様より購入」で実験した内容です。
これは、STマイクロ社の複合センサーLSM9DS1をI2Cで容易に制御可能したモジュールです。
複合センサーLSM9DS1は、3軸の加速度センサーと3軸のジャイロセンサおよび3軸の磁力センサーの9軸を持っています。

このモジュールをブレッドボード用に取り付けるために、次のようにワイヤーを次のように半田付けしました。


そして、Raspberry Pi Pico and Pico W の情報源 を参考に、ブレッドボードで次のように配線しました。



左の配置において、
Picoの
左上から下に1〜20 ピンと並んでいます。
そして、
右下から上へ21〜40と並んでいます。

配線は次の通りです。
PicoW_RUN_30Pin−リセットスイッチ−PicoW_GND_28Pin

PicoW_GP14_19Pin−390Ω抵抗−LED−PicoW_GND_28Pin

LSM9DS1-I2C赤_1Pin−PicoW_3.3V_36Pin

LSM9DS1-I2C黒_2Pin−PicoW_GND_28Pin

LSM9DS1-I2C黄_3Pin−PicoW_0_SDA_21Pin

LSM9DS1-I2C緑_4Pin−PicoW_0_SCL_22Pin


この接続イメージで、磁気方位のX軸方向が↓で、Y軸方向が→です。
ジャイロ(角速度)センサーの回転軸で、X軸が↑で、Y軸が→です。
加速度センサーで、X軸方向が↑で、Y軸方向が→です。


以下はThonny環境でのMicroPythonのコードで、上記のように接続したI2Cデバイスのアドレスを列挙するプログラムです。
from machine import Pin, Ic2

IC2_SDA = 16 # GP16のジェネラル端子をSDA(Serial Data)に指定用変数
IC2_SCL = 17 # GP17のジェネラル端子をSCL(Serial Clock)に指定用変数
IC2_CH = 0 # IC2のチャンネル指定用変数

# SCL はスタンダードモードの100KHzの通信モードで、IC2を初期化
ic2=IC2( IC2_CH, scl=Pin(IC2_SCL), sda=IC2_SDA, freq=100000)

for addr in ic2.scan():
    print( f"{addr:x}" )
この実行結果を以下に示します。
1c
6a
モジュール内のJ1,J2が未接続の状態で、加速センサとジャイロセンサのペア 0x6A 、磁力センサはが0x1Cのアドレスで、 上記ではこれが見えています。
参考:クラス I2C -- 2線式シリアルプロトコル

AE-LSM9DS1-I2Cで磁気センサーの動作だけを確認

磁気センサーのデフォルトはパワーダウン状態で、 使う場合は CTRL_REG3_M (22h)のレジスタにMD[1:0] bitsを書き込む必要がある。
( 下位2ビットのデフォルトの0b11はPower-down mode)
ここをを0b01にすると、Single-conversion modeになる。
また、温度補正の出力を得るには、CTRL_REG1_M (20h)レジスタのTEMP_COMPビットを1にする。
レジスタは、CTRL_REG1_M〜CTRL_REG5_Mが制御レジスタが0x20〜0x24のアドレスで指定できる。
またOUT_X_L_M,OUT_X_H_M、OUT_Y_L_M,OUT_Y_H_M、OUT_Z_L_M,OUT_Z_H_Mで各レジスタでX軸、Y軸、Z軸 の下位と上位バイトを取得できます。
下記は、CTRL_REG1_M指定で、10Hzの周期で測定更新ごとに情報を表示させる検討用プログラムです。
from machine import Pin, I2C
import utime

I2C_SDA=16# GP16のジェネラル端子をSDA「Serial Data」に指定用変数
I2C_SCL=17# GP17のジェネラル端子をSCL「Serial Clock」に指定用変数
I2C_CH=0# I2Cのチャンネル指定用変数(Picoでは0と1のチャンネルがある)
I2C_M_ADDR=0x1C#磁力センサのアドレス

# 磁気センサー関連のレジスタ番号と設定値(lsm9ds1.pdf参照)
CTRL_REG1_M_N=0x20# レジスタ番号
CTRL_REG1_M=0b10010000# 温度補正 Low-power mode ODR(output data rate):10Hz デフォルト:00010000
CTRL_REG2_M_N=0x21
CTRL_REG2_M=0b00000000# Full scale:±4gauss デフォルト:00000000
CTRL_REG3_M_N=0x22
CTRL_REG3_M=0b00000000# I2Cのenable Continuous conversion mode デフォルト:00000011
CTRL_REG4_M_N=0x23
CTRL_REG4_M=0b00000000# Z-axis:low power, data LSb at lower address, デフォルト: 00000000
CTRL_REG5_M_N=0x24
CTRL_REG5_M=0b00000000# continuous update デフォルト: 00000000
STATUS_REG_M=0x27# 状態
OUT_X_L_M=0x28
OUT_X_H_M=0x29
OUT_Y_L_M=0x2A
OUT_Y_H_M=0x2B
OUT_Z_L_M=0x2C
OUT_Z_H_M=0x2D
OFFSET_X_REG_L_M=0x05

# SCL はスタンダードモードの100KHzの通信モードで、I2Cを初期化
i2c=I2C( I2C_CH, scl=Pin(I2C_SCL), sda=I2C_SDA, freq=100000)
for addr in i2c.scan(): print( f"enabled address:{addr:02x}" )

#磁力センサのアドレスを指定して、各レジスタを設定
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG1_M_N, bytes([CTRL_REG1_M]))
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG2_M_N, bytes([CTRL_REG2_M]))
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG3_M_N, bytes([CTRL_REG3_M]))
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG4_M_N, bytes([CTRL_REG4_M]))
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG5_M_N, bytes([CTRL_REG5_M]))

CTRL_REG3_M_N=0x22
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG3_M_N, bytes([0x0]))

while True:
    while True:
        statu=i2c.readfrom_mem( I2C_M_ADDR, STATUS_REG_M,1)
        #print(f"statu:{statu[0]:08b}", end=" ")
        if statu[0] & 0x80 : break # 更新があれば? 
    
    bxl=i2c.readfrom_mem( I2C_M_ADDR, OUT_X_L_M,1) # X軸
    bxh=i2c.readfrom_mem( I2C_M_ADDR, OUT_X_H_M,1)
    byl=i2c.readfrom_mem( I2C_M_ADDR, OUT_Y_L_M,1) # Y軸
    byh=i2c.readfrom_mem( I2C_M_ADDR, OUT_Y_H_M,1)
    bzl=i2c.readfrom_mem( I2C_M_ADDR, OUT_Z_L_M,1) # Z軸
    bzh=i2c.readfrom_mem( I2C_M_ADDR, OUT_Z_H_M,1)
    bin=[bxl[0],bxh[0], byl[0],byh[0], bzl[0],bzh[0]]
    print(bin)
    pass
    bin=i2c.readfrom_mem( I2C_M_ADDR, OUT_X_L_M, 6) #  X軸〜Z軸
    bin=[v for v in bin]
    print( bin )
    pass
    bin=i2c.readfrom_mem( I2C_M_ADDR, OFFSET_X_REG_L_M, 6)
    bin=[v for v in bin]
    print( bin )
上記の実行結果例を以下に示します。
[9, 5, 73, 6, 172, 244]
[9, 5, 73, 6, 172, 244]
[0, 0, 0, 0, 0, 0]
[235, 4, 108, 6, 121, 244]
[235, 4, 108, 6, 121, 244]
[0, 0, 0, 0, 0, 0]
[9, 5, 58, 6, 189, 244]
[9, 5, 58, 6, 189, 244]
[0, 0, 0, 0, 0, 0]
[231, 4, 95, 6, 207, 244]
[231, 4, 95, 6, 207, 244]
[0, 0, 0, 0, 0, 0]
[13, 5, 57, 6, 176, 244]
[13, 5, 57, 6, 176, 244]
[0, 0, 0, 0, 0, 0]
・・・以下省略
上記の  の部分は個々のレジスタを指定で情報を得ているのに対し、   は、アドレスとして先頭となるOUT_X_L_Mを指定し、そこから並ぶ6byteの情報を取得しています。
両者は同じ情報を得ており、 例えば[13, 5, 57, 6, 176, 244]であれば、
X軸の下位byteが13で上位byteが5、Y軸の下位byteが57で上位byteが6、Z軸の下位byteが176で上位byteが244 と並んでいます。

以上でアクセス方法が分かったので、磁気センサーのX軸,Y軸,Z軸の16byte情報を表示するコードは次のようになりました。

from machine import Pin, I2C
import utime

I2C_SDA=16# GP16のジェネラル端子をSDA「Serial Data」に指定用変数
I2C_SCL=17# GP17のジェネラル端子をSCL「Serial Clock」に指定用変数
I2C_CH=0# I2Cのチャンネル指定用変数(Picoでは0と1のチャンネルがある)
I2C_M_ADDR=0x1C#磁力センサのアドレス

# 磁気センサー関連のレジスタ番号と設定値(lsm9ds1.pdf参照)
CTRL_REG1_M_N=0x20# レジスタ番号
CTRL_REG1_M=0b10010000# 温度補正 Low-power mode ODR:10Hz デフォルト:00010000
CTRL_REG2_M_N=0x21
CTRL_REG2_M=0b00000000# Full scale:±4gauss デフォルト:00000000
CTRL_REG3_M_N=0x22
CTRL_REG3_M=0b00000000# I2Cのenable Continuous conversion mode デフォルト:00000011
CTRL_REG4_M_N=0x23
CTRL_REG4_M=0b00000000# Z-axis:low power, data LSb at lower address, デフォルト: 00000000
CTRL_REG5_M_N=0x24
CTRL_REG5_M=0b00000000# continuous update デフォルト: 00000000
STATUS_REG_M=0x27# 状態
OUT_X_L_M=0x28 # このアドレスより、OUT_X_H_M、OUT_Y_L_M、OUT_Y_H_M、OUT_Z_L_M、OUT_Z_H_Mレジスタが並ぶ
OFFSET_X_REG_L_M=0x05

# SCL はスタンダードモードの100KHzの通信モードで、I2Cを初期化
i2c=I2C( I2C_CH, scl=Pin(I2C_SCL), sda=I2C_SDA, freq=100000)
#for addr in i2c.scan(): print( f"enabled address:{addr:02x}" )

#磁力センサのアドレスを指定して、各制御レジスタを設定
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG1_M_N, bytes([CTRL_REG1_M]))
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG2_M_N, bytes([CTRL_REG2_M]))
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG3_M_N, bytes([CTRL_REG3_M]))
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG4_M_N, bytes([CTRL_REG4_M]))
i2c.writeto_mem( I2C_M_ADDR, CTRL_REG5_M_N, bytes([CTRL_REG5_M]))

import math

while True:
    while True: # データ更新を待つ
        statu=i2c.readfrom_mem( I2C_M_ADDR, STATUS_REG_M,1)
        #print(f"statu:{statu[0]:08b}", end=" ")
        if statu[0] & 0x80 : break
    
    bin=i2c.readfrom_mem( I2C_M_ADDR, OUT_X_L_M, 6) # X,Y,Z軸の磁気センサー情報取得
    #print( [v for v in bin] )
    magbin=[bin[n] + (bin[n+1]<<8) for n in range(0,len(bin),2)] # 2byteからuint16へ変換
    magbin=[v if v <= 32767 else v - 65536 for v in magbin] # uint16からint16へ変換
    deg = math.atan(magbin[1]/magbin[0]) * 360 / math.pi / 2 # 角度算出
    print( f"X:{magbin[0]:6}, Y:{magbin[1]:6}, Z:{magbin[2]:6} , deg={deg:5.2f}" )
    utime.sleep(0.5)
上記の実行例を以下に示しています。0.5秒ごとに計測結果(x,y,z,y/xのアークタンジェントの角度)を表示しています。
X:  2732, Y:  1768, Z:  -573 , deg=32.91
X:  2706, Y:  1786, Z:  -671 , deg=33.43
X:  2649, Y:  1797, Z:  -604 , deg=34.15
X:  2673, Y:  1821, Z:  -581 , deg=34.26
X:  2653, Y:  1817, Z:  -609 , deg=34.41
X:  2639, Y:  1858, Z:  -606 , deg=35.15
X:  2751, Y:  1741, Z:  -590 , deg=32.33
X:  2828, Y:  1721, Z:  -669 , deg=31.32
X:  2871, Y:  1596, Z:  -641 , deg=29.07
X:  3096, Y:   922, Z:  -747 , deg=16.58
X:  3110, Y:   631, Z:  -750 , deg=11.47
X:  2934, Y:   -15, Z:  -911 , deg=-0.29
X:  2232, Y:  -377, Z:  -945 , deg=-9.59
X:  1216, Y:  -598, Z:  -842 , deg=-26.19
X:   966, Y:  -494, Z:  -900 , deg=-27.08
X:   144, Y:    -7, Z:  -930 , deg=-2.78
X:   -13, Y:   202, Z:  -977 , deg=-86.32
X:  -255, Y:   557, Z:  -958 , deg=-65.40
X:  -299, Y:  1012, Z: -1080 , deg=-73.54
X:  -315, Y:  1517, Z: -1223 , deg=-78.27
X:  -329, Y:  2172, Z: -1348 , deg=-81.39
X:  -313, Y:  2270, Z: -1342 , deg=-82.15
X:  -263, Y:  2541, Z: -1356 , deg=-84.09
X:    70, Y:  3050, Z: -1245 , deg=88.69
X:   827, Y:  3621, Z: -1234 , deg=77.13
X:  1110, Y:  3754, Z: -1322 , deg=73.53
X:  1736, Y:  3585, Z: -1173 , deg=64.16
X:  2810, Y:  2619, Z:  -775 , deg=42.99
X:  2898, Y:  2156, Z:  -688 , deg=36.65
X:  2846, Y:  1817, Z:  -647 , deg=32.56
X:  2751, Y:  1583, Z:  -552 , deg=29.92
X:  2725, Y:  1583, Z:  -545 , deg=30.15
X:  2701, Y:  1607, Z:  -549 , deg=30.75
X:  2715, Y:  1585, Z:  -491 , deg=30.28
X:  2727, Y:  1555, Z:  -513 , deg=29.69
X:  2715, Y:  1561, Z:  -480 , deg=29.90
X:  2713, Y:  1625, Z:  -460 , deg=30.92
X:  2737, Y:  1569, Z:  -544 , deg=29.82
X:  2725, Y:  1569, Z:  -547 , deg=29.93
X:  2697, Y:  1569, Z:  -475 , deg=30.19
X:  2695, Y:  1517, Z:  -500 , deg=29.37
X:  2706, Y:  1535, Z:  -448 , deg=29.56

上記の実行中に、ブレッドボードを左へ1回転させています。それにより、角度が約30度→約0度→約-90度→約90度→約30度と変化しています。
実験の結果ですが、X軸が最大になる時、X軸が北を向いてしました。

AE-LSM9DS1-I2Cで加速度センサーとジャイロセンサーの動作を確認

ジャイロセンサーの動作チェック

まず、ジャイロセンサー(角速度センサー)の主要レジスタを次のように設定しています。
CTRL_REG1_G (10h) に測定周期(ODR:output data rate)を書き込むことで、ジャイロセンサー(角速度センサー)使用を設定する。
(帯域幅(BW:bandwidth)の設定も行う)
CTRL_REG2_G (11h) で、lsm9ds1.pdfのFigure 28.の block diagramにおけるINT_SELとOUT_SELを指定しているが、分からないのでデフォルト値を利用。
CTRL_REG3_G (12h) デフォルト値を利用(High-pass filter F disableなど)
OUT_TEMP_L (15h), OUT_TEMP_H (16h)で温度データも取得できるようであるが、利用していません。
STATUS_REG (17h) のレジスタで、ジャイロセンサーのGDAのビットが1であれば新しいデータがあると判断できる。
ジャイロセンサーのデータは、OUT_X_G (18h - 19h)、OUT_Y_G (1Ah - 1Bh)、OUT_Z_G (1Ch - 1Dh)の読み込み専用レジスタを使う。
以上を使って、ジャイロセンサー(角速度センサー)のX軸,Y軸,Z軸の16byte符号あり整数の情報を、表示し続けるコードで試してみました。
from machine import Pin, I2C
import utime

I2C_SDA=16# GP16のジェネラル端子をSDA「Serial Data」に指定用変数
I2C_SCL=17# GP17のジェネラル端子をSCL「Serial Clock」に指定用変数
I2C_CH=0# I2Cのチャンネル指定用変数(Picoでは0と1のチャンネルがある)
I2C_AG_ADDR=0x6a#加速センサとジャイロセンサのアドレス

# SCL はスタンダードモードの100KHzの通信モードで、I2Cを初期化
i2c=I2C( I2C_CH, scl=Pin(I2C_SCL), sda=I2C_SDA, freq=100000)
for addr in i2c.scan(): print( f"enabled address:{addr:02x}" )

# ジャイロのセンサー関連のレジスタ番号と設定値(lsm9ds1.pdf参照)
CTRL_REG1_G_N=0x10# レジスタ番号
CTRL_REG1_G=0b01000000# 角速度センサ制御レジスタ デフォルト:00000000
#CTRL_REG1_G[7〜5]のODR_G:010 測定周期59.5Hz
#CTRL_REG1_G[4〜3]のFS_G:00 Gyroscope full-scaleを245 dps
#CTRL_REG1_G[1〜0]のBW_G:00 帯域幅
CTRL_REG2_G_N=0x11
CTRL_REG2_G=0b00000000# デフォルト:00000000
CTRL_REG3_G_N=0x12
CTRL_REG3_G=0b00000000# デフォルト:00000000
STATUS_REG=0x17# 状態
OUT_X_G=0x18 # このアドレスより、OOUT_Y_G (1Ah - 1Bh)、OUT_Z_G (1Ch - 1Dh)のレジスタが並ぶ

#各ジャイロセンサレジスタを設定
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG1_G_N, bytes([CTRL_REG1_G]))
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG2_G_N, bytes([CTRL_REG2_G]))
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG3_G_N, bytes([CTRL_REG3_G]))

while True:
    while True:
        statu=i2c.readfrom_mem( I2C_AG_ADDR, STATUS_REG,1)
        #print(f"statu:{statu[0]:08b}", end=" ")
        if statu[0] & 0x02 : break
    
    bin=i2c.readfrom_mem( I2C_AG_ADDR, OUT_X_G, 6) # X,Y,Z軸のジャイロセンサー情報取得
    #print( [v for v in bin] )
    gyro=[bin[n] + (bin[n+1]<<8) for n in range(0,len(bin),2)]
    gyro=[v if v <= 32767 else v - 65536 for v in gyro]
    print( gyro )
    utime.sleep(0.5)

ぶら下げて、手で右矢印のように回転させた時実行結果例
よって、X軸の回転角度の速度がマイナスになっています。
体感的には、合っていると感じました。
[-677, 257, -286]
[102, -509, 269]
[157, -189, 5]
[104, -91, -33]
[-496, -97, -626]
[379, -83, 1084]
[-242, 54, 1022]
[-808, 521, 53]
[-150, 76, 2308]
[-567, 474, 437]
[29, -503, 295]
[1313, -2819, 308]
[-548, -147, -1036]
[-9442, 1418, -1416]
[-3083, -590, 433]
[-2627, -332, -2331]
[-13313, 3791, -3612]
[-5737, 607, -2932]
[-10359, 38, -576]
[-6350, 585, -1068]
[-8663, 1362, -592]
[-7645, 1386, -538]
[-11306, 1614, -819]
[-3794, 530, 404]
[-9136, 1420, -1063]
[-9563, 1262, -629]
[-4040, 2328, 157]
[1833, 400, 1146]
[3814, 6263, -3505]
[-1733, 4808, -1815]
[-325, -78, 12]
[-327, -75, 7]
[-337, -72, 13]
[-318, -77, 9]
[-321, -62, 12]
[-327, -64, 15]
[-309, -84, 12]
最後の方のデータは置いて固定した状態ですが、固定状態で
約[-325, -78, 12]の値になっています。

ジャイロのセンサーに対して、加速度センサーの取得動作も追加してチェックする

CTRL_REG1_Gがデフォルトの0x00である場合、ジャイロセンサーはパワーダウン状態となり、加速度センサーだけ使うモードになります。
その場合、加速度センサーの内部の測定周期(ODR:output data rate)をCTRL_REG6_XL (20h)のレジスタの[7〜5bit]で設定します。
ですが加速度計とジャイロスコープの複数の読み取りモードの場合、同じ測定周期になるようです。
以下は、前述のジャイロセンサー読み取りコードを追加、変更して作成しました。
なお、FIFO_CTRL (2Eh)レジスタで、FIFO の利用モード指定がありますが、デフォルトの未使用のままです。
from machine import Pin, I2C
import utime

I2C_SDA=16# GP16のジェネラル端子をSDA「Serial Data」に指定用変数
I2C_SCL=17# GP17のジェネラル端子をSCL「Serial Clock」に指定用変数
I2C_CH=0# I2Cのチャンネル指定用変数(Picoでは0と1のチャンネルがある)
I2C_AG_ADDR=0x6a#加速センサとジャイロセンサのアドレス

# SCL はスタンダードモードの100KHzの通信モードで、I2Cを初期化
i2c=I2C( I2C_CH, scl=Pin(I2C_SCL), sda=I2C_SDA, freq=100000)
for addr in i2c.scan(): print( f"enabled address:{addr:02x}" )

# ジャイロのセンサー関連のレジスタ番号と設定値(lsm9ds1.pdf参照)
CTRL_REG1_G_N=0x10# レジスタ番号
CTRL_REG1_G=0b01000000# 角速度センサ制御レジスタ デフォルト:00000000
#CTRL_REG1_G[7〜5bit]のODR_G:010 測定周期59.5Hz
#CTRL_REG1_G[4〜3bit]のFS_G:00 Gyroscope full-scaleを245 dps
#CTRL_REG1_G[1〜0bit]のBW_G:00 帯域幅
CTRL_REG2_G_N=0x11
CTRL_REG2_G=0b00000000# デフォルト:00000000
CTRL_REG3_G_N=0x12
CTRL_REG3_G=0b00000000# デフォルト:00000000
#CTRL_REG3_G でLow-power disabled、High-pass filter desable,Gyroscope high-pass filter cutoff frequency set
STATUS_REG=0x17# 状態
OUT_X_G=0x18 # このアドレスより、OOUT_Y_G (1Ah - 1Bh)、OUT_Z_G (1Ch - 1Dh)のレジスタが並ぶ
#各ジャイロセンサレジスタをを上記の通り設定
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG1_G_N, bytes([CTRL_REG1_G]))
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG2_G_N, bytes([CTRL_REG2_G]))
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG3_G_N, bytes([CTRL_REG3_G]))

# 加速度のセンサー関連のレジスタ番号と設定値
CTRL_REG4_N=0x1E
CTRL_REG4=0b00111000#0,0,Zen_G,Yen_G,Xen_G,0,LIR_XL1,4D_XL1 #デフォルト値:00111000
CTRL_REG5_N=0x1F
CTRL_REG5=0b00111000#0,0,Zen_G,Yen_G,Xen_G,0,LIR_XL1,4D_XL1 #デフォルト値:00111000
CTRL_REG6_XL_N=0x20
CTRL_REG6_XL=0b00000000#デフォルト値:00000000
#CTRL_REG6_XL[7〜5bit]はジャイロスコープ利用時無効?で、ジャイロスコープと同じ測定周期
#CTRL_REG6_XL[4〜3bit]はAccelerometer full-scale:±2g
#CTRL_REG6_XL[4〜3bit]
OUT_X_L_XL=0x28#OUT_X_H_XL,OUT_Y_L_XL,OUT_Y_H_XL,OUT_Z_L_XL,OUT_Z_H_XL
#各加速度のセンサーレジスタを上記の通り設定
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG4_N, bytes([CTRL_REG4]))
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG5_N, bytes([CTRL_REG5]))
i2c.writeto_mem( I2C_AG_ADDR, CTRL_REG6_XL_N, bytes([CTRL_REG6_XL]))

while True:
    statu=i2c.readfrom_mem( I2C_AG_ADDR, STATUS_REG,1)
    #print(f"statu:{statu[0]:08b}", end=" ")
    if statu[0] & 0x02 : # ジャイロセンサー情報あり?
        bin=i2c.readfrom_mem( I2C_AG_ADDR, OUT_X_G, 6) # X,Y,Z軸のジャイロセンサー情報取得
        #print( [v for v in bin] )
        gyro=[bin[n] + (bin[n+1]<<8) for n in range(0,len(bin),2)]
        gyro=[v if v <= 32767 else v - 65536 for v in gyro]
        print( f"gyroscope:{gyro}" )
    if statu[0] & 0x01: # 加速度情報情報あり?
        bin=i2c.readfrom_mem( I2C_AG_ADDR, OUT_X_L_XL, 6) # X,Y,Z軸の加速度情報取得
        #print( [v for v in bin] )
        accel=[bin[n] + (bin[n+1]<<8) for n in range(0,len(bin),2)]
        accel=[v if v <= 32767 else v - 65536 for v in accel]
        print( f"Accelerometer:{accel}" )
    utime.sleep(0.5)
上記の実行例で、ジャイロと加速度センサーの情報を交互に表示しています。
enabled address:1c
enabled address:6a
gyroscope:[-315, -79, 15]
Accelerometer:[-136, -415, 15919]
gyroscope:[-325, -70, 13]
Accelerometer:[-136, -404, 15916]
gyroscope:[-318, -84, 6]
Accelerometer:[-131, -404, 15914]
gyroscope:[-316, -72, 7]
Accelerometer:[-124, -418, 15918]
gyroscope:[-317, -66, 7]
Accelerometer:[-138, -404, 15907]
gyroscope:[-307, -76, 5]
Accelerometer:[-131, -412, 15912]
gyroscope:[-315, -68, 15]
Accelerometer:[-142, -414, 15919]
gyroscope:[-328, -76, 15]
Accelerometer:[-140, -437, 15898]
gyroscope:[-311, -78, 14]











センサーデバイスの覚書

ジャイロセンサー(角速度センサー)は、ある物体の角度が単位時間当たりどれだけ変化しているかを表す物理量です。
角速度の出力はdps(degree per second)で表します。
つまり、 1秒間に1回転している物体の場合、角速度は360dpsとなります。
そのセンシング種別の一つに静電容量方式を利用したMEMSジャイロセンサーがあります。
これは、コリオリ(フランスの数学者)の力を利用しています。
このコリオリの力とは、回転運動しているものを移動させると、その移動方向の直角方向に生じる慣性力の事で、転向力と呼ばれます。
転向力は、Fcoriolis=-2*m*Rad_per_sec*V の式で得られます。
(Fcoriolis:転向力ベクトル,  m:質量,  Rad_per_sec:角速度ベクトル, V:速度ベクトル)
この転向力は角速度と比例関係なので、転向力から逆算することで回転力を得る考え方です。