加速度センサ(ADXL343)を Raspberry Pi 4 で使う
Analog Devices の3軸加速度センサ ADXL343 を £5 ぐらいで購入できましたので Raspberry Pi 4 で動かしてみました。 9pinの足を全部はんだ付けしてブレッドボード上に実装しています。ちなみにはんだ付けする前の写真はこちらです。あんまり上手じゃないですけど、とりあえず繋がりさえすればOKです。
I2Cでの接続になります。ADXL343 上の VIN を Pi 4 の 3v3 へ接続、GND,SDA,SCL はそれぞれ同名のクチにジャンパ線で接続しています。
正しく接続できたか i2cdetect で確認します。 先日遊んでいた BME680 も接続していますのでアドレスは 0x53 と 0x76 の両方が見えていますが ADXL343 は 0x53 の方です。
pi@raspberrypi:~/rpiLogger $ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- 53 -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 --
今回、I2Cの Read/Write には pigpio というライブラリを使っています。 abyz.me.uk
pigpioで読み出した x, y, z の3軸データをビジーループの中でCSVファイルに吐き出すようにしてみました。 CSVの左列にはunixtimeとマイクロ秒を並べて時系列データのようにしています。 時系列のピッチが不揃いなのはご容赦ください。ビジーループで雑に吐き出しただけですので。
書いたソースを全文貼っておきます。雑なC言語ですみません。もし同じようなことをする人がおられましたら、
$ gcc -Wall -pthread file.c -lpigpio -lrt
pigpio のインストール後、このようにコンパイルして実行ファイルが作れます。
ちなみにこのpigpioで i2cOpen() するときにアドレスを 0x53 ではなく間違った値を入れてしまっても正常リターンが返されます。 その後読み書きのAPIが PI_I2C_READ_FAILED や PI_I2C_WRITE_FAILED で失敗する振る舞いになりました。Openの時点でエラーになってくれれば分かりやすいのに、かるくハマりました。。
ソースはこちら
#include <stdio.h> #include "pigpio.h" #define ADXL343_I2C_ADDR_PRIMARY 0x53 #define ADXL343_BW_RATE 0x2C #define ADXL343_DATA_FORMAT 0x31 #define ADXL343_FIFO_CTL 0x38 #define ADXL343_POWER_CTL 0x2D #define ADXL343_DATAX0 0x32 #define ADXL343_DATAY0 0x34 #define ADXL343_DATAZ0 0x36 static int handle; static FILE *fp; void initSensor() { /* BW_RATE : 0x0f = 1600Hz */ i2cWriteByteData(handle, ADXL343_BW_RATE, 0x0f ); i2cWriteByteData(handle, ADXL343_DATA_FORMAT, 0x00 ); i2cWriteByteData(handle, ADXL343_FIFO_CTL, 0x00 ); i2cWriteByteData(handle, ADXL343_POWER_CTL, 0x08 ); } void writeCSV(int x_dat, int y_dat, int z_dat ) { int seconds,micros; gpioTime(1, &seconds, µs ); fprintf(fp, "%d %6d: x:y:z ,%6d,%6d,%6d\n",seconds,micros,x_dat,y_dat,z_dat ); } void readSensor() { int x_dat, y_dat, z_dat; while(1) { x_dat = i2cReadWordData(handle, ADXL343_DATAX0); y_dat = i2cReadWordData(handle, ADXL343_DATAY0); z_dat = i2cReadWordData(handle, ADXL343_DATAZ0); writeCSV( x_dat, y_dat, z_dat ); } } int main(int argc, char *argv[]) { if (gpioInitialise() < 0) return 1; handle = i2cOpen(1, ADXL343_I2C_ADDR_PRIMARY, 0); fp = fopen("save.csv","w"); initSensor(); readSensor(); fclose(fp); i2cClose(handle); gpioTerminate(); }
実行してみたところ、CSVファイルは3軸それぞれの値が2バイトデータで出力されます。 時間出力の読み方ですが、左列の1563603955のような10桁数字が1970年1月1日からの秒で、その横の6桁数字がマイクロ秒です。このマイクロ秒部分を読み取ると、サンプルごとの時間間隔はおおむね1500マイクロ秒(1.5ミリ秒)ぐらいになっている模様です。
1563603955 512977: x:y:z , 12, 62, 228 1563603955 514534: x:y:z , 18, 74, 238 1563603955 516064: x:y:z , 16, 58, 238 1563603955 517594: x:y:z , 12, 56, 242 1563603955 519121: x:y:z , 16, 58, 242 1563603955 520650: x:y:z , 20, 58, 236 1563603955 522177: x:y:z , 26, 64, 236 1563603955 523705: x:y:z , 22, 66, 240 1563603955 525233: x:y:z , 24, 62, 232 1563603955 526762: x:y:z , 20, 62, 232 1563603955 528290: x:y:z , 20, 68, 230 1563603955 529817: x:y:z , 22, 66, 230 1563603955 531345: x:y:z , 16, 64, 232 1563603955 532873: x:y:z , 10, 74, 224 1563603955 534401: x:y:z , 16, 70, 228 1563603955 535929: x:y:z , 8, 60, 232 1563603955 537458: x:y:z , 14, 64, 224 1563603955 538985: x:y:z , 12, 64, 224
すこし気に入らなかったので I2C の速度をデフォルトの 100KHz から 400KHzに変更してみました。 /boot/config.txt に
dtparam=i2c_baudrate=400000
と書いて再起動します。
この状態で実行してみたところ、時間間隔は約0.8ミリ秒ぐらいに縮まりました。1.0KHzサンプリングの時系列データを作るぐらいならぎりぎりなんとかなりそうな性能ですね。このあともう少し試行錯誤していると0.4ミリ秒ピッチぐらいで動けるようになってきました。安定した定周期で時系列データを取れるようにしていきたいと思います。
1563605344 553451: x:y:z , 65472, 65520, 240 1563605344 554291: x:y:z , 65478, 65528, 230 1563605344 555131: x:y:z , 65476, 65518, 220 1563605344 555972: x:y:z , 65478, 65530, 222 1563605344 556814: x:y:z , 65482, 65524, 236 1563605344 557654: x:y:z , 65480, 65530, 234 1563605344 558499: x:y:z , 65502, 65528, 240 1563605344 559340: x:y:z , 65492, 65530, 224 1563605344 560180: x:y:z , 65480, 65524, 232 1563605344 561021: x:y:z , 65480, 65524, 232 1563605344 561861: x:y:z , 65452, 65526, 234 1563605344 562702: x:y:z , 65486, 65524, 238 1563605344 563543: x:y:z , 65486, 65532, 214 1563605344 564384: x:y:z , 65476, 65526, 200 1563605344 565225: x:y:z , 65482, 65524, 224