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

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

詳細はこちら
Arduino

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

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

Q&A

解決済

2回答

4125閲覧

2台の arduino と PC をシリアル通信させているつもりだが値が送られない

退会済みユーザー

退会済みユーザー

総合スコア0

Arduino

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

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

0グッド

1クリップ

投稿2019/09/30 11:07

編集2019/09/30 11:09

「あるセンサ」と 「arduino(Aとします)」 をI2C通信させています
この「A」と「別のarduino(Bとします)」をシリアル通信させてAが取得しているセンサの値をBと共有し,
さらに「B」と「PC」をUSBケーブルを通じてシリアル通信させ,PCのシリアルモニタ上で見られるようにしたいと思っています.

SoftwareSerialを用いて以下のようにプログラムを組んでみたのですが,PC側のシリアルモニタでは,最初0が表示されたあとdelayごとにずっと-1が表示され続けてしまいます.

どこかプログラムにおかしい部分はありますでしょうか.

以下は「A」のコードです

#include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); // RX, TX void setup(){ Serial.begin(115200); mySerial.begin(115200); } double P = 0; void loop(){ Serial.println(P); //PCのシリアルモニタにPの値を表示 mySerial.listen(); P = mySerial.read(); //PにmySerial.readでBから持ってきたセンサの値を格納 delay(1000); }

以下は「B」のコードです

#include <Wire.h> #include <AllSensors_DLHR.h> //センサとのI2C通信に必要 AllSensors_DLHR_L10G_8 gagePressure(&Wire); //センサとのI2C通信に必要 #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); // RX, TX void setup(){ mySerial.begin(115200); // ソフトウェアシリアルの初期化 Wire.begin(); gagePressure.setPressureUnit(AllSensors_DLHR::PressureUnit::PASCAL); //センサとのI2C通信に必要 } double P; //センサの値格納用 void loop(){ gagePressure.startMeasurement(); //センサとのI2C通信に必要 gagePressure.readData(true); //センサとのI2C通信に必要 P = gagePressure.pressure; //Pにセンサの値を格納(Pには間違いなくdouble型のセンサの値が格納できています) mySerial.listen(); mySerial.write(P); delay(1000); }

Bのコード内にI2C通信のライブラリ関係が入っていますが,最終的にdouble型のPの中にセンサの値は格納されていることは確認しています.(シリアル通信でPの値がAから最終的にPCまで渡されないことで悩んでいます)

シリアルモニタの画面はこうなっています
イメージ説明

配線は
センサとAがI2C通信の配線で接続
AとBは2ピンと3ピン同士を接続(USBケーブルで給電)
BとPCがUSBケーブルで接続
です

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

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

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

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

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

guest

回答2

0

ベストアンサー

  • SoftwareSerialは重い処理なので、9600bpsとかそのへんまでにしといたほうがいいでしょう。

  • Arduino UNO(他AVRのArduino)においては、doubleは実はfloatと同じです。doubleとしても害はありませんが、有効桁が多くなるわけではないのは知っておくべきでしょう。

  • シリアル通信において、通信データの単位は"1バイト"です。doubleのような1バイトに収まらないデータを扱うときは何らかの「プロトコル」を決めなければいけません。以前別の回答で書いた「通信の話」はTCP/IPについてでしたが、シリアル通信でも事情は同様です。

何らかの方法で「データのひとかたまり」がわかるようにして、送信側と受信側でその形式について合意したうえで通信をしないといけません。

データの内部形式とかを気にしないで済むという点で、テキストデータを送受して改行コードを区切りとする、つまりSerial.println()でデータを文字列にして最後に改行を付けて送信し、Serial.readStrngUntil()で改行までを一括で受け取り、文字列をatof()等でdoubleに変換する、というあたりのやり方が手っ取り早いのではないでしょうか。

投稿2019/10/01 03:56

thkana

総合スコア7703

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

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

退会済みユーザー

退会済みユーザー

2019/10/01 08:12

ありがとうございました!
guest

0

まず、SoftwereSerialはプログラムコードでシリアル通信を実装しているため、あまり高速になると不安定となります
ここはボーレートを、9600,あるいはもっと小さい値にして動作の確認してみましょう
#確実に送受信ができるようになってから、ボーレートを大きくしていけばいい

で、次に、Serial.write関数ですが、引数にDouble変数を取るようにはできていません
Doubleの値を、文字列に変換してからserial.println関数で送るようにしましょう。
また、受信側も、1行単位で受信して、そこからdouble値に変換する必要があります

投稿2019/09/30 12:32

y_waiwai

総合スコア88038

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

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

退会済みユーザー

退会済みユーザー

2019/10/01 08:12

ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問