#ESP32でAmbientに接続しADXL345データを転送し表にした、その時のデータや流れを記録。
やっつけで一昼夜を通してESP32とADXL345(三軸加速度センサー)を使いシリアルモニターとAmbientにデータ転送を成功させた。
時間にして約15時間程度(途中うたたねや食事ももちろんとった、でもかかりすぎ?)をかけやっと形になった。
多分忘れると思うので備忘録として残します。
##結線
至って簡単だが、Arduino uno や Arduino nano と何ら変わらないが、中華モノだったか知らないが、ピンが曲がってブレッドボードにうまく刺さらなかった。無理やり付けた。
ESP32自体には何も難しいことはないが、やりなれないプログラミングにはなかなか骨が折れた。
##プログラミング(Aruduino IDE)
いろんなところからの寄せ集めのような全体ですが、とりあえず私は動いた。
#include <Wire.h>
#include <Ambient.h>
//アドレス指定
#define ADXL345_ADDR 0x53
#define DATA_FORMAT 0x31
#define POWER_CTL 0x2D
#define DATAX0 0x32
#define FULL_RES_16G 0x0B
#define BIT10_16G 0x03
#define MEASURE 0x08
WiFiClient client;
Ambient ambient; // Ambientオブジェクトを定義
//ESP32におけるADXL345加速度センサ使用てすと
const char* ssid = "74D21DBC979A-2G";
const char* password = "55351101652577";
unsigned int channelId = 37697; // AmbientのチャネルID
const char* writeKey = "3d1a0875f4a46513"; // ライトキー
void setup() {
Wire.begin();//I2Cを初期化
Serial.begin(115200);//シリアル通信を115200bpsで初期化
delay(100);
WiFi.begin(ssid, password); // Wi-Fi APに接続
while (WiFi.status() != WL_CONNECTED) { // Wi-Fi AP接続待ち
delay(100);
}
Serial.print("WiFi connected\r\nIP address: ");
Serial.println(WiFi.localIP());
pinMode(21, INPUT_PULLUP); //デファルトのSDAピン21 のプルアップの指定
pinMode(22, INPUT_PULLUP); //デファルトのSDAピン22 のプルアップの指定
ambient.begin(channelId, writeKey, &client); // チャネルIDとライトキーを指定してAmbientの初期化
Wire.beginTransmission(ADXL345_ADDR);//I2Cスレーブのデータ送信開始
Wire.write(DATA_FORMAT);//データ・フォーマット・コントロール
Wire.write(FULL_RES_16G);//「最大分解能モード」、「±16g」
//Wire.write(BIT10_16G);//「10bit固定分解能モード」、「±16g」
Wire.endTransmission();//I2Cスレーブのデータ送信終了
Wire.beginTransmission(ADXL345_ADDR);//I2Cスレーブのデータ送信開始
Wire.write(POWER_CTL);//省電力機能コントロール
Wire.write(MEASURE);//測定モード
Wire.endTransmission();//I2Cスレーブのデータ送信終了
}
void loop() {
unsigned int dac[6];
unsigned int i, x, y, z;
float X_Axis, Y_Axis, Z_Axis, XYZ_Axis;
Wire.beginTransmission(ADXL345_ADDR);//I2Cスレーブのデータ送信開始
Wire.write(DATAX0);//出力データバイトを「X軸データ0」のアドレスに指定
Wire.endTransmission();//I2Cスレーブのデータ送信終了
Wire.requestFrom(ADXL345_ADDR, 6);//I2Cデバイス「ADXL345」に6Byteのデータ要求
for (i=0; i<6; i++){
while (Wire.available() == 0 ){}
dac[i] = Wire.read();//dacにI2Cデバイス「ADXL345」のデータ読み込み
}
x = (dac[1] << 8) | dac[0];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
X_Axis = float(x) * 0.0392266;//加速度の計算、X_Axisに代入 ※0.0392266=(4/1000*9.80665)
y = (dac[3] << 8) | dac[2];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
Y_Axis = float(y) * 0.0392266;//加速度の計算、Y_Axisに代入
z = (dac[5] << 8) | dac[4];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
Z_Axis = float(z) * 0.0392266;//加速度の計算、Z_Axisに代入
XYZ_Axis = (X_Axis + Y_Axis + Z_Axis) / 3;
Serial.print("X-Axis ");//文字列「X.」をシリアルモニタに送信
Serial.print(X_Axis);//「X_Axis」をシリアルモニタに送信
Serial.print(" m/s^2 ");//文字列「m/s^2」をシリアルモニタに送信
Serial.print("Y-Axis ");//文字列「Y.」をシリアルモニタに送信
Serial.print(Y_Axis);//「Y_Axis」をシリアルモニタに送信
Serial.print(" m/s^2 ");//文字列「m/s^2」をシリアルモニタに送信
Serial.print("Z-Axis ");//文字列「Z.」をシリアルモニタに送信
Serial.print(Z_Axis);//「Z_Axis」をシリアルモニタに送信
Serial.print(" m/s^2");//文字列「m/s^2」をシリアルモニタに送信、改行
Serial.println(XYZ_Axis);//「Z_Axis」をシリアルモニタに送信
ambient.set(1,X_Axis);
ambient.set(2,Y_Axis);
ambient.set(3,Z_Axis);
ambient.send();
delay(1000);//1000msec待機(1秒待機)
}
Ambientに送信するにあたって注意する箇所は WiFi ssid と WiFi password と Ambient チャンネルID ライトキーを間違えないこと。それで間違え探しを30分ほどしてしまった。また変数の宣言も忘れずに。
他のコードはIDEにかけるとエラーが出るので何とかなるが、ルーターssid、パスワードやAmbientのIDやキーを間違っていたら、シリアルモニターには生データが次々表示されるので間違えに気づきにくい。
シリアルモニターでの出力はこんな感じ。
#Ambientについて
実際Ambientにデータを送信したら下記のようなグラフが現れた
またCSVデータもダウンロードできた。
だがデータ作成の時間が理解しずらいのでグーグル先生に聞いたところ
表示されている時間は ISO8601 という形式で表示されているとのことで変換が必要らしい。
探し当てた答えは =DATAVALUE(MIDB(B2,1,10))+TIMEVALUE(MIDB(B2,12,10))+TIME(9,0,0)を別セルで計算すれば正しい表示がされるとのこと。また表示形式→ユーザー定義→yyyy/m/d h:mm:ssに設定すれば普通の表示に変換される。ただし、ミリ秒までは表示されないので別途 yyyy/m/d h:mm:ss.000 にすればミリ秒まで表示されるが小数点1位までのようだ。まあそこまで表示してくれれば何とか使えるかと思います。
#最後に
センサーとマイコンでデータを取り、Ambientにデータを送りややリアルタイム(少しのタイムラグはある)で誰でもグラフプロットができる時代が来ていたことに驚きを隠せない。
最小限の構成で、しかも安価に、こんなに早く計測デバイスと記録デバイス、グラフプロットができるとは・・・
更にアイデアが浮かんだので更に進化させていきたいと思います。近い将来誰でもどこでもIoTが身近になることは間違いないです。