JSONをGET⇒パース⇒値取り出し⇒OLED表示
こんにちは、くろべこです。
さて、今回は実際にWebAPIを活用したIoT電子工作的な事をやってみますよ!
内容はタイトルにもある様にクライアントとしてHTTPサーバーにアクセスしてJSONデータをGETします。そして、GETしたJSONデータを逆シリアル化を行いパースさせて値を取り出します。取り出した値はOLEDに表示するってやつですね!!
まあ、でも前回紹介した【HTTPクライアント】【ArduinoJson】の記事を合体させて、OLEDを追加しただけですけどね(笑)
これが出来ると何が出来るかというと、、、ネット上で公開されている多種多様なデータ(WebAPI)を思うがままに操ることが出来ます。ワクワクしてきませんか!?
用意するものはESP8266とOLED(SSD1306)だけなので2000円いかないくらいで揃えられると思います。基本的にアマゾンで揃えられるので、持っていない方はポチって見てはいかがでしょうか?
コードの紹介と解説
(注)本コードではバージョン6のArduinoJsonを使用しています。バージョン違いの場合動かない可能性がありますのでご注意ください。
コード構成
- ヘッダファイル/定数/変数定義
- シリアル通信設定
- WiFi通信設定(ステーションモード)
- OLEDイニシャライズ
- HttpClientで指定WebAPI(HTTPS)からJSONデータGETリクエスト
- JSONの逆シリアル化&文字抽出
- OLEDに値表示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
#include <Arduino.h> #include <ESP8266WiFi.h> #include <ArduinoJson.h> #include <ESP8266HTTPClient.h> #include <WiFiClientSecureBearSSL.h> #include <Wire.h> #include <ACROBOTIC_SSD1306.h> #ifndef STASSID #define STASSID "65661981-2.4G" #define STAPSK "28544552" #endif const char* ssid = STASSID; const char* password = STAPSK; IPAddress ip; // Fingerprint for demo URL, expires on June 2, 2021, needs to be updated well before this date const uint8_t fingerprint[20] = {0xd2,0xb8,0xf1,0x80,0xac,0x29,0x63,0xf8,0x22,0xaa,0x9e,0x99,0x4d,0x73,0x7b,0x59,0x3b,0x92,0xb4,0xe8}; const String url = "https://covid19-japan-web-api.now.sh/api/v1/total"; static String payload; void setup() { Serial.begin(115200); // We start by connecting to a WiFi network Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); ip=WiFi.localIP(); Serial.println(ip); //OLED start Wire.begin(); oled.init(); // Initialze SSD1306 OLED display oled.clearDisplay(); // Clear screen oled.setTextXY(0,0); // Set cursor position, start of line 0 oled.putString("HttpClirnt_Start"); delay(3000); oled.clearDisplay(); // Clear screen } void loop() { HttpClientGet(url); JsonParsing(payload); Serial.println("Wait 10s before next round..."); delay(3000); } void HttpClientGet(String url){ std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure); client->setFingerprint(fingerprint); HTTPClient https; Serial.print("[HTTPS] begin...\n"); if (https.begin(*client, url)) { // HTTPS Serial.print("[HTTPS] GET...\n"); // start connection and send HTTP header int httpCode = https.GET(); // httpCode will be negative on error if (httpCode > 0) { // HTTP header has been send and Server response header has been handled Serial.printf("[HTTPS] GET... code: %d\n", httpCode); // file found at server if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { payload = https.getString(); Serial.println(payload); } } else { Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str()); } https.end(); } else { Serial.printf("[HTTPS] Unable to connect\n"); } } void JsonParsing(String json){ // Allocate the JSON document // Use arduinojson.org/v6/assistant to compute the capacity. const size_t capacity = JSON_OBJECT_SIZE(13) + 130; DynamicJsonDocument doc(capacity); // Parse JSON object DeserializationError error = deserializeJson(doc, json); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.c_str()); return; } long date = doc["date"]; // 日付 long pcr = doc["pcr"]; // PCR検査者 int positive = doc["positive"]; // 陽性 int symptom = doc["symptom"]; // 症状あり int symptomless = doc["symptomless"]; // 無症状 int symptomConfirming = doc["symptomConfirming"]; // 症状確認中 int hospitalize = doc["hospitalize"]; // 入院 int mild = doc["mild"]; // 軽度 int severe = doc["severe"]; // 重度 int confirming = doc["confirming"]; // 確認中 int waiting = doc["waiting"]; // 待機中 int discharge = doc["discharge"]; // 復帰 int death = doc["death"]; // 死亡 char buf[50];//文字列変換用 // Extract values Serial.println(F("Response:")); sprintf(buf,"日付:%ld",date); Serial.println(buf); sprintf(buf,"PCR検査者合計:%ld",pcr); Serial.println(buf); sprintf(buf,"陽性:%d",positive); Serial.println(buf); sprintf(buf,"症状あり:%d",symptom); Serial.println(buf); sprintf(buf,"無症状:%d",symptomless); Serial.println(buf); sprintf(buf,"症状確認:%d",symptomConfirming); Serial.println(buf); sprintf(buf,"入院:%d",hospitalize); Serial.println(buf); sprintf(buf,"軽度:%d",mild); Serial.println(buf); sprintf(buf,"重度:%d",severe); Serial.println(buf); sprintf(buf,"確認中:%d",confirming); Serial.println(buf); sprintf(buf,"待機中:%d",waiting); Serial.println(buf); sprintf(buf,"退院:%d",discharge); Serial.println(buf); sprintf(buf,"死亡:%d",death); Serial.println(buf); oled.setTextXY(0,0); oled.putString("date:"); oled.setTextXY(0,5); oled.putString((String)date); oled.setTextXY(1,0); oled.putString("pcr:"); oled.setTextXY(1,4); oled.putString((String)pcr); oled.setTextXY(2,0); oled.putString("positive:"); oled.setTextXY(2,9); oled.putString((String)positive); oled.setTextXY(3,0); oled.putString("symptom:"); oled.setTextXY(3,8); oled.putString((String)symptom); oled.setTextXY(4,0); oled.putString("silent:"); oled.setTextXY(4,7); oled.putString((String)symptomless); oled.setTextXY(5,0); oled.putString("confirming:"); oled.setTextXY(5,11); oled.putString((String)symptomConfirming); oled.setTextXY(6,0); oled.putString("hospital:"); oled.setTextXY(6,9); oled.putString((String)hospitalize); delay(3000); oled.clearDisplay(); // Clear screen oled.setTextXY(0,0); oled.putString("mild:"); oled.setTextXY(0,5); oled.putString((String)mild); oled.setTextXY(1,0); oled.putString("severe:"); oled.setTextXY(1,7); oled.putString((String)severe); oled.setTextXY(2,0); oled.putString("confirming:"); oled.setTextXY(2,11); oled.putString((String)confirming); oled.setTextXY(3,0); oled.putString("discharge:"); oled.setTextXY(3,10); oled.putString((String)discharge); oled.setTextXY(4,0); oled.putString("death:"); oled.setTextXY(4,6); oled.putString((String)death); } |
いやー、ずらずらと書いていますがJSONデータの値抽出とOLEDへの描画コードでだいぶ容量を食ってしまいました、、、
ESPに接続するOLEDは以下のような配線をしてみてください。
コードの書き込みが終了しましたら、シリアルモニタを開きまして正常にWiFiに接続してHTTPをGET出来ているか確認してみてください。正常にGET出来ている場合は【code: 200】が返ってきます。もしエラーがある場合はエラーコードが返ってくるので、以下のコード表から何のエラーか確認してみてください。エラーの場合は負数が返ってくるようです。
<<シリアルモニタ>>
JSON逆シリアル化&OLED表示
そして、JSONデータをGET出来ましたら、deserializeJson(doc, json)でJSONデータをオブジェクトデータに逆シリアル化します。
そして、逆シリアル化されたJSONオブジェクトから値を取り出すためにはキーを指定して取り出す感じです。たとえば、long date = doc[“date”]こんなかんじ。
このように値抽出をひたすらやって、OLEDに表示させると以下のようになります。
いかがでしょうか、WebAPIをOLEDに表示させることが出来ました。
これが出来たので、あとはお好みのAPIを使っていろんなことが出来ますね!!
では、今回はこんなところで!
コメント