LoginSignup
1
0

ESP32でMicroPythonを用いて,KXM52-1050(加速度センサ),L3GD20H(ジャイロセンサ)を利用する.

Last updated at Posted at 2024-01-10

はじめに

 ESP32でMicroPythonを利用して加速度と角速度を得るために,加速度センサ(KXM52-1050),ジャイロセンサ(L3GD20H)を利用します.
プログラムエディタはThonnyを利用しました.
 ESP32でMicroPythonが使用できる前提で話を進めていきます.
 以下のモジュールをインポートしています.

from machine import ADC, PWM, Pin, I2C
import time

Thoonyで開くことを前提にしており,Ctrl + Cでデータの取得を終了するようにしています.

加速度センサ(KXM52-1050)

ESP32とKXM52-1050の接続方法

KXM52-1050のピン
1 ... ESP32の3.3V電源,KXM52-1050の2PIN
2 ... KXM52-1050の1PIN
3 ... ESP32のGND,KXM52-1050の4PIN
4 ... KXM52-1050の4PIN
5 ... なし
6 ... ESP32の34PIN
7 ... ESP32の39PIN
8 ... ESP32の36PIN

加速度センサ.png

加速度センサのプログラム

データを受け取る

#3軸それぞれの加速度データ受け取り
z = ADC(Pin(36, Pin.IN), atten=ADC.ATTN_11DB)
y = ADC(Pin(39, Pin.IN), atten=ADC.ATTN_11DB)
x = ADC(Pin(34, Pin.IN), atten=ADC.ATTN_11DB)

# 0-65535の範囲の整数を返す
x_v = x.read_u16()
y_v = y.read_u16()
z_v = z.read_u16()

センサのデータを[$m/s^2$]に変換する変数

def kasoku(v):
    V = v * (3.55 / 65535)
    ag = (V - 1.65) / 660 * 1000
    a = ag * 9.8
    return a

加速度センサ全体のプログラム

def kasoku(v):
    V = v * (3.55 / 65535)
    ag = (V - 1.65) / 660 * 1000
    a = ag * 9.8
    return a

 #3軸それぞれの加速度データ受け取り
z = ADC(Pin(36, Pin.IN), atten=ADC.ATTN_11DB)
y = ADC(Pin(39, Pin.IN), atten=ADC.ATTN_11DB)
x = ADC(Pin(34, Pin.IN), atten=ADC.ATTN_11DB)

# 0-65535の範囲の整数を返す
x_v = x.read_u16()
y_v = y.read_u16()
z_v = z.read_u16()
nowtime = time.ticks_ms() - first_time
        
# センサデータを加速度[m/s^2]へ変換する
x_val = kasoku(x_v)
y_val = kasoku(y_v)
z_val = kasoku(z_v)

ジャイロセンサ(L3GD20H)

ESP32とL3GD20Hの接続方法

1 ... ESP32の3.3V電源および,10k抵抗を利用してL3GD20Hの5PIN
2 ... ESP32の22PIN
3 ... ESP32の21PIN
4 ... L3GD20Hの8PIN
5 ... 10k抵抗を利用してL3GD20Hの1PIN
6 ... なし
7 ... なし
8 ... ESP32のGDNおよび,L3GD20Hの4PIN

ジャイロセンサ.png

ジャイロセンサのプログラム

データを受け取るための設定

# データを取得するESP-32のピンを設定する
p21 = Pin(21, Pin.IN, Pin.PULL_UP)
p22 = Pin(22, Pin.IN, Pin.PULL_UP)

# I2C通信を行うピンの設定を行う
i2c = I2C(scl=Pin(22), sda=Pin(21))  # sclピンとsdaピンを使用

# デバイスのI2Cアドレス
device_address = 0x6A  # 書き込み先アドレスを指定する変数

# データを書き込む
data_to_write = b'\x0F'  # 書き込むデータをバイト列で指定
i2c.writeto_mem(device_address, 0x20, data_to_write)
data_to_write = b'\x20'
i2c.writeto_mem(device_address, 0x23, data_to_write)

# 読み込み先アドレスを格納する変数
ANGULAR_VELOCITY_REG = 0x28

データを受け取り,値を[$deg/s$]に変換する

#角速度データ受け取り
xl = i2c.readfrom_mem(device_address, 0x28, 1)
xh = i2c.readfrom_mem(device_address, 0x29, 1)
yl = i2c.readfrom_mem(device_address, 0x2A, 1)
yh = i2c.readfrom_mem(device_address, 0x2B, 1)
zl = i2c.readfrom_mem(device_address, 0x2C, 1)
zh = i2c.readfrom_mem(device_address, 0x2D, 1)
        
# センサデータを、合成する
wx = xh[0] << 8 | xl[0]
wy = yh[0] << 8 | yl[0]
wz = zh[0] << 8 | zl[0]
        
if wx >= 32768:
    wx = wx - 65536
if wy >= 32768:
    wy = wy - 65536
if wz >= 32768:
    wz = wz - 65536
        
angular_velocity_x = wx * 0.07
angular_velocity_y = wy * 0.07
angular_velocity_z = wz * 0.07

ジャイロセンサ全体のプログラム

# データを取得するESP-32のピンを設定する
p21 = Pin(21, Pin.IN, Pin.PULL_UP)
p22 = Pin(22, Pin.IN, Pin.PULL_UP)

# I2C通信を行うピンの設定を行う
i2c = I2C(scl=Pin(22), sda=Pin(21))  # sclピンとsdaピンを使用

# デバイスのI2Cアドレス
device_address = 0x6A  # 書き込み先アドレスを指定する変数

# データを書き込む
data_to_write = b'\x0F'  # 書き込むデータをバイト列で指定
i2c.writeto_mem(device_address, 0x20, data_to_write)
data_to_write = b'\x20'
i2c.writeto_mem(device_address, 0x23, data_to_write)

# 読み込み先アドレスを格納する変数
ANGULAR_VELOCITY_REG = 0x28

#角速度データ受け取り
xl = i2c.readfrom_mem(device_address, 0x28, 1)
xh = i2c.readfrom_mem(device_address, 0x29, 1)
yl = i2c.readfrom_mem(device_address, 0x2A, 1)
yh = i2c.readfrom_mem(device_address, 0x2B, 1)
zl = i2c.readfrom_mem(device_address, 0x2C, 1)
zh = i2c.readfrom_mem(device_address, 0x2D, 1)
        
# センサデータを、合成する
wx = xh[0] << 8 | xl[0]
wy = yh[0] << 8 | yl[0]
wz = zh[0] << 8 | zl[0]
        
if wx >= 32768:
    wx = wx - 65536
if wy >= 32768:
    wy = wy - 65536
if wz >= 32768:
    wz = wz - 65536
        
angular_velocity_x = wx * 0.07
angular_velocity_y = wy * 0.07
angular_velocity_z = wz * 0.07

実装

取得時間を計測するために,データを取得し始める前に開始時間を持つ変数を作成します.

#開始時間を取得する
first_time = time.ticks_ms()

#経過時間の計算
nowtime = time.ticks_ms() - first_time

データをテキストファイルとして保存するために,ファイルに書き込みを行えるようにし,データの取得終了時にファイルを閉ます.

# 取得データの書き込み先のファイルを開く
f = open('data_test.txt', 'w')

#ファイルを閉じる
f.close()

加速度センサおよび,角速度センサを取得し続けるためのプログラム全体

# 必要なモジュールをインポートする
from machine import ADC, PWM, Pin, I2C
import time

# センサから取得したデータを加速度[m/s^2]に変換する
def kasoku(v):
    V = v * (3.55 / 65535)
    ag = (V - 1.65) / 660 * 1000
    a = ag * 9.8
    return a

###################################################################
#角速度変数

# データを取得するESP-32のピンを設定する
p21 = Pin(21, Pin.IN, Pin.PULL_UP)
p22 = Pin(22, Pin.IN, Pin.PULL_UP)

# I2C通信を行うピンの設定を行う
i2c = I2C(scl=Pin(22), sda=Pin(21))  # sclピンとsdaピンを使用

# デバイスのI2Cアドレス
device_address = 0x6A  # 書き込み先アドレスを指定する変数

# データを書き込む
data_to_write = b'\x0F'  # 書き込むデータをバイト列で指定
i2c.writeto_mem(device_address, 0x20, data_to_write)
data_to_write = b'\x20'
i2c.writeto_mem(device_address, 0x23, data_to_write)

# 読み込み先アドレスを格納する変数
ANGULAR_VELOCITY_REG = 0x28

####################################################################

# 経過時間を調べるためにデータ取得開始時間を取得する
first_time = time.ticks_ms()

# 取得データの書き込み先のファイルを開く
f = open('data_test.txt', 'w')

# Ctrl + Cで停止させた後に、ファイルに書き込むためにtry文でwhileを回す
try:
    while True:
        #########################################################################################
        #3軸それぞれの加速度データ受け取り
        z = ADC(Pin(36, Pin.IN), atten=ADC.ATTN_11DB)
        y = ADC(Pin(39, Pin.IN), atten=ADC.ATTN_11DB)
        x = ADC(Pin(34, Pin.IN), atten=ADC.ATTN_11DB)

        # 0-65535の範囲の整数を返す
        x_v = x.read_u16()
        y_v = y.read_u16()
        z_v = z.read_u16()
        
        # センサデータを加速度[m/s^2]へ変換する
        x_val = kasoku(x_v)
        y_val = kasoku(y_v)
        z_val = kasoku(z_v)
        #########################################################################################
        #角速度データ受け取り
        xl = i2c.readfrom_mem(device_address, 0x28, 1)
        xh = i2c.readfrom_mem(device_address, 0x29, 1)
        yl = i2c.readfrom_mem(device_address, 0x2A, 1)
        yh = i2c.readfrom_mem(device_address, 0x2B, 1)
        zl = i2c.readfrom_mem(device_address, 0x2C, 1)
        zh = i2c.readfrom_mem(device_address, 0x2D, 1)
        
        # センサデータを、合成する
        wx = xh[0] << 8 | xl[0]
        wy = yh[0] << 8 | yl[0]
        wz = zh[0] << 8 | zl[0]
        
        if wx >= 32768:
            wx = wx - 65536
        if wy >= 32768:
            wy = wy - 65536
        if wz >= 32768:
            wz = wz - 65536
        
        angular_velocity_x = wx * 0.07
        angular_velocity_y = wy * 0.07
        angular_velocity_z = wz * 0.07
        #########################################################################################
        #経過時間の計算
        nowtime = time.ticks_ms() - first_time
        
        #ファイルへの書き込み
        f.write(str(nowtime) + ", " + str(x_val) + ", " + str(y_val) + ", " + str(z_val) + ", " + str(angular_velocity_x) + ", " + str(angular_velocity_y) + ", " + str(angular_velocity_z) + "\n")
        #シェルへの書き込み
        print(str(nowtime) + ", X: " + str(x_val) + ", Y: " + str(y_val) + ", Z:" + str(z_val) + ", WX:" + str(angular_velocity_x) + ", WY" + str(angular_velocity_y) +  ", WZ" + str(angular_velocity_z))
        
        time.sleep(0.03)
finally:
    f.close()

取得したデータ

傾けずに地面に置いた場合
zkita.png
Z軸の加速度が約9[$m/s^2$]になっており,重力加速度がかかっていることが分かります.

y_kita.png

xkita.png

同様に横,縦に傾けた結果,Y軸,X軸の値が約10[$m/s^2$]になっており,重力加速度を測定できていることが分かります.

参考にしたサイト

概要 — MicroPython latest ドキュメント : https://micropython-docs-ja.readthedocs.io/ja/latest/index.html
加速度センサ - garretlab - FC2 : https://garretlab.web.fc2.com/arduino/lab/acceleration_sensor/
3軸ジャイロセンサーL3GD20Hの使い方(I2C通信/SPI通信) | 初心者のためのセンサーと測定入門 : https://s-design-tokyo.com/use_l3gd20h_i2c/

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0