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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

M5Stack

M5Stackは、小型のマイコンモジュールです。拡張モジュールが豊富に用意されており、センサと組み合わせることで測定機能を自由に追加することができます。

kintone

kintone(キントーン)とは、サイボウズ社が提供する業務改善プラットフォームです。

Arduino

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

Q&A

解決済

1回答

8399閲覧

M5Stack(ESP32)が勝手に再起動してしまいます

nullsan

総合スコア20

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

M5Stack

M5Stackは、小型のマイコンモジュールです。拡張モジュールが豊富に用意されており、センサと組み合わせることで測定機能を自由に追加することができます。

kintone

kintone(キントーン)とは、サイボウズ社が提供する業務改善プラットフォームです。

Arduino

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

0グッド

0クリップ

投稿2020/01/07 22:04

お世話になっております。
M5StackでWi-Fi経由でkintoneにデータをアップロードするコードを書き実行しました。
M5Stackを起動しアップロードを始めるとなんどトライしても約132秒後に勝手に再起動してしまいます。

原因がまったくわからないのでハードの問題かソフトの問題かわかりません。
コードを記しますので原因や解決法についてアドバイスを頂ければ助かります。

#include <M5Stack.h> #include <TinyGPS++.h> #include <HTTPClient.h> #include <M5StackUpdater.h> #include "utility/MPU9250.h" HardwareSerial GPS_s(2); MPU9250 IMU; HTTPClient http; TinyGPSPlus gps; //各種初期セット int signalin = 35; //A0pin読み取り設定 int signalVal = 0; //アナログ値格納用 float sigV = 0; //信号電圧 int batv = 0; //バッテリー電圧 int Timeout = 0; //Wi-Fi接続タイムアウト float sigLine = 1; //ADC閾値初期セット値 int DelayTime = 0; //ADCノイズディレイタイム初期セット値 unsigned long RunTime = 0;//端末稼働時間 //kintone const int appId = アプリID; //GPS int STAS = 0; int HDOP = 0; float ALT = 0; float SPD = 0; float LAT = 0; float LNG = 0; void setup() { M5.begin(); M5.Power.begin(); Wire.begin(); GPS_s.begin(9600); IMU.initMPU9250(); if (digitalRead(BUTTON_A_PIN) == 0) { Serial.println("Will Load menu binary"); updateFromFS(SD); ESP.restart(); } // Wi-Fi 接続待ち WiFi.begin(); // Wi-Fi接続 while (WiFi.status() != WL_CONNECTED) { delay(100); M5.Lcd.printf("."); Timeout = millis(); if (Timeout >= 10000) { M5.Lcd.printf("wifiTimeout"); delay(1500); M5.Lcd.printf("Reboot now"); delay(1500); ESP.restart(); } } M5.Lcd.println("\nwifi connect ok"); delay(1000); pinMode(signalin, INPUT); M5.Lcd.drawJpgFile(SD, "/jpg/GMS.jpg"); delay(3000); M5.Lcd.drawJpgFile(SD, "/jpg/miniGMS.jpg"); } void loop() { M5.update(); signalVal = analogRead(signalin); sigV = signalVal * 3.3 / 4095; batv = M5.Power.getBatteryLevel(); RunTime = millis()/1000; IMU.readAccelData(IMU.accelCount); // 加速度の生データーを取得する IMU.getAres(); // スケール値を取得する // x/y/z軸の加速度値を計算する IMU.ax = (float)IMU.accelCount[0] * IMU.aRes - IMU.accelBias[0]; IMU.ay = (float)IMU.accelCount[1] * IMU.aRes - IMU.accelBias[1]; IMU.az = (float)IMU.accelCount[2] * IMU.aRes - IMU.accelBias[2]; while (GPS_s.available() > 0) { if (gps.encode(GPS_s.read())){ STAS = gps.satellites.value(); HDOP = gps.hdop.value(); ALT = gps.altitude.meters(); SPD = gps.speed.kmph(); LAT = gps.location.lat(); LNG = gps.location.lng(); break; } } //LCD M5.Lcd.fillRect(0, 0, 265, 240, 0xFFFF); M5.Lcd.setCursor(1, 1); //文字の位置 M5.Lcd.setTextSize(1);//文字の大きさ M5.Lcd.setTextColor(BLACK); M5.Lcd.print("ADC:"); M5.Lcd.print(sigV); M5.Lcd.print("V"); M5.Lcd.print(" IB:"); M5.Lcd.print(batv); M5.Lcd.println("%"); M5.Lcd.print("ax:"); M5.Lcd.print(IMU.ax); M5.Lcd.println("mG"); M5.Lcd.print("ay:"); M5.Lcd.print(IMU.ay); M5.Lcd.println("mG"); M5.Lcd.print("az:"); M5.Lcd.print(IMU.az); M5.Lcd.println("mG"); M5.Lcd.print("satellites:"); M5.Lcd.print(gps.satellites.value()); // Number of satellites in use (u32) M5.Lcd.print(" hdop:"); M5.Lcd.println(gps.hdop.value()); // Horizontal Dim. of Precision (100ths-i32) M5.Lcd.print("month:"); M5.Lcd.print(gps.date.month()); M5.Lcd.print(" day:"); M5.Lcd.println(gps.date.day()); M5.Lcd.print("Time/"); M5.Lcd.print(gps.time.hour()); M5.Lcd.print(":"); M5.Lcd.print(gps.time.minute()); M5.Lcd.print(":"); M5.Lcd.print(gps.time.second()); M5.Lcd.print(":"); M5.Lcd.println(gps.time.centisecond()); M5.Lcd.print("ALT:"); M5.Lcd.print(gps.altitude.meters()); M5.Lcd.print(" SPD:"); M5.Lcd.print(gps.speed.kmph()); M5.Lcd.println("km/h"); M5.Lcd.print("LAT="); M5.Lcd.println(gps.location.lat(), 6); M5.Lcd.print("lng="); M5.Lcd.println(gps.location.lng(), 6); //kintone接続&アップロード const int appId = アプリID; char jsonFormat[] = "{\"app\":\"%d \",\"record\": {\"kadou\":{\"value\":\"%d\"},\"IB\":{\"value\":\"%d\"},\"ADC\":{\"value\":\"%3.2f\"},\"AX\":{\"value\": \"%3.2f\"},\"AY\":{\"value\":\"%3.2f\"},\"AZ\":{\"value\":\"%3.2f\"},\"S\":{\"value\":\"%d\"},\"hdop\":{\"value\":\"%d\"},\"ALT\":{\"value\":\"%5.1f\"},\"SPD\":{\"value\":\"%4.1f\"},\"Lat\":{\"value\":\"%9.6f\"},\"Lon\":{\"value\":\"%9.6f\"}}}"; char json[sizeof jsonFormat + (8 * 11) -1]; sprintf(json, jsonFormat, appId, RunTime, batv, sigV, IMU.ax, IMU.ay, IMU.az, STAS, HDOP, ALT, SPD, LAT, LNG); int httpResponseCode = 0; http.begin("https://サブドメイン名.cybozu.com/k/v1/record.json"); http.addHeader(F("X-Cybozu-API-Token"), F("APIキー")); http.addHeader(F("Content-type"), F("application/json")); httpResponseCode = http.POST(json); M5.Lcd.printf("httpResponseCode = %d \n", httpResponseCode); M5.Lcd.println(http.getString()); delay(1000); }

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

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

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

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

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

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

dodox86

2020/01/08 01:17

http.POST(json); でhttpsでPOSTをしていますが、httpsで送信できていないか、レスポンスが返ってこないか、レスポンスは返ってきているけど期待のレスポンスになっていなくて停まっているのかもしれません。そこから確認されてみてはいかがでしょう。
nullsan

2020/01/08 22:18

ご回答ありがとうございます。 正常にデータがアップロードされている上、アップロード中はhttpResponseCodeで1が返ってきているので問題なく通信されているかと思っています。 ほかに確認方法があればご教示いただけますか?
dodox86

2020/01/09 00:05

> httpResponseCodeで1 1で正しいのでしょうか? ESP32のHTTPClientであれば、ここはHTTPステータスの200とか返ってきそうなところですが。http.POSTをしなければ再起動しないのであれば、明らかにhttp.POST(の使い方)が原因です。あとはsprintfを使わずに、固定値で送った場合にどうなるか試してみてはいかがでしょうか。sprintf(の使い方)の問題かどうかが切り分けられます。既に回答をいただいているので、以降はコメントは控えます。
thkana

2020/01/09 13:42

とりあえず、 httpResponseCode = http.POST(json); の行をコメントにしたらどう変わるか、ぐらいは見てもバチは当たらないと思う。
nullsan

2020/01/09 22:16

>dodox86様 ご回答ありがとうございます。ステータスコードは200が返ってきました。 ただ再起動が発生してしまうことに変わりなし,,です。 >thkana様 コメントアウトしたところ、再起動発生しなくなりました! また、アップロード間隔を1sから2sに変更したところ、稼働時間も倍になりましたがやはり再起動は発生します。。。 なにが原因なのでしょうか。。。
thkana

2020/01/09 22:48

それでわかるのは、やっぱりhttpClient周りが怪しいということ。 ところで、前の質問 https://teratail.com/questions/232747 のendの件はどうだったんでしょう?
dodox86

2020/01/10 01:27

http.POSTを何回もやっている内に、トータルで130秒くらいで再起動している、と言うことでしょうか。であれば、httpのオブジェクトを使いまわしているために、中で何か致命的なメモリーリークなどが起きているのかもしれません。HTTPClient httpをグローバル変数として宣言するのではなく、loop()関数内のローカルで試してみては。
dodox86

2020/01/10 01:32

あと、httpオブジェクトを使いまわしているのであれば、 http.addHeader(F("X-Cybozu-API-Token"), F("APIキー")); などとloop()ごとに実行してはいけないのでは。(中で適切に処理されているかもしれませんが)これだとどんどん追加されてしまうと思います。
nullsan

2020/01/11 08:12

dodox86さんご回答ありがとうございます。 http.addHeader(F("X-Cybozu-API-Token"), F("APIキー"));という部分はloopの外で一度だけ処理すればloopでその都度実行する必要はない、ということでしょうか?
thkana

2020/01/12 12:08

Pythonでお試しサーバ立てて実験してみたのですが、httpの接続を無造作に http.begin("http://192.168.10.3:8000"); としていたら高頻度(数回に1回)でリブートがかかりました。Python側でHTTP0.9と出るのが気になってHTTPClient.hを覗くと、 #ifdef HTTPCLIENT_1_1_COMPATIBLE なんていう条件コンパイルもあったりしてするので、なにかの拍子でHTTP0.9になったりするのかも知れません。HTTP0.9にはPOSTがないのでいろいろ起こるとか? ちなみに、 http.begin("192.168.0.3",8000); としたらHTTP1.1になって、しばらく走らせてもリブートはかかりませんでした。何かその辺書き方を変えてみたら、例えば bool begin(String host, uint16_t port, String uri = "/"); だったらどうなるか、というのは試せそうです。
nullsan

2020/01/19 04:52

詳しい説明と検証ありがとうございます。 こちらでも検証を進めてみます!
nullsan

2020/01/19 04:53

dodox86さん >HTTPClient httpをグローバル変数として宣言するのではなく、loop()関数内のローカルで試してみては。 まさにこれが原因でした! なぜこのようなことが起きるのか不思議ですが、ほかの皆様から頂いた情報をもとに検証をしてみたいと思います!
dodox86

2020/01/19 05:42

> なぜこのようなことが起きるのか不思議ですが、 ローカルで宣言すると、HTTPClientクラスのオブジェクトはloop()が実行されるたびに生成(初期化)し、消滅します。 http.addHeader()(<とは限りませんが)などの呼び出しでメモリ使用が累積することもなくなる為でしょう。N回目で必ずNG(再起動かかる)なら、再現性が極めて高いと言えて、その可能性が大きいです。HTTPClientのソースファイル自体を読んでみることをおすすめします。
dodox86

2020/01/19 06:00

例えばお使いのM5StackのHTTPClientのソースが以下なのであれば https://github.com/espressif/arduino-esp32/blob/master/libraries/HTTPClient/src/ HTTPClient::addHeader は HTTPClientクラス内のメンバー変数String _headers;に、addHeaderを呼び出すごとに足し込んでいくようなコードになっています。最初の呼び出しであれば引数に「初めてのヘッダー追加」とのようにフラグを指定する必要がありそうです。 void addHeader(const String& name, const String& value, bool first = false, bool replace = true); これが原因であれば、HTTPClientをグローバルに宣言していて、それを使いまわす元のコードでは問題(メモリーを使い切る)があることになります。あとはご自分で確認してみてください。
nullsan

2020/01/19 06:01

なるほどですね。 グローバルですとオブジェクトがその都度呼び出されて蓄積されていって最終的にメモリがオーバーフローするということでしょうか?
dodox86

2020/01/19 06:08

C++のお話になります。HTTPClientのオブジェクト(インスタンス)が生き続けていて、loop()を呼び出すたびにaddHeaderなり他のメンバー関数を呼び出し、その中でメモリ使用量が増えるような操作になったら、どうなるでしょうか。グローバル変数ではなく、loop()内のスコープで生成(construct)、消滅(destruct)するなら、使用するメモリは累積しませんよね。
guest

回答1

0

ベストアンサー

まず考えられることは、電源の容量不足です
電源はどこからとってるでしょうか。この電源を変えてみて、状態が変わるかを見てみましょう

投稿2020/01/07 22:23

y_waiwai

総合スコア87800

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

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

nullsan

2020/01/07 23:03

>まず考えられることは、電源の容量不足です 電源はバッテリーモジュールから取得しています。 ■バッテリーモジュール https://www.switch-science.com/catalog/3653/ 外部電源(モバイルバッテリー5V)を接続してもやはり再起動してしまいますので、コンセントから取得してみます。。。
y_waiwai

2020/01/07 23:14

電源変えても全く同じタイミングで止まる、というならソフト由来ということになろうかとおもわれます。
y_waiwai

2020/01/07 23:23

コードを見ていて、イカにも怪しいところが。 > char json[sizeof jsonFormat + (8 * 11) -1]; 配列サイズが不足して、スタックを破壊、暴走してるんでは 配列サイズですが、512とか1024とかにしてみては。
nullsan

2020/01/08 22:16

いつもご回答ありがとうございます。 配列サイズを1024に変更しました。すると一度目は約240秒ほど稼働できましたが再起動が発生しました。 その後の稼働時間は約130秒となり結果は変わりませんでした...。
y_waiwai

2020/01/08 22:27

それで状態が変わったのならまさにそれが原因ってことですね。 そこらへんの周りを見直してみては。
nullsan

2020/01/08 22:44

わかりました! ちなみにChar型というのは指定した配列に従ってをメモリに値を保存後、別関数で指定したアドレスの値を都度呼び出しているという解釈でよろしいでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問