質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

87.79%

XBeeでのシリアル通信で予期せぬループをしてしまう。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,579

score 13

前提・実現したいこと

XBeeとArduino化したATMega328P-PUチップを二つ使用して、シリアル通信でセンサーから受け取った値に対して、12V電圧のオンオフを制御したい。(土が乾いていたらポンプで水やりができるプログラム)

発生している問題・エラーメッセージ

土壌センサが読み取った値によって、乾燥していれば'T'をもう一方のXBeeに送信する。'T'を受け取れば電圧がかかるようになっている。初めに湿っている状態では電圧がかからなく、そこから乾燥状態にすれば電圧がかかったが、その後に湿っている状態に戻しても電圧がかかったままになってしまう。('T'がずっと送信された場合のループが繰り返される)

該当のソースコード

Arduino スケッチ

センサー側

const int SensorIn = A5;//土壌湿度センサー値取得ピン番号

//初期設定
void setup(){
Serial.begin(9600);
pinMode(SensorIn, INPUT);}

//機能:土壌湿度センサーの値を読み込む関数
int SensorRead(){
int SensorValue = 0;                 
for(byte i=0;i<=10;i++){  //A3ポートの電圧を10回読み平均値を出す
delay(10);                       //一定時間電流を流して測定値を安定させる
SensorValue = SensorValue + analogRead(SensorIn);
}                 //センサー電圧を10回読み合計する
return SensorValue / 10;} //センサー電圧平均値を返す 

//メインループ
void loop(){
if(SensorRead()<350) { //土が乾燥していた場合以下実行
Serial.print('T'); // 文字'T'を送信
delay(10); // シリアル通信があふれないよう
}
}

受信側

const int Power = 8;//12V制御ピン番号

//初期設定
void setup(){
Serial.begin(9600);
pinMode(Power, OUTPUT);
}

//メインループ
void loop(){
if(Serial.available() > 0){  //土が乾燥していた場合以下実行
if (Serial.read() == 'T') {
digitalWrite(Power, HIGH);//水を出す
delay(5000);//5秒待つ
}
else{
digitalWrite(Power, LOW);
}
}//水を止める
digitalWrite(Power, LOW); 
delay(1000);
}//1秒待つ

試したこと

センサー側で一度乾いた状態を作って、受信側が電圧を出力する状態にした後に、センサー側の電源を切っても受信側は’T’を受信した場合のループを繰り返した。

受信側の電源を切って、再度電源を入れると'T'を受信して起こるループは止まった。
ただもう一度乾いた状態を作って、湿った状態にしても電圧がかかる状態がループした。

よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

if(SensorRead()<350) {

これが成立している間、送信しっぱなしになるので、この関数の戻り値が各状態のときにどうなってるか、どっかに出してみてみることですな。


if (Serial.read() == 'T') {
digitalWrite(Power, HIGH);//水を出す
delay(5000);//5秒待つ
}

シリアル入力のバッファが16バイトあるとどっかで読んだ覚えがあるので、
Tの送信が終わっても、16回水が出ることになるけど、それは想定した動作なのかな?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/10 00:04

    ちなみに、Arduino UNOの受信バッファは64byteだったかと。
    https://www.arduino.cc/en/serial/available
    いずれにしろ、数秒をdelayで待つ、なんてのは基本的にやらないほうがいいことです。

    キャンセル

  • 2019/04/10 11:28

    すみません。
    数分で止まったので16回だと勝手に思ってました。
    64byteで確認できました。
    数秒をdelayで待つことのデメリットが分かりません。
    よければ教えていただけないでしょうか。
    実際は3分ほど水やりをして、再度センサーで判定を行うの繰り返しを考えています。
    よろしくお願いします。

    キャンセル

  • 2019/04/10 23:36

    > 数秒をdelayで待つことのデメリット
    今回で言えば、送信側が100ms周期で動いていることに対するアンバランスですね。
    一般論としては、待っている間なにも出来ない、というのが欠点となり得ます。例えば、「緊急停止スイッチ」を追加したとして、そのスイッチを操作しても最悪5秒システムが反応しない、などという事態になります。質問の件だけについて言えば5秒の無反応で支障はないのかも知れませんけれど。
    反応の良いシステムはゆっくりでいいアプリケーションに使えますが、反応の悪いシステムでは不具合が出るので、だったらどちらで作っておいたほうが得か(大した手間でもないので)、というあたり。

    キャンセル

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

  • ただいまの回答率 87.79%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る