Не могу получить данные из Googlesheet, используя esp32 и Arduinojson - PullRequest
0 голосов
/ 17 февраля 2020

Я новичок в esp32, и теперь я пытаюсь получить данные, используя Arduino Json. В моем googlesheet "A1" есть номер, и я хочу, чтобы esp32 получил его, я отправляю свой googlesheet в inte rnet и используйте URL: https://spreadsheets.google.com/feeds/cells/1RICYSv0y0wEEu-PhcCL45jZmh7DlFSAsbW8Bie0inbA/1/public/values?alt=json&range=A1. и мой номер в объекте> feed> entry> 0> content> $ 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 Ответ

0 голосов
/ 18 февраля 2020

Если я основываюсь на вашем json выводе и вычисляю размер буфера с помощью Arduino Json Assistant , я получаю это:

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 не удался, потому что у вас не хватает 2270 байт в bufferSize (т. Е. Ваш размер bufferSize слишком мал).

Обновление

Я не пытался отлаживать Ваш код, но у меня под рукой есть код моего веб-клиента, поэтому я просто запускаю, и он работает для меня

Мой код основан на HTTPClient, который является частью ESP32 Arduino Core, о чем вы можете прочитать в ESP-Arduino github . Он основан на Arduino WifiClient, который вы использовали, но с гораздо более простым и удобным API, особенно для получения полезной нагрузки ответа. Я бы порекомендовал вам взглянуть.

Я добавляю Arduino Json в свой код, чтобы увидеть, есть ли какие-либо проблемы с синтаксическим анализом полученного json, но мины основаны на синтаксисе v6, вы можете преобразовать его к синтаксису v5, если вы все еще чувствуете, что вам легче использовать v5. Кстати, документ json содержит Unicode, я должен добавить #define ARDUINOJSON_DECODE_UNICODE 1 в верхней части программы в oder, чтобы он работал, в противном случае я получу 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() {

}
...