北東北 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/17
13,888件の閲覧回数

精一杯がんばって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/17
13,872件の閲覧回数

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

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

0 件の賞賛
メッセージ3/17
13,868件の閲覧回数

LabView超初心者のKintadと申します。

 

複数の生体センサをArduino UNOから読み込んでPCで処理することを考えています。サンプリング周波数は1kHz程度で最大8チャンネル程度です。これまでは、nRF52マイコンとC++/MFCで作成したWindowsデスクトップアプリの組み合わせを使っていました。だいぶ前に人に作っていただいたファーム・アプリを改良して使ってきたのですが、色々、処理速度も上がってきているので、ひょっとして、Arduino/LabViewの組み合わせが使えるのではないかと探していたら、このサイトを見つけました。LabViewは高価だと認識していたのですが、商用でなければ、LabVIEW Community Editionが使えるということも知り、ぜひ使ってみたいと思っています。

 

で、UNOのR3を使って、Continuous Serial Read BinaryBlock内の、inoファイルとviファイルを使ってみたのですが、Arduinoの方はうまく行ったのですが、LabViewは下のエラーが出て動作しません、シリアル設定の定義ファイルが見つからないようなのでが、viを読み込むときにctlファイルを聞いてきているところで、入力できないことと関係があると思われます。

 

今回、初めて、LabViewを使ったズブの素人です。ご指導いただけると幸いです。

 

アラート.jpg

0 件の賞賛
メッセージ4/17
490件の閲覧回数

こんにちは、おおはしです。

 

分かりにくくてすみません。

原因は以下の推測通りだと思います。

***********************************

LabViewは下のエラーが出て動作しません、シリアル設定の定義ファイルが見つからないようなのでが、viを読み込むときにctlファイルを聞いてきているところで、入力できないことと関係があると思われます。

***********************************

”Serial - Settings.ctl”は
LabVIEWのexamples > Instrument IO > Serial > supportの中に入っています。
LabVIEW Community 2024 Q3の”Serial - Settings.ctl”を添付しましたので、ダウンロードして
"Continuous Serial Read BinaryBlock.vi"と同じ階層に置いていただければそれを読み込んでくれると思います。
あるいは、”Serial - Settings.ctl”はどこにあると聞いてきたときに"examples > Instrument IO > Serial > support"とたどれば”Serial - Settings.ctl”が見つかると思います。
どうでしょうか?
0 件の賞賛
メッセージ5/17
477件の閲覧回数

おおはしさま

 

お返事が遅くなって申し訳ございません。おおはしさまからメールが届いていたので、間違って、そちらに返信しておりました。

 

Continuous_AnalogIn4kHz_SerialOutの方で、とりあえず、動作が確認できました(下図)

これをベースに、多チャンネル化・ビット数等、条件の最適化をしていこうと思います。

今後ともご指導お願いいたします。

 

スクショ.jpg

メッセージ6/17
420件の閲覧回数

kintadさん、
動いたとの連絡ありがとうございました。

周りの方々にLabVIEW Community版の宣伝をよろしくお願いします。

 

シリアル通信関連のプログラムはexamplesの”Continuous Serial Write and Read.vi”を改造して作ることが多くて、作成している環境では動いてしまうので”Serial - Settings.ctl”がType def.(タイプ定義)されていることを忘れてしまいます。
Type def.(タイプ定義)を解除してしまえば面倒はないと思います。

スクリーンショット 2025-03-04 12.58.16.png

0 件の賞賛
メッセージ7/17
401件の閲覧回数

おおはしさま

 

ありがとうございます。

Type def.(タイプ定義)を解除してみました。

 

1kHzサンプリングで測定しているのですが、チャートの横軸を5秒程度にしたいのですが、どこをいじったらいいのでしょうか?

おそらく、データを離散的に表示する必要があるのかと思うのですが

 

真面目に勉強すればわかるのだとは思いますが…聞いてしまって申し訳ございません

0 件の賞賛
メッセージ8/17
396件の閲覧回数

おおはしさま

 

すみません、できました。いじれるようになってくると、操作性もよく、すばらしいですね。

スクショ.jpg

0 件の賞賛
メッセージ9/17
391件の閲覧回数

ここで紹介するのが適切かどうかわかりませんが、

【ペリテック創業40周年】40周年記念キャンペーン:LabVIEW基礎講座PDFプレゼント

というのがあって、この資料は初めて触る人にもわかりやすいかもしれません。

 

40周年記念キャンペーン:LabVIEW基礎講座PDFプレゼント 

 

0 件の賞賛
メッセージ10/17
385件の閲覧回数