使用 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,您似乎有几个可用的函数可以帮助解决这个问题。

例如,您可以使用 indexOflastIndexOfsubstring 获取第一个“{”和最后一个“}”之间的所有内容:

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);

同样,这对负载格式做出了假设,您可能希望进行一些测试来验证这些假设。

(我无法测试此代码,因此您可能需要调试并进行更正。)