使用 WiFiNINA 获取 JSON 数据的问题
Issue with WiFiNINA to get JSON data
我正在尝试使用 Arduino nano 33 IoT 向我的天气预报 API 服务发出 GET 请求,但我无法解析 JSON 数据,因为代码还会输出内部的其他信息字符串,有没有办法只用 JSON 数据“清理”字符串?
这是我的代码
#include <ArduinoJson.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key index number (needed only for WEP)
int status = WL_IDLE_STATUS;
char server[] = "api.weatherapi.com"; // name address for Google (using DNS)
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to WiFi");
printWifiStatus();
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected to server");
// Make a HTTP request:
client.println("GET /v1/forecast.json?key=9c5df5870ht454gsd0fdd8194739211006&q=Rimini&days=2&aqi=no&alerts=no HTTP/1.0");
client.println("Host: api.weatherapi.com");
client.println("Connection: close");
client.println();
}
}
void loop() {
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
String payload = client.readString();
Serial.println(payload);
DynamicJsonDocument doc(4000);
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
client.stop();
return;
}
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting from server.");
client.stop();
// do nothing forevermore:
while (true);
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
输出:
Starting connection to server...
connected to server
HTTP/1.1 200 OK
Date: Wed, 14 Jul 2021 16:58:42 GMT
Content-Type: application/json
Connection: close
Vary: Accept-Encoding
Server: BunnyCDN-IT1-555
CDN-PullZone: 93447
CDN-Uid: 8fa3a04a-75d9-4707-8056-b7b33c8ac7fe
CDN-RequestCountryCode: IT
CDN-EdgeStorageId: 555
CDN-CachedAt: 2021-07-14 18:58:42
CDN-RequestPullSuccess: True
CDN-RequestPullCode: 200
Cache-Control: public, max-age=180
CDN-RequestId: d6bc580dc2a234693a1ad59cb34aabcb
CDN-Cache: EXPIRED
{"location":{"name":"Rimini","region":"Emilia-Romagna","country":"Italy","lat":44.06,"lon":12.58,"tz_id":"Europe/Rome","localtime_epoch":1626281922,"localtime":"2021-07-14 18:58"},"current":{"condition":{},"uv":7.0},"forecast":{"forecastday":[{"date":"2021-07-14","day":{"daily_will_it_rain":0,"daily_chance_of_rain":"67","daily_will_it_snow":0,"daily_chance_of_snow":"0","condition":{}},"astro":{},"hour":[{"condition":{},"chance_of_rain":"45"},{"condition":{},"chance_of_rain":"67"},{"condition":{},"chance_of_rain":"45"},{"condition":{},"chance_of_rain":"22"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"29"},{"condition":{},"chance_of_rain":"58"},{"condition":{},"chance_of_rain":"87"},{"condition":{},"chance_of_rain":"84"},{"condition":{},"chance_of_rain":"81"},{"condition":{},"chance_of_rain":"78"},{"condition":{},"chance_of_rain":"52"},{"condition":{},"chance_of_rain":"26"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"}]},{"date":"2021-07-15","day":{"daily_will_it_rain":0,"daily_chance_of_rain":"0","daily_will_it_snow":0,"daily_chance_of_snow":"0","condition":{}},"astro":{},"hour":[{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"}]}]}}
deserializeJson() failed: InvalidInput
disconnecting from server.
字符串“payload”从'HTTP/1.1 200 OK'开始,它应该从'{"location"....'开始
感谢所有帮助我的人。
一个简单的解决方案是修改字符串。
查看 Arduino documentation for String,您似乎有几个可用的函数可以帮助解决这个问题。
例如,您可以使用 indexOf
、lastIndexOf
和 substring
获取第一个“{”和最后一个“}”之间的所有内容:
int start = payload.indexOf('{');
int end = payload.lastIndexOf('}');
String body = payload.substring(start, end + 1);
这不一定是最可靠的解决方案(例如,您应该检查“{”和“}”是否可能出现在 HTTP header 中),但这应该会给您一些提示一个解法。再一次,如果这是一个小项目,这可能足以满足您的用例。
或者,您可以根据换行符剪切字符串:
int start = payload.indexOf('\n');
int body = payload.substring(start + 1);
同样,这对负载格式做出了假设,您可能希望进行一些测试来验证这些假设。
(我无法测试此代码,因此您可能需要调试并进行更正。)
我正在尝试使用 Arduino nano 33 IoT 向我的天气预报 API 服务发出 GET 请求,但我无法解析 JSON 数据,因为代码还会输出内部的其他信息字符串,有没有办法只用 JSON 数据“清理”字符串? 这是我的代码
#include <ArduinoJson.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key index number (needed only for WEP)
int status = WL_IDLE_STATUS;
char server[] = "api.weatherapi.com"; // name address for Google (using DNS)
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to WiFi");
printWifiStatus();
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected to server");
// Make a HTTP request:
client.println("GET /v1/forecast.json?key=9c5df5870ht454gsd0fdd8194739211006&q=Rimini&days=2&aqi=no&alerts=no HTTP/1.0");
client.println("Host: api.weatherapi.com");
client.println("Connection: close");
client.println();
}
}
void loop() {
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
String payload = client.readString();
Serial.println(payload);
DynamicJsonDocument doc(4000);
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
client.stop();
return;
}
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting from server.");
client.stop();
// do nothing forevermore:
while (true);
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
输出:
Starting connection to server...
connected to server
HTTP/1.1 200 OK
Date: Wed, 14 Jul 2021 16:58:42 GMT
Content-Type: application/json
Connection: close
Vary: Accept-Encoding
Server: BunnyCDN-IT1-555
CDN-PullZone: 93447
CDN-Uid: 8fa3a04a-75d9-4707-8056-b7b33c8ac7fe
CDN-RequestCountryCode: IT
CDN-EdgeStorageId: 555
CDN-CachedAt: 2021-07-14 18:58:42
CDN-RequestPullSuccess: True
CDN-RequestPullCode: 200
Cache-Control: public, max-age=180
CDN-RequestId: d6bc580dc2a234693a1ad59cb34aabcb
CDN-Cache: EXPIRED
{"location":{"name":"Rimini","region":"Emilia-Romagna","country":"Italy","lat":44.06,"lon":12.58,"tz_id":"Europe/Rome","localtime_epoch":1626281922,"localtime":"2021-07-14 18:58"},"current":{"condition":{},"uv":7.0},"forecast":{"forecastday":[{"date":"2021-07-14","day":{"daily_will_it_rain":0,"daily_chance_of_rain":"67","daily_will_it_snow":0,"daily_chance_of_snow":"0","condition":{}},"astro":{},"hour":[{"condition":{},"chance_of_rain":"45"},{"condition":{},"chance_of_rain":"67"},{"condition":{},"chance_of_rain":"45"},{"condition":{},"chance_of_rain":"22"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"29"},{"condition":{},"chance_of_rain":"58"},{"condition":{},"chance_of_rain":"87"},{"condition":{},"chance_of_rain":"84"},{"condition":{},"chance_of_rain":"81"},{"condition":{},"chance_of_rain":"78"},{"condition":{},"chance_of_rain":"52"},{"condition":{},"chance_of_rain":"26"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"}]},{"date":"2021-07-15","day":{"daily_will_it_rain":0,"daily_chance_of_rain":"0","daily_will_it_snow":0,"daily_chance_of_snow":"0","condition":{}},"astro":{},"hour":[{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"},{"condition":{},"chance_of_rain":"0"}]}]}}
deserializeJson() failed: InvalidInput
disconnecting from server.
字符串“payload”从'HTTP/1.1 200 OK'开始,它应该从'{"location"....'开始 感谢所有帮助我的人。
一个简单的解决方案是修改字符串。
查看 Arduino documentation for String,您似乎有几个可用的函数可以帮助解决这个问题。
例如,您可以使用 indexOf
、lastIndexOf
和 substring
获取第一个“{”和最后一个“}”之间的所有内容:
int start = payload.indexOf('{');
int end = payload.lastIndexOf('}');
String body = payload.substring(start, end + 1);
这不一定是最可靠的解决方案(例如,您应该检查“{”和“}”是否可能出现在 HTTP header 中),但这应该会给您一些提示一个解法。再一次,如果这是一个小项目,这可能足以满足您的用例。
或者,您可以根据换行符剪切字符串:
int start = payload.indexOf('\n');
int body = payload.substring(start + 1);
同样,这对负载格式做出了假设,您可能希望进行一些测试来验证这些假设。
(我无法测试此代码,因此您可能需要调试并进行更正。)