Не удается получить данные из Googlesheet с помощью esp32 и Arduinojson

Я новичок в esp32, и теперь я пытаюсь получить данные с помощью ArduinoJson. В моем googlesheet "A1" есть номер, и я хочу, чтобы esp32 его получил, я отправляю свой googlesheet в Интернет и использую url:https://spreadsheets.google.com/feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1. и мой номер находится в объект> фид> запись> 0 > контент> $t.

Вот проблема: когда я использую 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

1 ответ

Решение

If I based on your json output and calculate the bufferSize using https://arduinojson.org/v5/assistant/, I get this:

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;

Noticed the + 2270 at the end? Your parsing json failed because your are short of 2270 bytes in bufferSize (i.e. your bufferSize is too small).

Updte

I didn't try to debug your code, but I have my web client code handy with me so I just run and it works for me.

My code is based on HTTPClient which is part of ESP32 Arduino Core that you can further read about it at ESP-Arduino github. It is based on Arduino WifiClient that you used but with much simpler and easy to use API, especially for getting response payload. I would recommend you take a look.

I add ArduinoJson to my code to see if there is any issue on parsing the received json, but mines is based on v6 syntax, you can convert it to v5 syntax if you still feel it is easier for you to use v5. BTW, the json document contains Unicode, I have to add #define ARDUINOJSON_DECODE_UNICODE 1 on the top of the program in oder to make it work, otherwise I will get an 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() {

}
Другие вопросы по тегам