HI我试图通过此网址使用Benoit Blanchon 2014-2016的Json图书馆https://github.com/bblanchon/ArduinoJson
我开始挣扎,因为我有第二代以太网屏蔽。一旦我意识到我需要第二个以太网库,就明白了。但是我得到的错误消息无法解析json,我不确定为什么,以及如何调试。
// Sample Arduino Json Web Client
// Downloads and parse http://api.sunrise-sunset.org/json?lat=53.440&lng=0.200&date=today
//
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include <ArduinoJson.h>
#include <SPI.h>
#include <Ethernet.h>
EthernetClient client;
const char* server = "api.sunrise-sunset.org"; // server's address
const char* resource = "/json?lat=53.440&lng=0.200&date=today"; // http resource
const unsigned long BAUD_RATE = 9600; // serial connection speed
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
// The type of data that we want to extract from the page
struct UserData {
char sunrise[32];
char sunset[32];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
// initSerial();
// initEthernet();
Serial.begin(9600);
Serial.println("Serial ready");
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = { 192,168,0,202 };
Ethernet.begin(mac, ip);
Serial.println("Ethernet ready");
delay(1000);
}
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if (connect(server)) {
if (sendRequest(server, resource) && skipResponseHeaders()) {
char response[MAX_CONTENT_SIZE];
readReponseContent(response, sizeof(response));
UserData userData;
if (parseUserData(response, &userData)) {
printUserData(&userData);
}
}
disconnect();
}
wait();
}
// Initialize Serial port
void initSerial() {
Serial.begin(BAUD_RATE);
while (!Serial) {
; // wait for serial port to initialize
}
Serial.println("Serial ready");
}
// Initialize Ethernet library
void initEthernet() {
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
if (!Ethernet.begin(mac)) {
Serial.println("Failed to configure Ethernet");
return;
}
Serial.println("Ethernet ready");
delay(1000);
}
// Open connection to the HTTP server
bool connect(const char* hostName) {
Serial.print("Connect to ");
Serial.println(hostName);
bool ok = client.connect(hostName, 80);
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
// Send the HTTP GET request to the server
bool sendRequest(const char* host, const char* resource) {
Serial.print("GET ");
Serial.println(resource);
client.print("GET ");
client.print(resource);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Connection: close");
client.println();
return true;
}
// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
}
return ok;
}
// Read the body of the response from the HTTP server
void readReponseContent(char* content, size_t maxSize) {
size_t length = client.readBytes(content, maxSize);
content[length] = 0;
Serial.println(content);
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
//{
// "results":{
// "sunrise":"5:45:00 AM",
// "sunset":"5:58:51 PM",
// "solar_noon":"11:51:55 AM",
// "day_length":"12:13:51",
// "civil_twilight_begin":"5:10:15 AM",
// "civil_twilight_end":"6:33:36 PM",
// "nautical_twilight_begin":"4:28:54 AM",
// "nautical_twilight_end":"7:14:57 PM",
// "astronomical_twilight_begin":"3:45:29 AM",
// "astronomical_twilight_end":"7:58:22 PM"
// },
// "status":"OK"
//}
bool parseUserData(char* content, struct UserData* userData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// This is only required if you use StaticJsonBuffer.
const size_t BUFFER_SIZE =
JSON_OBJECT_SIZE(2) // the root object has 2 elements
+ JSON_OBJECT_SIZE(10); // the "result" object has 10 elements
// Allocate a temporary memory pool on the stack
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
// If the memory pool is too big for the stack, use this instead:
// DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(content);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// Here were copy the strings we're interested in
strcpy(userData->sunrise, root["results"]["sunrise"]);
strcpy(userData->sunset, root["results"]["sunset"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
return true;
}
// Print the data extracted from the JSON
void printUserData(const struct UserData* userData) {
Serial.print("Name = ");
Serial.println(userData->sunrise);
Serial.print("Company = ");
Serial.println(userData->sunset);
}
// Close the connection with the HTTP server
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
// Pause for a 1 minute
void wait() {
Serial.println("Wait 60 seconds");
delay(60000);
}
答案 0 :(得分:0)
JSON字符串前面有161
,因为服务器正在使用Chunked transfer encoding。
这是HTTP 1.1规范的一个特性,禁用它的唯一方法是在请求中使用HTTP 1.0。
请参阅:
response
缓冲区。