🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Raspbian

Raspbianは、DebianベースのRaspberry Pi用ディストリビューション。ハードウェア浮動小数点演算を有効にすることが可能で、Webブラウズなどの速度を向上できます。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

解決済

2回答

1522閲覧

ArduinoとRaspberry Pi 3B+間でのUSBシリアル通信

masotail

総合スコア6

Raspbian

Raspbianは、DebianベースのRaspberry Pi用ディストリビューション。ハードウェア浮動小数点演算を有効にすることが可能で、Webブラウズなどの速度を向上できます。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2019/12/20 08:23

Arduinoで一定回数測定した複数の電圧データをリアルタイムでまとめてRaspberry Pi に送り,送り終えたらまた一定回数測定し送る...というのを実現したいと思っていますがやり方がわかりません。教えてください。
電圧測定のコードは下のようになっています。下のコードでいうとs[1000],V0[1000],V1[1000],V2[1000]を送りたいと考えています。転送後ただの数字の並びとしてではなく送る前と同様に配列として扱いたいです。

Arduino

1void setup() { 2 // シリアルポート初期化 3 Serial.begin(9600); 4} 5 6int sampling_num = 1000; 7float sampling_rate = 0.001;//1microsに何回サンプリングするか 8int sampling_interval = 1/sampling_rate;//[micros] 9 10float s[1000]; 11float V0[1000]; 12float V1[1000]; 13float V2[1000]; 14 15void loop() { 16 17 int moji; 18 // シリアルポートより、文字を1字読み込む 19 moji = Serial.read(); 20 21 // 文字入力があった場合のみif関数を実行 22 if(moji != -1){ 23 24 int i=0; 25 int k=0; 26 // 開始時間を記録 27 unsigned long StartTime = micros(); 28 unsigned long NextTime = StartTime; 29 30 while(k<sampling_num){i=0; 31 32 while(i<sampling_num){ 33 s[i]=micros()-StartTime; 34 NextTime=NextTime+sampling_interval; 35 int result0; 36 int result1; 37 int result2; 38 39 result0 = analogRead(0); 40 result1 = analogRead(1); 41 result2 = analogRead(2); 42 43 V0[i]= result0 * 5.0 / 1023.0; 44 V1[i]= result1 * 5.0 / 1023.0; 45 V2[i]= result2 * 5.0 / 1023.0; 46 47 while (micros() < NextTime){ 48 }i++; 49 } k++; 50 51 } 52 53}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2019/12/21 01:01

Arduinoと言っているのがUNOであるなら、RAMが2KBしかないという大問題が... ESP32をArduinoとして使っている、とかならいけますけれど。
masotail

2019/12/21 01:59

Dueを使う予定です。その場合は可能でしょうか?他の種類のArduinoが適しているならば教えていただきたいです。
thkana

2019/12/21 04:02

ARMだとfloatひとつが4byteで、それを4000個確保しようというのだから、その分のメモリ容量はわかりますね?
guest

回答2

0

どんなに頑張ってもシリアル通信はバイトデータの連なりをやりとりすることしか出来ませんから、シリアル通信を通す段階で「ただの数字の並び」にするしかありません。あとは、それをPythonのプログラムで(受け側がPythonというのはあっちにしか書いてなかったか) 再構成してやることになります。

いきなり複雑なことをやらないで、ひとつの数値を送り、受けるところを確実にして下さい。質問の雰囲気からそれが出来ていないだろうと思っているのですが、それが出来なきゃ話になりませんから。
次にそれをふたつの数値にします。
そうしたら、あとは(極論ですが)それを4000回繰り返すだけです。

投稿2019/12/21 04:16

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

手順は、
(1)arduino側で測定した時間と、3つの電圧の測定を1000回繰り返して

float s[1000]; float V0[1000]; float V1[1000]; float V2[1000];

という4つの配列にデータを入れる。

(2)これらの配列の内容を文字列に変換して、arduinoからraspberryにシリアル通信を使って送る。

(3)raspberry側は送られてきた文字列を4つの配列に戻す。

というような感じです。

arduinoとraspberry間で厳密なデータ交換手順(プロトコル)を定めてから始めると、面倒だと思いますから、データを送るのにはCSV形式の文字列を使うのが良いと思います。

シリアル通信は、バイト(8bit)データの列しか送れません(配列のような構造を持つデータをそのまま送るのは無理です)。

なので、
・Arduino側で配列から文字列に変えて、raspberryに送る。
・raspberry側で文字列を受け取って、それを配列に戻す。
という作業が必要なのです。

=補足:配列のデータを文字列に変えるコード=

回答でcsv形式の文字列と書いたのは、コンマ(",")でデータを区切った文字列で一群のデータ(1つの配列の内容)を表し、改行文字列("\r\n")でデータ群を区切るものを想定しています。
例えば、

float anArray[5] = {1.23, 2.38, -1.25, 4.12, 6.33};

という配列は、
"1.23,2.38,-1.25,4.12,6.33\r\n"という文字列にします。

配列から文字列を作るコードは、下記のような感じです。

string stringData = ""; //結果の文字列を入れる変数  for (i=0; i<5, i++) { if(i<4){ //最初の4つは、データの数字とカンマを追加する stringData = stringData + _Floating_to_string("%f",anArray[i])+","; } else{ //最後は、データの数字と改行文字列を追加する stringData = stringData + _Floating_to_string("%f",anArray[i])+"\r\n";} }

raspberry側でこのような文字列を受信したら、改行文字の手前までを切り出して、それをカンマを区切り文字にしたsplit関数で配列にできます。

投稿2019/12/20 12:41

編集2019/12/21 06:23
coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masotail

2019/12/20 15:57

ご返答ありがとうございます。 シリアル通信をする上での方法はわかりましたが調べても具体的な方法はよくわかりませんでした。初歩的な質問で申し訳ありませんが、配列をcsv形式の文字列に変換する方法と文字列を配列に戻す方法について具体的に教えていただきたいです。
masotail

2019/12/21 12:32

配列を文字列にする方法に関するご丁寧な解説ありがとうございました。 split関数使用後、文字配列になりますが数値配列として扱いたいと考えています。例えば '1.5' ではなく1.5という数値として配列に格納したいです。その方法を教えていただきです。また改行文字列/r/nを使うことによって複数のデータ群を一つの文字列で表すことができることは分かりましたが、最後に書かれてある改行文字/r/nの手前で切り出すことによって一つの文字列を複数の配列群(ここではs,V0,V1,V2の4つ)に戻す具体的な方法について教えていただきたいです。
coco_bauer

2019/12/22 02:37

「C++ 文字を数値に変換」でWeb検索すれば判るのではないですか? 少しは自助努力したほうが良いです。 何でも人任せでは、いつまで経っても自分でプログラムが書けるようにならないですよ。 そもそも、C++の参考書とか持ってますか? ちゃんと最初から最後まで読んでいますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問