Декодирование и кодирование JSON с Arduino или ESP8266
В этом руководстве вы узнаете, как декодировать (парсить JSON-строку) и кодировать (генерировать JSON-строку) с помощью библиотеки ArduinoJson, используя Arduino с Ethernet-шилдом. Это руководство также работает с Wi-Fi модулями ESP8266 и ESP32 с небольшими изменениями.
Примечание
Важно: данное руководство совместимо только с библиотекой ArduinoJSON версии 5.13.5.
Что такое JSON?
JSON расшифровывается как J ava S cript O bject N otation. JSON — это легковесный текстовый открытый стандарт, предназначенный для обмена данными.
JSON в основном используется для сериализации и передачи структурированных данных по сетевому соединению — передача данных между сервером и клиентом. Он часто используется в сервисах, таких как API (Application Programming Interfaces — интерфейсы прикладного программирования) и веб-сервисы, предоставляющие публичные данные.
Основы синтаксиса JSON
В JSON данные структурированы определённым образом. JSON использует символы { } , : « « [ ] и имеет следующий синтаксис:
Данные представлены в виде пар ключ/значение
Двоеточие (:) присваивает значение ключу
Пары ключ/значение разделяются запятыми (,)
Фигурные скобки содержат объекты ({ })
Квадратные скобки содержат массивы ([ ])
Например, для представления данных в JSON пары ключ/значение выглядят следующим образом:
{"key1":"value1", "key2":"value2", "key3":"value3"}
Примеры JSON
В реальном примере вы можете захотеть структурировать данные о пользователе:
{"name":"Rui", "country": "Portugal", "age":24}
Или в IoT-проекте вы можете захотеть структурировать данные с ваших датчиков:
{"temperature":27.23, "humidity":62.05, "pressure":1013.25}
В JSON значениями могут быть другие JSON-объекты (sports) или массивы (pets). Например:
{
"name": "Rui",
"sports": {
"outdoor": "hiking",
"indoor": "swimming"
},
"pets": [
"Max",
"Dique"
]
}
Здесь мы структурируем данные о пользователе, и у нас есть несколько ключей: «name», «sports» и «pets».
Ключу name присвоено значение Rui. Rui может заниматься различными видами спорта в зависимости от места. Поэтому мы создаём ещё один JSON-объект для сохранения любимых видов спорта Rui. Этот JSON-объект является значением ключа «sports».
Ключ «pets» содержит массив с именами питомцев Rui, и он содержит значения «Max» и «Dique» внутри.
Большинство API возвращают данные в формате JSON, и большинство значений сами являются JSON-объектами. Следующий пример показывает данные, предоставляемые API погоды.
{
"coord": {
"lon": -8.61,
"lat": 41.15
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04d"
}
],
"base": "stations",
"main": {
"temp": 288.15,
"pressure": 1020,
"humidity": 93,
"temp_min": 288.15,
"temp_max": 288.15
},
(...)
}
Этот API предоставляет большой объём информации. Например, первые строки хранят координаты с долготой и широтой.
Arduino с Ethernet-шилдом
Примеры в этом руководстве используют Arduino с Ethernet-шилдом. Просто установите шилд на вашу плату Arduino и подключите его к сети кабелем RJ45 для установки интернет-соединения (как показано на рисунке ниже).
Примечание: примеры, приведённые в этом руководстве, также работают с ESP8266 и ESP32 с небольшими изменениями.
Подготовка Arduino IDE
Самый простой способ декодировать и кодировать JSON-строки в Arduino IDE — использовать библиотеку ArduinoJson версии 5.13.5, которая была разработана как наиболее интуитивно понятная JSON-библиотека с минимальным размером и наиболее эффективным управлением памятью для Arduino.
Она была написана с учётом Arduino, но не привязана к библиотекам Arduino, поэтому вы можете использовать эту библиотеку в любом другом C++ проекте. Также существует документация библиотеки с примерами и справочником по API.
Возможности
Декодирование JSON (поддерживаются комментарии)
Кодирование JSON (с опциональными отступами)
Элегантный API, очень простой в использовании
Фиксированное выделение памяти (zero malloc)
Без дублирования данных (zero copy)
Портативная (написана на C++98)
Самодостаточная (без внешних зависимостей)
Малый размер
Библиотека только из заголовочных файлов
Лицензия MIT
Совместимость
Платы Arduino: Uno, Due, Mini, Micro, Yun…
ESP8266, ESP32 и платы WeMos
Teensy, RedBearLab, Intel Edison и Galileo
PlatformIO, Particle и Energia
Установка библиотеки ArduinoJson
Для этого проекта вам нужно установить библиотеку ArduinoJson в вашу Arduino IDE:
Нажмите здесь, чтобы скачать ArduinoJson версии 5.13.5. У вас должен появиться файл .zip в папке Downloads
Распакуйте .zip файл, и вы получите папку ArduinoJson-master
Переименуйте папку из ~~ArduinoJson-master~~ в ArduinoJson
Переместите папку ArduinoJson в папку библиотек вашей Arduino IDE
Наконец, перезапустите Arduino IDE
Декодирование JSON — Парсинг JSON-строки
Давайте начнём с декодирования/парсинга следующей JSON-строки:
{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
Импортируйте библиотеку ArduinoJson:
#include <ArduinoJson.h>
Arduino JSON использует предварительно выделенный пул памяти для хранения дерева JsonObject, это делается с помощью StaticJsonBuffer. Вы можете использовать ArduinoJson Assistant для вычисления точного размера буфера, но для этого примера 200 достаточно.
StaticJsonBuffer<200> jsonBuffer;
Создайте массив символов с именем json[] для хранения примера JSON-строки:
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
Используйте функцию parseObject() для декодирования/парсинга JSON-строки в JsonObject с именем root.
JsonObject& root = jsonBuffer.parseObject(json);
Чтобы проверить, было ли декодирование/парсинг успешным, вы можете вызвать root.success():
if(!root.success()) {
Serial.println("parseObject() failed");
return false;
}
Результат может быть false по трём причинам:
JSON-строка имеет недопустимый синтаксис;
JSON-строка не представляет объект;
StaticJsonBuffer слишком мал — используйте ArduinoJson Assistant для вычисления размера буфера.
Теперь, когда объект или массив находится в памяти, вы можете легко извлечь данные. Самый простой способ — использовать JsonObject root:
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
Вы можете использовать декодированные переменные sensor, time, latitude или longitude в логике вашего кода.
API OpenWeatherMap
Для реального примера использования Arduino с Ethernet-шилдом мы собираемся использовать бесплатный API от OpenWeatherMap для запроса прогноза погоды на текущий день для выбранного вами местоположения.
Умение работать с API — это отличный навык, потому что он предоставляет вам доступ к широкому спектру постоянно обновляемой информации, такой как текущая цена акций, курс обмена валют, последние новости, информация о трафике и многое другое.
Использование API
Бесплатный план OpenWeatherMap предоставляет всё необходимое для этого примера. Для использования API вам нужен API-ключ, известный как APIID. Чтобы получить APIID:
Откройте браузер и перейдите на OpenWeatherMap
Нажмите кнопку Sign up и создайте бесплатный аккаунт
После создания аккаунта вам будет представлена панель управления с несколькими вкладками (см. рисунок ниже)
Выберите вкладку API Keys и скопируйте ваш уникальный Key
Это уникальный ключ, который вам нужен для получения информации с сайта. Скопируйте и сохраните этот ключ, он вам скоро понадобится.
Чтобы получить информацию о погоде в выбранном вами местоположении, введите следующий URL, заменив разделы в фигурных скобках на информацию о вашем местоположении и ваш уникальный API-ключ:
http://api.openweathermap.org/data/2.5/weather?q={your city},{your country code}&APPID={your API Key}
Замените {your city} на город, для которого вам нужны данные, {your country code} на код страны для этого города, и {your API key} на ваш уникальный API-ключ, который мы нашли ранее. Например, наш URL API для города Порту в Португалии после замены деталей будет выглядеть так:
http://api.openweathermap.org/data/2.5/weather?q=Porto,PT&APPID=801d2603e9f2e1c70e042e4------
Примечание: дополнительная информация об использовании API для получения данных о погоде доступна здесь.
Скопируйте ваш URL в браузер, и он должен выдать кучу информации, соответствующей данным о погоде в вашем регионе.
В нашем случае он возвращает погоду в Порту, Португалия, на день написания:
{
"coord": {
"lon": -8.61,
"lat": 41.15
},
"weather": [
{
"id": 701,
"main": "Mist",
"description": "mist",
"icon": "50d"
}
],
"base": "stations",
"main": {
"temp": 290.86,
"pressure": 1014,
"humidity": 88,
"temp_min": 290.15,
"temp_max": 292.15
},
(...)
}
Выполнение API-запроса с Arduino
Теперь, когда у вас есть URL, который возвращает данные о погоде в вашем регионе, вы можете автоматизировать эту задачу и получить доступ к этим данным в ваших проектах Arduino или ESP8266. Вот полный скрипт, который нужно загрузить на ваш Arduino с Ethernet-шилдом для получения температуры в Кельвинах и влажности:
/*
* Rui Santos
* Complete Project Details https://randomnerdtutorials.com
* Based on the Arduino Ethernet Web Client Example
* and on the sketch "Sample Arduino Json Web Client"
* of the Arduino JSON library by Benoit Blanchon
* (bblanchon.github.io/ArduinoJson)
*/
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>
EthernetClient client;
// Name address for Open Weather Map API
const char* server = "api.openweathermap.org";
// Replace with your unique URL resource
const char* resource = "REPLACE_WITH_YOUR_URL_RESOURCE";
// How your resource variable should look like, but with your own
// COUNTRY CODE, CITY and API KEY (that API KEY below is just an example):
//const char* resource = "/data/2.5/weather?q=Porto,pt&appid=bd939aa3d23ff33d3c8f5dd1";
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// The type of data that we want to extract from the page
struct clientData {
char temp[8];
char humidity[8];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to initialize
}
Serial.println("Serial ready");
if(!Ethernet.begin(mac)) {
Serial.println("Failed to configure Ethernet");
return;
}
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()) {
clientData clientData;
if(readReponseContent(&clientData)) {
printclientData(&clientData);
}
}
}
disconnect();
wait();
}
// 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(host);
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;
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
/*{
"coord": {
"lon": -8.61,
"lat": 41.15
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 296.15,
"pressure": 1020,
"humidity": 69,
"temp_min": 296.15,
"temp_max": 296.15
},
"visibility": 10000,
"wind": {
"speed": 4.6,
"deg": 320
},
"clouds": {
"all": 0
},
"dt": 1499869800,
"sys": {
"type": 1,
"id": 5959,
"message": 0.0022,
"country": "PT",
"sunrise": 1499836380,
"sunset": 1499890019
},
"id": 2735943,
"name": "Porto",
"cod": 200
}*/
bool readReponseContent(struct clientData* clientData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// See https://bblanchon.github.io/ArduinoJson/assistant/
const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) +
2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) +
JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(12) + 390;
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// Here were copy the strings we're interested in using to your struct data
strcpy(clientData->temp, root["main"]["temp"]);
strcpy(clientData->humidity, root["main"]["humidity"]);
// 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 printclientData(const struct clientData* clientData) {
Serial.print("Temp = ");
Serial.println(clientData->temp);
Serial.print("Humidity = ");
Serial.println(clientData->humidity);
}
// 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);
}
Примечание: убедитесь, что вы заменили переменную resource на ваш уникальный URL-ресурс OpenWeatherMap:
const char* resource = "REPLACE_WITH_YOUR_URL_RESOURCE";
Модификация кода для вашего проекта
В этом примере Arduino выполняет HTTP GET запрос к нужному сервису (в данном случае API OpenWeatherMap), но вы можете изменить его для запроса к любому другому веб-сервису. Мы не будем объяснять код Arduino построчно.
Для этого проекта важно, чтобы вы понимали, что нужно изменить в коде Arduino для декодирования/парсинга любого JSON-ответа. Следуйте следующим трём шагам.
ШАГ #1 — struct
Создайте структуру данных, которая может хранить информацию, которую вы хотите извлечь из API. В данном случае мы хотим хранить температуру и влажность в массивах символов:
struct clientData {
char temp[8];
char humidity[8];
};
ШАГ #2 — размер JsonBuffer
Перейдите в ArduinoJson Assistant и скопируйте полный ответ API OpenWeatherMap в поле Input.
Скопируйте сгенерированное Expression (см. предыдущий рисунок), в нашем случае:
JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(12)
Вам нужно отредактировать функцию readReponseContent() с вашим сгенерированным размером JsonBuffer из ArduinoJson Assistant, чтобы выделить соответствующий объём памяти для декодирования JSON-ответа от API:
bool readReponseContent(struct clientData* clientData) {
const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) +
2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) +
JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(12) + 390;
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& root = jsonBuffer.parseObject(client);
Всё ещё внутри функции readReponseContent() вам нужно скопировать переменные, которые нужны для вашего проекта, в вашу структуру данных:
strcpy(clientData->temp, root["main"]["temp"]);
strcpy(clientData->humidity, root["main"]["humidity"]);
ШАГ #3 — доступ к декодированным данным
Затем вы можете легко получить доступ к декодированным JSON-данным в вашем коде Arduino и сделать что-нибудь с ними. В этом примере мы просто выводим температуру в Кельвинах и влажность в серийный монитор Arduino IDE:
void printclientData(const struct clientData* clientData) {
Serial.print("Temp = ");
Serial.println(clientData->temp);
Serial.print("Humidity = ");
Serial.println(clientData->humidity);
}
Демонстрация
Откройте серийный монитор Arduino IDE на скорости 9600 бод, и вы увидите температуру в Кельвинах и влажность в процентах, выводимые в серийный монитор каждые 60 секунд.
Вы можете получить доступ к остальной информации в ответе API OpenWeatherMap, но для целей демонстрации мы декодировали только температуру и влажность.
Кодирование JSON — Генерация JSON-строки
Давайте узнаем, как кодировать/генерировать следующую JSON-строку:
{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
Вы можете прочитать документацию по кодированию здесь.
Импортируйте библиотеку ArduinoJson:
#include <ArduinoJson.h>
Arduino JSON использует предварительно выделенный пул памяти для хранения дерева объектов, это делается с помощью StaticJsonBuffer. Вы можете использовать ArduinoJson Assistant для вычисления точного размера буфера, но для этого примера 200 достаточно.
StaticJsonBuffer<200> jsonBuffer;
Создайте JsonObject с именем root, который будет хранить ваши данные. Затем присвойте значения gps и 1351824120 ключам sensor и time соответственно:
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "gps";
root["time"] = 1351824120;
Затем, чтобы поместить массив в ключ data, сделайте следующее:
JsonArray& data = root.createNestedArray("data");
data.add(48.756080);
data.add(2.302038);
Очень вероятно, что вам потребуется вывести сгенерированный JSON в серийный монитор для целей отладки, для этого:
root.printTo(Serial);
После кодирования вашей информации в JSON-строку вы можете отправить её на другое устройство или веб-сервис, как показано в следующем примере.
Пример кодирования с Arduino и Node-RED
Для этого примера вам нужен Node-RED или аналогичное программное обеспечение, которое может принимать HTTP POST запросы. Вы можете установить Node-RED на свой компьютер, но мы рекомендуем запуск Node-RED на Raspberry Pi.
Создание потока (flow)
В этом потоке вы будете получать HTTP POST запрос и выводить полученные данные в окне Debug. Следуйте следующим 6 шагам для создания вашего потока:
1) Откройте программу Node-RED в вашем браузере
2) Перетащите узел HTTP input и узел debug
3) Отредактируйте HTTP input, добавив метод POST и URL /json-post-example
4) Вы можете оставить настройки по умолчанию для узла debug
5) Соедините ваши узлы
6) Чтобы сохранить ваше приложение, нужно нажать кнопку deploy в правом верхнем углу
Ваше приложение сохранено и готово к работе.
Отправка JSON-данных с Arduino
После того как Node-RED подготовлен к приёму POST запросов по URL /json-post-example, вы можете использовать следующий пример кода на Arduino с Ethernet-шилдом для отправки данных.
/*
* Rui Santos
* Complete Project Details https://randomnerdtutorials.com
* Based on the Arduino Ethernet Web Client Example
* and on the sketch "Sample Arduino Json Web Client"
* of the Arduino JSON library by Benoit Blanchon
* (bblanchon.github.io/ArduinoJson)
*/
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>
EthernetClient client;
// Replace with your Raspberry Pi IP address
const char* server = "REPLACE_WITH_YOUR_RASPBERRY_PI_IP_ADDRESS";
// Replace with your server port number frequently port 80
// with Node-RED you need to use port 1880
int portNumber = 1880;
// Replace with your unique URL resource
const char* resource = "/json-post-example";
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
while(!Serial) {
; // wait for serial port to initialize
}
Serial.println("Serial ready");
if(!Ethernet.begin(mac)) {
Serial.println("Failed to configure Ethernet");
return;
}
Serial.println("Ethernet ready");
delay(1000);
}
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if(connect(server, portNumber)) {
if(sendRequest(server, resource) && skipResponseHeaders()) {
Serial.print("HTTP POST request finished.");
}
}
disconnect();
wait();
}
// Open connection to the HTTP server (Node-RED running on Raspberry Pi)
bool connect(const char* hostName, int portNumber) {
Serial.print("Connect to ");
Serial.println(hostName);
bool ok = client.connect(hostName, portNumber);
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
// Send the HTTP POST request to the server
bool sendRequest(const char* host, const char* resource) {
// Reserve memory space for your JSON data
StaticJsonBuffer<200> jsonBuffer;
// Build your own object tree in memory to store the data
// you want to send in the request
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "dht11";
JsonObject& data = root.createNestedObject("data");
data.set("temperature", "30.1");
data.set("humidity", "70.1");
// Generate the JSON string
root.printTo(Serial);
Serial.print("POST ");
Serial.println(resource);
client.print("POST ");
client.print(resource);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(host);
client.println("Connection: close\r\nContent-Type: application/json");
client.print("Content-Length: ");
client.print(root.measureLength());
client.print("\r\n");
client.println();
root.printTo(client);
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;
}
// 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);
}
Примечание: убедитесь, что вы заменили переменную server вашим IP-адресом Raspberry Pi:
const char* server = "REPLACE_WITH_YOUR_RASPBERRY_PI_IP_ADDRESS";
Модификация кода для вашего проекта
В этом примере Arduino выполняет HTTP POST запрос к Node-RED, но вы можете изменить его для выполнения запроса к другому веб-сервису или серверу. Мы не будем объяснять код Arduino построчно. Для этого проекта важно, чтобы вы понимали, что нужно изменить в коде Arduino для кодирования/генерации JSON-запроса.
Функция sendRequest()
Для этого проекта вы можете модифицировать функцию sendRequest() с вашей собственной JSON-структурой данных:
bool sendRequest(const char* host, const char* resource) {
Начните с резервирования места в памяти для ваших JSON-данных. Вы можете использовать ArduinoJson Assistant для вычисления точного размера буфера, но для этого примера 200 достаточно.
StaticJsonBuffer<200> jsonBuffer;
Создайте JsonObject с именем root, который будет хранить ваши данные, и присвойте значения вашим ключам (в этом примере у нас есть ключ sensor):
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "dht11";
Чтобы поместить данные в массив, сделайте следующее:
JsonObject& data = root.createNestedObject("data");
data.set("temperature", "30.1");
data.set("humidity", "70.1");
Выведите сгенерированную JSON-строку в серийный монитор Arduino IDE для целей отладки:
root.printTo(Serial);
Остальная часть функции sendRequest() — это POST-запрос.
client.print("POST ");
client.print(resource);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(host);
client.println("Connection: close\r\nContent-Type: application/json");
client.print("Content-Length: ");
client.print(root.measureLength());
client.print("\r\n");
client.println();
root.printTo(client);
Обратите внимание, что вы можете использовать root.measureLength() для определения длины вашего сгенерированного JSON. Функция root.printTo(client) отправляет JSON-данные Ethernet-клиенту.
Демонстрация
Откройте серийный монитор Arduino IDE на скорости 9600 бод, и вы увидите JSON-объект, выводимый в серийный монитор каждые 60 секунд.
Во вкладке debug Node-RED вы увидите тот же JSON-объект, получаемый каждые 60 секунд:
Наконец, вы можете создать функции в Node-RED, которые делают что-то полезное с полученными данными, но для целей демонстрации мы просто выводим примеры данных.
Подведение итогов
В этом руководстве мы показали вам несколько примеров декодирования и кодирования JSON-данных. Вы можете следовать этим базовым шагам для создания более сложных проектов, требующих обмена данными между устройствами.
Надеемся, что это руководство было для вас полезным.
Если вам понравился этот проект и домашняя автоматизация, обязательно ознакомьтесь с нашим курсом: Создайте систему домашней автоматизации за $100.