0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Qiita全国学生対抗戦Advent Calendar 2024

Day 6

加速度センサー ADXL345を3200 Hzで動かしてみた

Last updated at Posted at 2024-12-25

私はCanSatという一種の自律制御ロボットの開発を行っているのですが、ロケットからの分離衝撃、地面への着地衝撃を測定する必要がありました。一般に着地した際には非常に短い時間の間に速度、加速度が変化するのでセンサーの動作周期を短くする必要があります。

マイコンとセンサー間の通信インターフェースにはI2C, SPI, UART等がありますが、今回はその中でも高速にデータの通信を行うことが出来るSPI通信を使って3軸加速度センサーを動かしてみたのでその方法を紹介します。

目次

開発環境

  • SBC: Raspberry pi zero w
  • 加速度センサー: ADXL345 (秋月電子)
  • OS: Debian GNU/Linux 12 (bookworm)

配線

3軸加速度センサー ADXL345は上の画像のようなピン配置をしているので下の表のようにRaspberry piと接続します

Raspberry pi pin ADXL345
1 pin 3V3 VDD
6 pin GND GND
21 pin MISO SDO
19 pin MOSI SDA(SDI)
23 pin SCLK SCL
24 pin CE0# CS

SPIを使うための設定

Raspberry PiのSPIはデフォルトでは無効になっているので、設定を変更して有効にします
以下のコマンドを使用してラズパイの設定を変更します

raspi-config

Interfacing Options -> SPI -> Yes を選択してSPIを有効化します
設定できたら、左右矢印でFinishを選択して、エンターキーを押して、raspi-configを終わります

SPI通信用ライブラリのインストール

ラズパイのpythonでSPI通信を行うにはpi-spidevライブラリを使用します
pipコマンドでインストールします

$ pip3 install spidev

コード

ADXL345をPython 3で動かすためのコードを以下に示します

spi_3200hz_adxl345.py
import spidev
import time
import datetime
import codecs
import math

#初期設定
spi = spidev.SpiDev()
spi.open(0,0)
spi.mode = 3  #このデバイスはSPI mode3で動作
spi.max_speed_hz = 1000000

spi.xfer2([0x2C, 0x0F]) # output data rate 3200 Hz
spi.xfer2([0x31, 0x09])
spi.xfer2([0x2D, 0x08]) #測定スタート

def hosuu_to_normal(num):
    if num > 32768:
        num -= 65536
    return num

def avg_offset_list(offset_list):
    res = 0
    for offset_list_ele in offset_list:
        res += offset_list_ele
    return res/len(offset_list)

offset_count = 10
offset_x = []
offset_y = []
offset_z = []

fmt_name = "record/acc_logs_ADXL_test_4g_{0:%Y%m%d-%H%M%S}.csv".format(datetime.datetime.now())
f_acc_logs = codecs.open(fmt_name, mode='w', encoding="utf-8")

header_value = u"yyyy-mm-dd hh:mm:ss.mmmmmm,x[g],y[g],z[g],norm[g]"
f_acc_logs.write(header_value+"\n")

max_value = 0

try:
    while True:
        #x,y,z方向の加速度を取得(2の補数表現)
        x_data_list = spi.xfer2([0xc0|0x32, 0x00, 0x00])
        y_data_list = spi.xfer2([0xc0|0x34, 0x00, 0x00])
        z_data_list = spi.xfer2([0xc0|0x36, 0x00, 0x00])
        x_data = x_data_list[1] | (x_data_list[2] << 8)
        y_data = y_data_list[1] | (y_data_list[2] << 8)
        z_data = z_data_list[1] | (z_data_list[2] << 8)
        #2の補数を10進に変換
        x_data = hosuu_to_normal(x_data)
        y_data = hosuu_to_normal(y_data)
        z_data = hosuu_to_normal(z_data)
        #加速度に変換(Dレンジ ±4g)
        x_data = x_data * 4 / 0x3FF
        y_data = y_data * 4 / 0x3FF
        z_data = z_data * 4 / 0x3FF

        if offset_count >= 0 :
            offset_count -= 1
            offset_x.append(x_data)
            offset_y.append(y_data)
            offset_z.append(z_data-(+1)) # z軸方向に重力があるように
            continue

        x_data -= avg_offset_list(offset_x)
        y_data -= avg_offset_list(offset_y)
        z_data -= avg_offset_list(offset_z)

        # write log file
        now = datetime.datetime.now()
        f_acc_logs.write(f'{now},{x_data},{y_data},{z_data},{math.sqrt(x_data**2+y_data**2+z_data**2)}\n')
        if math.sqrt(x_data**2+y_data**2+z_data**2) > max_value:
            max_value = math.sqrt(x_data**2+y_data**2+z_data**2)
            print(max_value)
        # print('x: {:4.2f}, y: {:4.2f}, z: {:4.2f} [G]'.format(x_data, y_data, z_data))
        # time.sleep(0.1)

except KeyboardInterrupt:
    print('!FINISH!')
    f_acc_logs.close()

データシートによると、センサーの出力レートを3200 Hz にするためにはレジスタ0x2Cに0x0Fを設定する必要があります。
コードの13行目

spi.xfer2([0x2C, 0x0F]) # output data rate 3200 Hz

の部分でこの設定を行っています。

参考サイト

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?