无法使用 esp32 和 Arduinojson 从 Googlesheet 获取数据
Can't get data from Googlesheet using esp32 and Arduinojson
我是 esp32 的新手,现在我正在尝试使用 ArduinoJson 获取数据,
在我的 googlesheet "A1" 中有一个数字,我想让 esp32 得到它,
我将我的 googlesheet 发送到互联网并使用 url:https://spreadsheets.google.com/feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1。
我的号码在 object > feed > entry > 0 > content > $t.
这是一个 problem:When 我用 esp32 来获取这个 json 数据,我无法获取它,即使我的 esp32 连接到 googlesheet
如果您需要,这是我的完整代码:
#include <ArduinoJson.h>
#include <WiFi.h>
#include <SPI.h>
WiFiClient client;
const char* ssid = "wwwwwwwww";
const char* password = "wwwwwwww";
const char* server = "spreadsheets.google.com";
const char* resource = "/feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1";
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 1024; // max size of the HTTP response
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
struct clientData {
char item[8];
};
void setup() {
Serial.begin(9600);
while (!Serial) {
}
Serial.println("Serial ready");
Serial.print("Connecting to wifi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
if(connect(server)) {
if(sendRequest(server, resource) && skipResponseHeaders()) {
clientData clientData;
if(readReponseContent(&clientData)) {
printclientData(&clientData);
}
}
}
disconnect();
wait();
}
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;
}
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(host);
client.println("Connection: close");
client.println();
return true;
}
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;
}
bool readReponseContent(struct clientData* clientData) {
const size_t bufferSize = 5*JSON_ARRAY_SIZE(1) +
JSON_ARRAY_SIZE(5) + 10*JSON_OBJECT_SIZE(1) +
6*JSON_OBJECT_SIZE(2) + 7*JSON_OBJECT_SIZE(3) +
JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(15);
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
strcpy(clientData->item, root["feed"]["entry"][0]["content"]["$t"]);
return true;
}
void printclientData(const struct clientData* clientData) {
Serial.print("Time = ");
Serial.println(clientData->item);
}
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
void wait() {
Serial.println("Wait 20 seconds");
delay(20000);
}
串行输出:
Connecting to wifi: wwwwwwwwww
..
WiFi connected
IP address:
xxx.xxx.x.xx
Connect to spreadsheets.google.com
Connected
GET /feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1
JSON parsing failed!
Disconnect
Wait 20 seconds
如果我根据您的 json 输出并使用 ArduinoJson Assistant 计算 bufferSize,我得到:
const size_t capacity = 5*JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(5) + 10*JSON_OBJECT_SIZE(1) + 6*JSON_OBJECT_SIZE(2) + 7*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(15) + 2270;
注意到最后的 + 2270
了吗?您的解析 json 失败,因为您的 bufferSize 中缺少 2270 字节(即您的 bufferSize 太小)。
更新
我没有尝试调试您的代码,但我手边有网络客户端代码,所以我 运行 它对我有用。
我的代码基于 HTTPClient,它是 ESP32 Arduino Core 的一部分,您可以在 ESP-Arduino github 进一步了解它。它基于您使用的 Arduino WifiClient,但更简单易用 API,尤其是在获取响应负载方面。我建议你看看。
我把ArduinoJson添加到我的代码中,看看是否有解析接收到的问题json,但是我的是基于v6语法,如果你仍然觉得它更容易,你可以将它转换为v5语法供您使用 v5。顺便说一句,json 文档包含 Unicode,我必须在程序顶部添加 #define ARDUINOJSON_DECODE_UNICODE 1
才能使其正常工作,否则我会得到一个 deserialization error: NotSupported
.
#define ARDUINOJSON_DECODE_UNICODE 1
#include <ArduinoJson.h>
#include <WiFi.h>
#include <HTTPClient.h>
HTTPClient http;
const char* ssid = "your_SSID";
const char* password = "your_password";
const char* url = "https://spreadsheets.google.com/feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1";
void setup() {
Serial.begin(115200);
while (!Serial) {}
Serial.print("Connecting to wifi: "); Serial.print(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print(".");
}
Serial.println();
Serial.print("IP address: "); Serial.println(WiFi.localIP());
http.begin(url);
int httpCode = http.GET(); //send GET request
if (httpCode != 200) {
Serial.print("Error on HTTP request: ");
Serial.println(httpCode);
} else {
String payload = http.getString();
Serial.println(payload);
// the following is based on ArduinoJson v6 API
StaticJsonDocument<4000> doc;
DeserializationError err = deserializeJson(doc, payload);
if (err) {
Serial.print("deserialization error ");
Serial.println(err.c_str());
}
JsonObject feed = doc["feed"];
const char* clientData = feed["entry"][0]["content"]["$t"];
Serial.println(clientData);
}
http.end(); //Free the resources
}
void loop() {
}
我是 esp32 的新手,现在我正在尝试使用 ArduinoJson 获取数据, 在我的 googlesheet "A1" 中有一个数字,我想让 esp32 得到它, 我将我的 googlesheet 发送到互联网并使用 url:https://spreadsheets.google.com/feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1。 我的号码在 object > feed > entry > 0 > content > $t.
这是一个 problem:When 我用 esp32 来获取这个 json 数据,我无法获取它,即使我的 esp32 连接到 googlesheet
如果您需要,这是我的完整代码:
#include <ArduinoJson.h>
#include <WiFi.h>
#include <SPI.h>
WiFiClient client;
const char* ssid = "wwwwwwwww";
const char* password = "wwwwwwww";
const char* server = "spreadsheets.google.com";
const char* resource = "/feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1";
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 1024; // max size of the HTTP response
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
struct clientData {
char item[8];
};
void setup() {
Serial.begin(9600);
while (!Serial) {
}
Serial.println("Serial ready");
Serial.print("Connecting to wifi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
if(connect(server)) {
if(sendRequest(server, resource) && skipResponseHeaders()) {
clientData clientData;
if(readReponseContent(&clientData)) {
printclientData(&clientData);
}
}
}
disconnect();
wait();
}
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;
}
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(host);
client.println("Connection: close");
client.println();
return true;
}
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;
}
bool readReponseContent(struct clientData* clientData) {
const size_t bufferSize = 5*JSON_ARRAY_SIZE(1) +
JSON_ARRAY_SIZE(5) + 10*JSON_OBJECT_SIZE(1) +
6*JSON_OBJECT_SIZE(2) + 7*JSON_OBJECT_SIZE(3) +
JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(15);
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
strcpy(clientData->item, root["feed"]["entry"][0]["content"]["$t"]);
return true;
}
void printclientData(const struct clientData* clientData) {
Serial.print("Time = ");
Serial.println(clientData->item);
}
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
void wait() {
Serial.println("Wait 20 seconds");
delay(20000);
}
串行输出:
Connecting to wifi: wwwwwwwwww
..
WiFi connected
IP address:
xxx.xxx.x.xx
Connect to spreadsheets.google.com
Connected
GET /feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1
JSON parsing failed!
Disconnect
Wait 20 seconds
如果我根据您的 json 输出并使用 ArduinoJson Assistant 计算 bufferSize,我得到:
const size_t capacity = 5*JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(5) + 10*JSON_OBJECT_SIZE(1) + 6*JSON_OBJECT_SIZE(2) + 7*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(15) + 2270;
注意到最后的 + 2270
了吗?您的解析 json 失败,因为您的 bufferSize 中缺少 2270 字节(即您的 bufferSize 太小)。
更新
我没有尝试调试您的代码,但我手边有网络客户端代码,所以我 运行 它对我有用。
我的代码基于 HTTPClient,它是 ESP32 Arduino Core 的一部分,您可以在 ESP-Arduino github 进一步了解它。它基于您使用的 Arduino WifiClient,但更简单易用 API,尤其是在获取响应负载方面。我建议你看看。
我把ArduinoJson添加到我的代码中,看看是否有解析接收到的问题json,但是我的是基于v6语法,如果你仍然觉得它更容易,你可以将它转换为v5语法供您使用 v5。顺便说一句,json 文档包含 Unicode,我必须在程序顶部添加 #define ARDUINOJSON_DECODE_UNICODE 1
才能使其正常工作,否则我会得到一个 deserialization error: NotSupported
.
#define ARDUINOJSON_DECODE_UNICODE 1
#include <ArduinoJson.h>
#include <WiFi.h>
#include <HTTPClient.h>
HTTPClient http;
const char* ssid = "your_SSID";
const char* password = "your_password";
const char* url = "https://spreadsheets.google.com/feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1";
void setup() {
Serial.begin(115200);
while (!Serial) {}
Serial.print("Connecting to wifi: "); Serial.print(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print(".");
}
Serial.println();
Serial.print("IP address: "); Serial.println(WiFi.localIP());
http.begin(url);
int httpCode = http.GET(); //send GET request
if (httpCode != 200) {
Serial.print("Error on HTTP request: ");
Serial.println(httpCode);
} else {
String payload = http.getString();
Serial.println(payload);
// the following is based on ArduinoJson v6 API
StaticJsonDocument<4000> doc;
DeserializationError err = deserializeJson(doc, payload);
if (err) {
Serial.print("deserialization error ");
Serial.println(err.c_str());
}
JsonObject feed = doc["feed"];
const char* clientData = feed["entry"][0]["content"]["$t"];
Serial.println(clientData);
}
http.end(); //Free the resources
}
void loop() {
}