Не могу прочитать данные json esp 32 ошибка «parseObject() failed»
привет, я просто пытаюсь сделать счетчик подписки на Youtube со светодиодной матрицей 32 * 8 и esp 32, и у меня возникла эта проблема, когда я пытался получить подписчиков для подсчета так в чем проблема и как я могу это исправить? `
``` //######################## Отображение счетчика подписчиков YouTube на светодиодной матрице ######## ######################
// Получает и отображает статистику канала YouTube
//################# БИБЛИОТЕКИ #################
String version = "v1.0"; // Версия этой программы
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h> // https://github.com/markruys/arduino-Max72xxPanel
#include <time.h>
//################ ПЕРЕМЕННЫЕ #################
// Используйте свой собственный ключ API, зарегистрировав бесплатную учетную запись разработчика Youtube на http://www.youtube.com
// Вывод светодиодной матрицы -> Пин ESP32
// Вкк-> 3в
// Земля -> Земля
// ДИН-> Пин MOSI может использовать результаты оператора печати 23
// КС-> SS pin использовать результаты оператора печати 5, возможно
// CLK-> Может быть, вывод SCK использует результаты оператора печати 18.
const char* channelId = "UCqTSLaEj9c4hiZkU0FfbaJA"; // Посмотрите информацию о вашем канале, нажмите на значок своего канала в правом верхнем углу, затем «Настройки», затем «Дополнительно»
const char* apiKey = "A--------------Aw"; // См. https://developers.google.com/youtube/v3/getting-started для ключа API, вы должны включить его, чтобы он работал!
const char* host = "https://www.googleapis.com";
unsigned long lastConnectionTime = 0; // Время последнего подключения к серверу в миллисекундах
const unsigned long postingInterval = 10L*60L*1000L; // Задержка между обновлениями в миллисекундах, вы должны ограничить количество запросов YouTube в день максимум
//################ ПРОГРАММНЫЕ ПЕРЕМЕННЫЕ и ОБЪЕКТЫ #################
int pinCS = 5; // Прикрепите CS к этому контакту, DIN к MOSI и CLK к SCK (см. http://arduino.cc/en/Reference/SPI)
int numberOfHorizontalDisplays = 4;
int numberOfVerticalDisplays = 1;
int wait = 35; // В миллисекундах
int spacer = 1;
int width = 5 + spacer; // Ширина шрифта 5 пикселей
int port = 443;
String time_str;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);
struct channelStatistics{
long viewCount;
long commentCount;
long subscriberCount;
bool hiddenSubscriberCount;
long videoCount;
};
// Измените свои учетные данные WiFi
const char* ssid = "SSid";
const char* password = "PASS";
channelStatistics channelStats;
void setup() {
Serial.begin(115200); // инициализируем последовательную связь
Serial.println("Mosi="+String(MOSI));
Serial.println("SS="+String(SS));
Serial.println("SCK="+String(SCK));
StartWiFi(ssid,password);
StartTime();
//------------------------------------------------ ----------------------
configTime(0 * 3600, 0, "pool.ntp.org", "time.nist.gov");
matrix.setIntensity(0); // Используйте значение от 0 до 15 для яркости
// Настройте светодиодную матрицу под свои нужды
// matrix.setPosition(0, 0, 0); // Первый дисплей находится в позиции <0, 0>
// matrix.setPosition(1, 1, 0); // Второй дисплей находится в позиции <1, 0>
// matrix.setPosition(2, 2, 0); // Третий дисплей находится в позиции <2, 0>
// matrix.setPosition(3, 3, 0); // И последний дисплей находится в позиции <3, 0>
// ...
matrix.setRotation(0, 1); // Первый дисплей - позиция повернута
matrix.setRotation(1, 1); // Первый дисплей - позиция повернута
matrix.setRotation(2, 1); // Первый дисплей - позиция повернута
matrix.setRotation(3, 1); // Первый дисплей - позиция повернута
lastConnectionTime = millis();
obtain_subscriber_stats();
}
void loop() {
display_message("Subs: " + String(channelStats.subscriberCount));
time_t now = time(nullptr);
String time = String(ctime(&now));
time.trim();
display_message(" on " + time);
if (millis() - lastConnectionTime > postingInterval) { // 15 минут
obtain_subscriber_stats();
lastConnectionTime = millis();
}
}
//################ ФУНКЦИИ ПРОГРАММЫ #################
void display_message(String message){ // Прокручиваем изображение влево
matrix.fillScreen(LOW);
for ( int i = 0 ; i < width * message.length() + matrix.width() - 1 - spacer; i++ ) {
int letter = i / width;
int x = (matrix.width() - 1) - i % width;
int y = (matrix.height() - 8) / 2; // центрируем текст по вертикали
while ( x + width - spacer >= 0 && letter >= 0 ) {
if (letter < message.length()) matrix.drawChar(x, y, message[letter], HIGH, LOW, 1); // ВЫСОКИЙ означает, что передний план включен, НИЗКИЙ означает, что фон выключен, НИЗКИЙ< HIGH инвертирует дисплей
letter--;
x -= width;
}
matrix.write(); // Отправляем растровое изображение для отображения
delay(wait);
}
}
void obtain_subscriber_stats() {
String command = "https://www.googleapis.com/youtube/v3/channels?part=statistics&id=" + строка (идентификатор канала);
String response = GetRequestFromYoutube(command);
StaticJsonBuffer <200> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(response); // Разбираем JSON
if (!root.success()) {
Serial.println(F("jsonBuffer.parseObject() failed"));
}
else
{
JsonObject& current = root["items"][0]["statistics"];
long subscriberCount = current["subscriberCount"];
long viewCount = current["viewCount"];
long commentCount = current["commentCount"];
long hiddenSubscriberCount = current["hiddenSubscriberCount"];
long videoCount = current["videoCount"];
channelStats.viewCount = viewCount;
channelStats.subscriberCount = subscriberCount;
channelStats.commentCount = commentCount;
channelStats.hiddenSubscriberCount = hiddenSubscriberCount;
channelStats.videoCount = videoCount;
}
Serial.println(" View Count = " + String(channelStats.viewCount));
Serial.println("Subscriber Count = " + String(channelStats.subscriberCount));
Serial.println(GetRequestFromYoutube(command));
Serial.println(response);
// Serial.println(jsonBuffer.parseObject(ответ));
}
String GetRequestFromYoutube(String request) {
String headers, body = "";
bool Headers = false;
bool currentLineIsBlank = true;
int MessageLength = 1000;
// Соединяемся с youtube API через ssl
WiFiClientSecure client;
if (client.connect(host, port)) {
Serial.println(".... connected to server");
char c;
int ch_count=0;
request += "&key=" + String(apiKey);
request = "GET " + request;
Serial.println(request);
client.println(request);
int now = millis();
while (millis()-now < 1500) {
while (client.available()) {
char c = client.read();
if(!Headers){
if (currentLineIsBlank && c == '\n') {
Headers = true;
}
else{
headers = headers + c;
}
} else {
if (ch_count < MessageLength) {
body = body+c;
ch_count++;
}
}
if (c == '\n') {
currentLineIsBlank = true;
} else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
}
return body;
}
////////////// Wi-Fi, функции времени и даты //////////////////
int StartWiFi(const char* ssid, const char* password) {
int connAttempts = 0;
Serial.print(F("\r\nConnecting to: ")); Serial.println(String(ssid));
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED ) {
delay(500); Serial.print(".");
if (connAttempts > 20) {
Serial.println("\nFailed to connect to a Wi-Fi network");
return -5;
}
connAttempts++;
}
Serial.print(F("WiFi connected at: "));
Serial.println(WiFi.localIP());
return 1;
}
void StartTime(){
configTime(0, 0, "0.uk.pool.ntp.org", "time.nist.gov");
setenv("TZ", "GMT0BST,M3.5.0/01,M10.5.0/02",1); // Изменить для вашего местоположения
UpdateLocalTime();
}
void UpdateLocalTime(){
struct tm timeinfo;
while (!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
}
//См. http://www.cplusplus.com/reference/ctime/strftime/
Serial.println(&timeinfo, "%a %b %d %Y %H:%M:%S"); // Отображает: суббота, 24 июня 2017 г., 14:05:49
char output[50];
strftime(output, 50, "%a %d-%b-%y (%H:%M:%S)", &timeinfo);
time_str = output;
}
```
@ abdalrahmanabs, 👍1
Обсуждение1 ответ
Лучший ответ:
В документации для ArduinoJson 5 перечислены причины, по которым parseObject()
может возвращать false
:
- Введен недопустимый формат JSON.
StaticJsonBuffer
слишком мал- Слишком большой
StaticJsonBuffer
(переполнение стека) DynamicJsonBuffer
не удается выделить память- Вы вызвали
parseObject()
вместоparseArray()
- Ограничение вложенности слишком низкое.
Взглянув на ваш код, можно предположить, что проблема номер 2: StaticJsonBuffer
очень маленький.
Действительно, я не знаю, как выглядит ввод, но 200 байт, вероятно, слишком мало для хранения результата.
Вы можете использовать ArduinoJson Assistant, чтобы вычислить необходимую емкость для JsonBuffer
. Не забудьте переключиться на DynamicJsonBuffer
, если он станет больше 4 КБ.< /p>
Наконец, я настоятельно рекомендую вам перейти на ArduinoJson 6, потому что он предлагает больше функций, лучшую производительность, лучшую память. использование и улучшенные отчеты об ошибках при одинаковом размере кода и переносимости.
- Не могу скомпилировать .ino с помощью библиотеки ArduinoJson
- esp32 Stack canary watchpoint срабатывает
- Почему функция server.on() из "ESPAsyncWebServer.h" выполняется на стороне setup(), а не на стороне loop()?
- Публиковать данные json в mqtt
- ESP32 отправляет данные на другой ESP32 без установления соединения Wi-Fi
- Передача нестатической функции-члена с помощью bind
- Увеличить частоту дискретизации на плате ESP32
- Ошибка Guru Meditation: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
почему вы не предоставляете всю информацию? ... Я совершенно уверен, что сообщение об ошибке длиннее, чем
parseObject() failed
, @jsotolaэто полная проблема, если вы прочитаете код, вы найдете это, если статус
`
JsonObject& root = jsonBuffer.parseObject(response); // Разбираем JSON если (!root.success()) { Serial.println(F("Ошибка jsonBuffer.parseObject()")); }`
он просто печатает это сообщение в последовательном мониторе, @ abdalrahmanabsраспечатайте содержимое и посмотрите на byre json. Вероятно, он либо слишком длинный, либо слишком умещается в 200 байт, либо форматирование нарушено., @Sim Son