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

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

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

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

Q&A

解決済

1回答

2227閲覧

ESP32で2つのURLにGETリクエストができない

Raptor_zip

総合スコア18

Arduino

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

0グッド

0クリップ

投稿2022/08/19 07:48

編集2022/08/19 09:32

前提・実現したいこと

ESP32で、Open Weather Map (以下OWM)により、天気を取得し、次に、ウェブ アプリケーション化したGASを経由してDiscordにメッセージを送信したいです。そのために、OWMとGASのリンクにGETリクエストを送信して、返答を受け取りたいです。
ESP32でGASにGETリクエストを送信するときは、パラメータにvalue=12345をつけています。
GASがGETリクエストを受信すると、DiscordにWebhookを通してBOTによるメッセージが送信されます。
しかし、GETリクエストを送信することが上手く行きませんでした。

試したこと・問題

次のコードを基にして4種類試しました。

Arduino

1#include <HTTPClient.h> 2#include <WiFi.h> 3const String url1 = "https://script.google.com/macros/s/*****/exec?value=12345"; 4const String url2 = "http://api.openweathermap.org/data/2.5/weather?q=Japan, JP&APPID=*****"; 5 6void setup() { 7 Serial.begin(115200); 8 const char *ssid = "Buffalo-G-*****"; ////WiFi_SSID 9 const char *password = "*****"; ////WiFi_パスワード 10 Serial.print("Connecting to "); 11 Serial.println(ssid); 12 WiFi.begin(ssid, password); 13 while (WiFi.status() != WL_CONNECTED) 14 { 15 delay(500); 16 Serial.print("."); 17 } 18 19 Serial.println(); 20 Serial.println("WiFi connected."); 21 Serial.print("IP address: "); 22 Serial.println(WiFi.localIP()); 23 24 HTTPClient http; 25 //1回目のGETリクエスト 26 http.begin(url1); 27 int httpCode = http.GET(); 28 if (httpCode > 0) { 29 String payload = http.getString(); 30 Serial.println(httpCode); 31 Serial.println(payload); 32 } 33 else { 34 Serial.println("Error on HTTP request"); 35 } 36 http.end(); 37 38 delay(1000); 39 40 //2回目のGETリクエスト 41 http.begin(url2); 42 httpCode = http.GET(); 43 if (httpCode > 0) { 44 String payload = http.getString(); 45 Serial.println(httpCode); 46 Serial.println(payload); 47 } 48 else { 49 Serial.println("Error on HTTP request"); 50 } 51 http.end(); 52} 53void loop() {}

①url1をOWMのURLにし、url2をGASのURLにしました。結果、OWMは成功し、GASは失敗(ステータス・コードがこない)。
②url1をGASのURLにし、url2をOWMのURLにしました。結果、GASは成功し、OWMは失敗(ステータス・コードがこない)。
③url1と2をGASのURLにしました。結果、それぞれ成功
④url1と2をOWMのURLにしました。結果、それぞれ成功
2つのURLが異なると、2つ目は失敗し、2つが同じURLだと成功するようです。なので、URLがGAS、OWMだから失敗したわけではないように感じます。確証はありませんが。

ArduinoIDEのツール→Core Debug LevelはVerboseにしてあります。
①のシリアルモニターの内容

上略 IP address: 192.168.11.9 [ 3170][V][HTTPClient.cpp:252] beginInternal(): url: https://script.google.com/macros/s/*****/exec?value=12345 [ 3178][D][HTTPClient.cpp:263] beginInternal(): unexpected protocol: https, expected http [ 3186][V][HTTPClient.cpp:252] beginInternal(): url: https://script.google.com/macros/s/*****/exec?value=12345 [ 3202][D][HTTPClient.cpp:303] beginInternal(): protocol: https, host: script.google.com port: 443 url: /macros/s/*****/exec?value=12345 [ 3219][D][HTTPClient.cpp:598] sendRequest(): request type: 'GET' redirCount: 0 [ 3227][V][ssl_client.cpp:62] start_ssl_client(): Free internal heap before TLS 251100 [ 3234][V][ssl_client.cpp:68] start_ssl_client(): Starting socket [ 3302][V][ssl_client.cpp:149] start_ssl_client(): Seeding the random number generator [ 3303][V][ssl_client.cpp:158] start_ssl_client(): Setting up the SSL/TLS structure... [ 3307][D][ssl_client.cpp:179] start_ssl_client(): WARNING: Skipping SSL Verification. INSECURE! [ 3315][V][ssl_client.cpp:257] start_ssl_client(): Setting hostname for TLS session... [ 3323][V][ssl_client.cpp:272] start_ssl_client(): Performing the SSL/TLS handshake... [ 4411][V][ssl_client.cpp:293] start_ssl_client(): Verifying peer X.509 certificate... [ 4411][V][ssl_client.cpp:301] start_ssl_client(): Certificate verified. [ 4414][V][ssl_client.cpp:316] start_ssl_client(): Free internal heap after TLS 200656 [ 4422][D][HTTPClient.cpp:1156] connect(): connected to script.google.com:443 [ 4429][V][ssl_client.cpp:369] send_ssl_data(): Writing HTTP request with 245 bytes... [ 5760][V][HTTPClient.cpp:1250] handleHeaderResponse(): RX: 'HTTP/1.1 302 Moved Temporarily' 省略 [ 5939][D][HTTPClient.cpp:1307] handleHeaderResponse(): code: 302 [ 5944][D][HTTPClient.cpp:1314] handleHeaderResponse(): Transfer-Encoding: chunked [ 5952][D][HTTPClient.cpp:628] sendRequest(): sendRequest code=302 [ 5958][D][HTTPClient.cpp:922] writeToStream(): read chunk len: 557 [ 5967][D][HTTPClient.cpp:1446] writeToStreamDataBlock(): connection closed or file end (written: 557). [ 5974][D][HTTPClient.cpp:922] writeToStream(): read chunk len: 0 [ 5979][D][HTTPClient.cpp:388] disconnect(): still data in buffer (2), clean up. [ 5987][D][HTTPClient.cpp:393] disconnect(): tcp keep open for reuse 302 <HTML> <HEAD> <TITLE>Moved Temporarily</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> <H1>Moved Temporarily</H1> The document has moved <A HREF="https://script.googleusercontent.com/macros/echo?user_content_key=*****">here</A>. </BODY> </HTML> [ 6044][D][HTTPClient.cpp:388] disconnect(): still data in buffer (2), clean up. [ 6049][D][HTTPClient.cpp:393] disconnect(): tcp keep open for reuse [ 7055][V][HTTPClient.cpp:252] beginInternal(): url: http://api.openweathermap.org/data/2.5/weather?q=Japan, JP&APPID=***** [ 7057][D][HTTPClient.cpp:297] beginInternal(): switching host from 'script.google.com' to 'api.openweathermap.org'. disconnecting first [ 7069][D][HTTPClient.cpp:388] disconnect(): still data in buffer (2), clean up. [ 7076][D][HTTPClient.cpp:395] disconnect(): tcp stop [ 7082][V][ssl_client.cpp:324] stop_ssl_socket(): Cleaning SSL connection. [ 7089][D][HTTPClient.cpp:303] beginInternal(): protocol: http, host: api.openweathermap.org port: 80 url: /data/2.5/weather?q=Japan, JP&APPID=***** [ 7103][D][HTTPClient.cpp:598] sendRequest(): request type: 'GET' redirCount: 0 [ 7111][V][ssl_client.cpp:62] start_ssl_client(): Free internal heap before TLS 249408 [ 7118][V][ssl_client.cpp:68] start_ssl_client(): Starting socket [ 7292][V][ssl_client.cpp:149] start_ssl_client(): Seeding the random number generator [ 7293][V][ssl_client.cpp:158] start_ssl_client(): Setting up the SSL/TLS structure... [ 7296][D][ssl_client.cpp:179] start_ssl_client(): WARNING: Skipping SSL Verification. INSECURE! [ 7305][V][ssl_client.cpp:257] start_ssl_client(): Setting hostname for TLS session... [ 7313][V][ssl_client.cpp:272] start_ssl_client(): Performing the SSL/TLS handshake... [ 7498][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29184) SSL - An invalid SSL record was received [ 7498][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29184 [ 7505][V][ssl_client.cpp:324] stop_ssl_socket(): Cleaning SSL connection. [ 7511][D][HTTPClient.cpp:1149] connect(): failed connect to api.openweathermap.org:80 [ 7518][W][HTTPClient.cpp:1469] returnError(): error(-1): connection refused Error on HTTP request [ 7536][D][HTTPClient.cpp:408] disconnect(): tcp is closed [ 7536][V][ssl_client.cpp:324] stop_ssl_socket(): Cleaning SSL connection. [ 7540][V][ssl_client.cpp:324] stop_ssl_socket(): Cleaning SSL connection.

②のシリアルモニターの内容

上略 IP address: 192.168.11.9 [ 2671][V][HTTPClient.cpp:252] beginInternal(): url: http://api.openweathermap.org/data/2.5/weather?q=Japan, JP&APPID=***** [ 2677][D][HTTPClient.cpp:303] beginInternal(): protocol: http, host: api.openweathermap.org port: 80 url: /data/2.5/weather?q=Japan, JP&APPID=***** [ 2692][D][HTTPClient.cpp:598] sendRequest(): request type: 'GET' redirCount: 0 [ 2868][D][HTTPClient.cpp:1156] connect(): connected to api.openweathermap.org:80 [ 3080][V][HTTPClient.cpp:1250] handleHeaderResponse(): RX: 'HTTP/1.1 200 OK' 省略 [ 3172][D][HTTPClient.cpp:628] sendRequest(): sendRequest code=200 [ 3179][D][HTTPClient.cpp:1446] writeToStreamDataBlock(): connection closed or file end (written: 472). [ 3188][D][HTTPClient.cpp:393] disconnect(): tcp keep open for reuse 200 //////天気のデータを取得することはできています {"coord":{"lon":139.7531,"lat":35.6854},"weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02d"}],"base":"stations","main":{"temp":304.2,"feels_like":307.37,"temp_min":302.02,"temp_max":305.38,"pressure":1003,"humidity":57},"visibility":10000,"wind":{"speed":8.23,"deg":200},"clouds":{"all":20},"dt":1660893869,"sys":{"type":2,"id":268395,"country":"JP","sunrise":1660852963,"sunset":1660901225},"timezone":32400,"id":1861060,"name":"Japan","cod":200} [ 3245][D][HTTPClient.cpp:393] disconnect(): tcp keep open for reuse [ 4245][V][HTTPClient.cpp:252] beginInternal(): url: https://script.google.com/macros/s/*****/exec?value=12345 [ 4249][D][HTTPClient.cpp:263] beginInternal(): unexpected protocol: https, expected http [ 4257][V][HTTPClient.cpp:252] beginInternal(): url: https://script.google.com/macros/s/*****/exec?value=12345 [ 4273][D][HTTPClient.cpp:297] beginInternal(): switching host from 'api.openweathermap.org' to 'script.google.com'. disconnecting first [ 4285][D][HTTPClient.cpp:395] disconnect(): tcp stop [ 4291][D][HTTPClient.cpp:303] beginInternal(): protocol: https, host: script.google.com port: 443 url: /macros/s/*****/exec?value=12345 [ 4308][D][HTTPClient.cpp:598] sendRequest(): request type: 'GET' redirCount: 0 [ 4361][D][HTTPClient.cpp:1156] connect(): connected to script.google.com:443 [ 4383][D][WiFiClient.cpp:545] connected(): Disconnected: RES: -1, ERR: 104 [ 4383][D][HTTPClient.cpp:628] sendRequest(): sendRequest code=-5 [ 4384][W][HTTPClient.cpp:1469] returnError(): error(-5): connection lost Error on HTTP request [ 4401][D][HTTPClient.cpp:408] disconnect(): tcp is closed

なぜ、下のように、なってしまうのでしょうか。原因と解決方法をご教授いただければ幸いです。
①の場合

[ 7076][D][HTTPClient.cpp:395] disconnect(): tcp stop [ 7082][V][ssl_client.cpp:324] stop_ssl_socket(): Cleaning SSL connection. [ 7089][D][HTTPClient.cpp:303] beginInternal(): protocol: http, host: api.openweathermap.org port: 80 url: /data/2.5/weather?q=Japan, JP&APPID=***** [ 7103][D][HTTPClient.cpp:598] sendRequest(): request type: 'GET' redirCount: 0

②の場合

[ 4361][D][HTTPClient.cpp:1156] connect(): connected to script.google.com:443 [ 4383][D][WiFiClient.cpp:545] connected(): Disconnected: RES: -1, ERR: 104 [ 4383][D][HTTPClient.cpp:628] sendRequest(): sendRequest code=-5

文字数制限によりシリアルモニターの内容は省略しています。
言葉足らずですがご回答を宜しくお願い致します。

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

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

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

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

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

dodox86

2022/08/19 09:28

確証は無く、思いつきですが、同じHTTPClientのオブジェクト(インスタンス)を使っているせいかもしれません。別の変数に分けてやってみたら状況が変わりませんでしょうか。
Raptor_zip

2022/08/20 01:44 編集

@dodox86さん 成功しました。本当にありがとうございます。 HTTPClient http; //1回目のGETリクエスト http.begin(url1); int httpCode = http.GET(); if (httpCode > 0) { String payload = http.getString(); Serial.println(httpCode); Serial.println(payload); } else { Serial.println("Error on HTTP request"); } http.end(); delay(1000); HTTPClient http2; //2回目のGETリクエスト http2.begin(url2); httpCode = http2.GET(); if (httpCode > 0) { String payload = http.getString(); Serial.println(httpCode); Serial.println(payload); } else { Serial.println("Error on HTTP request"); } http2.end();
guest

回答1

0

自己解決

@dodox86さんより、提案を頂き、同じHTTPClientのオブジェクト(インスタンス)を使っていため、2回目が失敗したことがわかりました。別の変数に分けると、2回目も成功しました。ありがとうございます。

arduino

1#include <HTTPClient.h> 2#include <WiFi.h> 3const String url2 = "https://script.google.com/macros/s/*****/exec?value=12345"; 4const String url1 = "http://api.openweathermap.org/data/2.5/weather?q=Japan, JP&APPID=*****"; 5 6void setup() { 7 Serial.begin(115200); 8 const char *ssid = "Buffalo-G-*****"; ////WiFi_SSID 9 const char *password = "*****"; ////WiFi_パスワード 10 delay(10); 11 Serial.println(); 12 13 // WiFiに接続 14 Serial.print("Connecting to "); 15 Serial.println(ssid); 16 WiFi.begin(ssid, password); 17 while (WiFi.status() != WL_CONNECTED) 18 { 19 delay(500); 20 Serial.print("."); 21 } 22 23 Serial.println(); 24 Serial.println("WiFi connected."); 25 Serial.print("IP address: "); 26 Serial.println(WiFi.localIP()); 27 28 HTTPClient http; 29 //1回目のGETリクエスト 30 http.begin(url1); 31 int httpCode = http.GET(); 32 if (httpCode > 0) { 33 String payload = http.getString(); 34 Serial.println(httpCode); 35 Serial.println(payload); 36 } 37 else { 38 Serial.println("Error on HTTP request"); 39 } 40 http.end(); 41 42 delay(1000); 43 44 HTTPClient http2; 45 46 //2回目のGETリクエスト 47 http2.begin(url2); 48 httpCode = http2.GET(); 49 if (httpCode > 0) { 50 String payload = http.getString(); 51 Serial.println(httpCode); 52 Serial.println(payload); 53 } 54 else { 55 Serial.println("Error on HTTP request"); 56 } 57 http2.end(); 58} 59void loop() {}

投稿2022/08/20 01:32

編集2022/08/20 01:44
Raptor_zip

総合スコア18

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

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

dodox86

2022/08/20 01:42

> 同じHTTPClientのオブジェクト(インスタンス)を使っていため、2回目が失敗したことがわかりました。 ああ、やっぱり。あくまで推測ですが、オブジェクトが破棄されるまでそのオブジェクト中でTCPコネクションの管理をしているのだと思います。 HTTPClientのソースを見ればはっきりしたことが分かるのだと思いますが。 今回の提案のように変数を別にするか、あるいは関数化して常に新規作成するか、new HTTPClient()で構築してdeleteで解放するなどしても同様の結果を得られると思います。 何はともあれ解決してよかったです。あと、どうでもいいですがdodoxではなく、dodox86ですw(ほんとにどうでもいい)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.42%

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

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

質問する

関連した質問