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

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

新規登録して質問してみよう
ただいま回答率
85.48%
GPS

GPSは、Global Positioning Systemの略です。衛星信号を使用して受信機の地上又は空中内の居場所を特定するナビゲーションシステムです。"GPS"は受信機のことも指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1725閲覧

Arduino 測定データ 定期的に取得

raspypy

総合スコア247

GPS

GPSは、Global Positioning Systemの略です。衛星信号を使用して受信機の地上又は空中内の居場所を特定するナビゲーションシステムです。"GPS"は受信機のことも指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/06/15 01:56

編集2021/06/18 06:59

##試していること
取得したデータを一定間隔の時間でAmbientに送信するプログラムを作成しています.
Arduino,Ambientに送信した後,deep sleepに移行します.

##困っていること
↓のプログラムで,Ambientへのデータ送信を試みているのですが,
deep sleepへの移行との兼ね合いで,うまく動作してくれません.
具体的には,↓のプログラムを実行すると,すぐにdeep sleepに移行してしまいます.

プログラムの意図としては,setup内でシリアルをオープンした後,
**sendAmbient()**関数でデータ取得,Ambientへのデータ送信をするという考えなのですが,
実際は,**sendAmbient()**関数へ移行することなく,Deep sleepになってしまいます.

##プログラム

C++

1void setup(){ 2  SwSerial.begin(9600); 3 4 Serial.printf("enter deep sleep\n"); 5 delay(10); 6 esp_deep_sleep(1000000LL * S_PERIOD); // S_PERIOD秒Deep Sleepする 7 Serial.printf("in deep sleep\n"); 8} 9 10

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

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

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

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

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

guest

回答3

0

ベストアンサー

setupでやるべき仕事とloopでやるべき仕事が分離できていないように思います。
最初に while (SwSerial.available() > 0) に到達した時、SwSerial.available() の値がどうなると思われますか?
つまり、起動直後にシリアルにデータが入ってきていることがあるかどうかということですが


https://garretlab.web.fc2.com/arduino_reference/language/functions/communication/serial/available.html

Serial.available()は、「シリアルポートから読み取り可能なバイト数(文字数)を取得する。これは、すでにArduinoボードに到着していて、シリアル通信用の受信バッファに格納されているデータである。シリアル通信用の受信バッファは64バイトまで格納することができる。」関数です。
つまり、while (SwSerial.available() > 0){...}は、「シリアルポートに何か入力が入っている場合は{...}ブロックの中身を実行し、シリアルポートに何かが入った状態でなくなったら、抜ける」処理となります。
さて、SerialをSerial.beginした直後のタイミングで、シリアルポートに何か入っている(相手から何かデータが送られている)でしょうか?送られていませんね。その結果、whileのブロックの中の処理は全く行わず、そのままdeep_sleep処理に入っているということです。

while (SwSerial.available() > 0){...} の上にさらにループが必要だと分かっていただけましたか?つまり何が言いたいかというと、loop関数を使ってあげてねということです


現在setup内で行っている、deep_sleepする処理を、どういうときにさせたいのかを考えれば、どこに書けばいいのかわかると思います。
「どういうときにsleepさせたいの?」
「その処理を行っているのはどこなの?」
を考えてください

投稿2021/06/15 04:54

編集2021/06/15 06:57
WoodenHamlet

総合スコア306

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

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

WoodenHamlet

2021/06/15 07:02

と言うかなんか、「場所かえてみたらなんかうごいた!ヨシ!」って思ってそうなのがなんだかなあ。 コレ多分setup直後deep_sleep入って、相手側からのシリアル通信で起きてその後sleepせず、whileの処理も中途半端に相手にデータ送り続けてる処理になってるしなあ…
raspypy

2021/06/15 07:23

deep sleepを記述する場所が間違えておりました. 「どういうときにsleepさせたいの」 のコメントがとても助かりました.ありがとうございました。
guest

0

起動時に :setup()
シリアルに1バイト以上受信データがある場合 : while(SwSerial.available() > 0){...}
1文字読み出して : SwSerial.read()
エンコードを試み : gps.encode(...)
成功したら : if(...)
sendAmbient()を実行してwhileを抜けてスリープに移る。

というコードになっています。いいですよね?


まず、while(SwSerial.available() > 0)ですが、
起動してから1バイト以上受信する前にここの判定に入ることが大半だと思います。
なのでこの場合whileの中に入りません。

仮にタイミングが良くて1文字は受け取ったとしましょう。
すると1文字受信しますが、1文字だけではgps.encode(...)が完成せずに即座に1回ループを回ります。
そうなるとSwSerial.available() > 0を判定しますが、しかしシリアル通信は遅いので今度は何も受信していません。そうなるとwhileを抜けます。

これがsendAmbient()が呼ばれない原因です。


やりたいことは
gps.encode(...)が成功するまで受信を続ける、
成功したらsendAmbient()を呼んでスリープに移るだと思います。

投稿2021/06/15 05:17

ozwk

総合スコア13521

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

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

raspypy

2021/06/15 05:42

分かりやすい回答ありがとうございます。 **gps.encode(...)が成功するまで受信を続ける、 成功したらsendAmbient()を呼んでスリープに移る** やりたいことを行うために,sendAmbient()の位置を修正しました. 今度は,sendAmbient()関数が呼び出されて"Hello"が表示されたのですが, その後の,**if (gps.location.isValid()) {**以降が実行されません.
ozwk

2021/06/15 05:58 編集

> gps.encode(...)が成功するまで受信を続ける 続けてないです。 修正後のコードは、「データを受信していたらgps.encode(...)を行う」を繰り返しています。 どこかのタイミング(十中八九最初の1回目)で受信していなかったら終わりです 問題の本質が何一つ改善していません while(SwSerial.available() > 0) を受信するまで待機するための呪文だと思っていませんか?
raspypy

2021/06/15 06:23 編集

プログラムを編集しました. "Hello1"まで表示されたところで,終わってしまいます.
WoodenHamlet

2021/06/15 06:44

if (gps.encode(SwSerial.read())) {が実行されていると思いますか?されていないと思いますか?>>raspypyさん
raspypy

2021/06/15 06:49

コメントありがとうございます。プログラムを編集しました. 現在掲示しているプログラムでは(常時送信となるため,現実的ではありませんが),ambientへのデータ送信ができています. ここまでは,できたのですが, ambientへデータ送信して,送信した後はdeep sleep(**秒)というプログラムに変更するところで躓いています.
guest

0

while (SwSerial.available() > 0) {

この条件が真になってないのでループしないんでしょうね

#これ、真になるわけがない、ってのはわかるでしょうか

投稿2021/06/15 01:58

編集2021/06/15 02:00
y_waiwai

総合スコア87774

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

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

raspypy

2021/06/15 02:04

すみません.これが真にならないという理由が分かりません. 真になっていると思い込んでいました.
y_waiwai

2021/06/15 02:14

まず、シリアル通信ってのはどういうもんか学びましょう ハードウエアの知識が必要になります  SwSerial.begin(9600); で、シリアルポートが初期化されます。この引数の数字は何を表すかわかるでしょうか。 シリアル通信で、1ビットあたりの周波数をここで設定します 通信はバイト単位で行われ、バイトの区切りでスタートビット、ストップビットが挟まるため、1バイトの通信は10ビットでおこなわれます で、ここで、1ビットあたり9600Hzと定義されました。 1バイト、10ビットの通信を行うのにどれだけの時間が必要でしょうか
raspypy

2021/06/15 07:25 編集

理解が悪くてすみません. としてみたのですが,これでもすぐにdeep sleepに移行してしまいます
y_waiwai

2021/06/15 04:22

whileをその条件では回らない、といってます。 このコードではここで書けるようなアドバイス程度ではあなたの思うようにはできませんので、まずはシリアル通信について学びましょう。 受信側だけではなくて、その相手方のほうがどんなものかという知識も必要です
raspypy

2021/06/15 07:24 編集

スイッチを用意して,押下したときに送信するというプログラムを動作させることができました.
y_waiwai

2021/06/15 05:22

そのシリアル通信で、送信側はどういうデータ形式なんでしょうか コードを見る限り、まともにデータを受信してる様子もありません。 そもそもシリアル通信をするというプログラムになってません。 繰り返しますが、まずはシリアル通信って何かというのを学ぶことから始めましょう(さんかいめ)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問