北東北 LabVIEWユーザー会

キャンセル
次の結果を表示 
次の代わりに検索 
もしかして: 

できるだけ高速にArduinoのアナログ入力でデータ収録する方法 (祝 "LabVIEW Community Edition")

非商用で使う無料のLabVIEW Community Editionの情報はご存知のことと思います。ArduinoとLabVIEWの連携はこれまで以上に活発になっていくと思いますので、Arduinoのアナログ入力で連続的にデータを収録する方法について検討しました。

 

Arduinoにはさまざまな基板がありますが、ここでは一番ポピュラーなUNOを使用しています。UNOの互換機は500円程度で入手できるので気軽に購入することができます。アナログ入力は6chあります。0-5Vで10ビット、1サンプリングにおよそ100μsecですから、10kHzぐらいのサンプリング周波数です。UNOに搭載されたマイクロコントローラATmega328のアナログ入力機能を使っていますので、レジスタの値を変更すると80kHzぐらいまでサンプリング周波数を変更することもできます。Arduinoの中でデータ処理をしてまとめた結果だけを受け取るのならばこのサンプリング周波数が生きてくるのですが、DAQデバイスのようにデータをPCに持って来ようとすると、シリアル通信がボトルネックになります。また、一定間隔のサンプリングとシリアル通信を両立する仕掛けも必要になります。

 

具体的にはArduino側のプログラムとして以下の事柄を考えます。

- タイマーによるアナログ入力

- 取得データのサーキュラバッファ

- バイナリデータでの送信

- 64バイトの通信バッファを意識した送信

LabVIEW側では送信されてきたものを受け取りテキパキ処理するだけです。

 

MA231079 2.JPG

 

MA231082 2.JPG

 

Arduinoからシリアル経由でできるだけ高速でデータを送り出すプログラム例はあまり見かけませんので参考になるかもしれません。また、もっと良い方法があれば教えていただきたいと思います。

 

続く投稿で、ArduinoプログラムとLabVIEWプログラムの説明とZIPファイルを添付します。

 

メッセージ1/3
12,706件の閲覧回数

精一杯がんばって10kHz、それなりにがんばって4kHzという感じです。

sketchSample.png

4kHz版のArduinoプログラムから説明しますので、

"Continuous_AnalogIn4kHz_SerialOut.ino"を見ながら以下を読んでください。

<<テキスト言語のコードを表示する機能が欲しいですが、残念ながらここには無い。>>

 

タイマー割込みはμsecで指定できるTimer1を使いました。

ライブラリはTimerOneライブラリを使います。

割り込み間隔は"const int T1_us=250;"で、250μsec間隔となります。割り込みで実行される関数はreadAnalog()です。"int circular[SizeBuffer];"という配列に"analogRead(A0)"で読んだ値を書き込みます。配列の指標は"volatile int arrayIndex"をバッファサイズで剰余した値を使います。volatileは割り込み中に変更される変数を他の場所で参照するときに使うとのことです。arrayIndexは現在の書き込み位置を知るためにメインループで参照します。

シリアルで最後に送ったデータの次から現在のarrayIndexのひとつ前までを送信するのですが、"analogRead(A0)"で読んだ値は2バイトデータなので上下バイトに分けて送信用の配列"byte data[(SizeTx+2)*2];"に書き込みます。配列の先頭は受け取りの目印のために0xFF, 0xFF, 0x00と決めて、4バイト目にデータ数を書いて置きます。

"Serial.write(data,(actSizeTx+2)*2);"で送信した後、"delay(1);"を置いています。

シリアルのボーレートは115200を使いました。

 

 

 

LabVIEW側はとりあえずシンプルに波形チャートに表示するだけとしました。"終端文字で読み取り終了?"はFalseにしておきます。データの切り出しは文字列関数が便利なので"0xFF, 0xFF, 0x00"を文字列に直してパターンで一致関数を使いました。

Continuous Serial Read BinaryBlock Diagram.png

200Hzの三角波です。

200Hz_SamplingRate4k.png

 

ボーレートが115200のときには4kHzがほぼ限界で、ボーレートを230400にするともう少し上げられます。さらに上げるとアナログ入力にかかる時間がネックになってくるので、AD変換クロックの分周比をデフォルトの1/128から1/16にすると10kHzまで上がりました。

分周比の変更は2行だけです。(ATmega328を使っているボードで有効)

ADCSRA = ADCSRA & 0xf8;
ADCSRA = ADCSRA | 0x04;

これも200Hzの三角波です。

200Hz_SamplingRate10k.png

500Hzの三角波にしてみました。

500Hz_SamplingRate10k.png

 

LabVIEW Community Editionが広く知られるようになれば、PCで受け取るプログラムをLabVIEWで書いて、少し速い現象で遊ぶ人も増えてくるかもしれません。

 

 

添付ファイル"Continuous Serial Read BinaryBlock.zip"

Continuous Serial Read BinaryBlock.vi

Continuous_AnalogIn4kHz_SerialOut.ino

Continuous_AnalogIn10kHz_SerialOut.ino

メッセージ2/3
12,690件の閲覧回数

2個目の投稿でファイル添付したのですがうまくいかなかったようです。この投稿で添付してみますが、うまくいかなければ後日添付します。

2個目の投稿のファイル添付がOKでしたので、この投稿は無視してください。

0 件の賞賛
メッセージ3/3
12,686件の閲覧回数