1msec周期でセンシングした値をArduinoからPCへシリアル通信で送ってみた
やりたいこと
Arduinoでセンサーの値をanalogReadで読み取り、読み取った値をPCへシリアル通信で転送するということをやります。
それを1msec周期で、複数チャンネルの値を取得するために、はじめは以下のようにしました。
Arduinoとシリアル通信について
Arduino
Arduinoはオープンソースハードウェアで電子工作や電子回路のプロトタイピングや教育目的で世界中で使用されています。
日本国内でもいくつか本が出ていて、一冊手にとってブレッドボードやLEDなどのパーツと一緒に何か作ってみると楽しいと思います。この本はサンプルも豊富でわかりやすかったです。おすすめです。
今回は自作したセンサーの値をanalodReadという関数で読み取って、それをPCに送るために工夫したことを書きました。
シリアル通信
Arduinoのようなマイコンボードから別のパソコンのような機器データを送る方法は幾つかあります。
サンプルコード
code:sample-1.ino
void emgRead() {
interrupts();
long milltime = millis();
int value1 = analogRead(0);
int value2 = analogRead(1);
int value3 = analogRead(2);
Serial.print(time);
Serial.print(",");
Serial.print(value * 3.3 / 1023.0);
Serial.print(",");
Serial.print(value2 * 3.3 / 1023.0);
Serial.print(",");
Serial.println(value3 * 3.3 / 1023.0);
}
void setup() {
analogReference(EXTERNAL);
Serial.begin(115200);
MsTimer2::set(1, emgRead); // 1ms間隔で実行
MsTimer2::start();
}
void loop() {
}
MsTimer2で1msec周期でemgRead()を実行します。1msec周期でセンシングしたデータは送れません。
2msec以上はかかっていました。シリアル通信の処理で1msec以上かかっています。
ボーレートは115200 bpsで設定しました。1 bytes = 8bit、14400 bytes / 1s、14.4 bytes / 0.001secという計算で、理論上は1msecで14.4bytes送れることになります。
sample-1のプログラムだと 2699,1.43,1.43,1.43のように 21bytesになるため、シリアル通信で1msecでデータを送ることができません。
そこで、以下のように変更しました。
HEX(16進数)を使うことで、データのサイズを小さくして送信しました。
code:sample.ino
void emgRead() {
interrupts();
long milltime = millis();
int value1 = analogRead(0);
int value2 = analogRead(1);
int value3 = analogRead(2);
// value1~3 は 0~1023
// valueはProcesing側で 3.3 をかけて、1023.0で割ることで 0~3.3V に変換します
sprintf(buf, "%04x%03x%03x%03x", milltime, value1, value2, value3);
Serial.println(buf);
}
void setup() {
analogReference(EXTERNAL);
Serial.begin(115200);
MsTimer2::set(1, emgRead); // 1ms間隔で実行
MsTimer2::start();
}
void loop() {
}
Processing側のシリアル通信で受け取るコードも載せておきます。
code:sample-processing.pde
// 後で載せます
送信するデータのサイズが4bytes(time) + 3bytes(value1) + 3bytes(value2) + 3bytes(value3) = 13bytes となり、21bytes から 13bytesまでデータを削減できました。この事によって、理論上は1msec周期でデータを送信することができます。
最後に
完全に1msec周期ではないですが、これでほぼリアルタイムで3チャンネルの同時計測が実現できます。
何かセンサーからArduinoを使ってデータをシリアル通信経由で取り込むときの参考になれば幸いです!