Decoding dan Encoding JSON dengan Arduino atau ESP8266

April 05, 2020
Dalam posting blog ini, Anda akan belajar cara mendekode (parse string JSON) dan menyandikan (menghasilkan string JSON) dengan pustaka ArduinoJson menggunakan Arduino menggunakan Arduino dengan perisai Ethernet. Panduan ini juga berfungsi dengan modul Wi-Fi ESP8266 dan ESP32 dengan perubahan kecil.
Penting: tutorial ini hanya kompatibel dengan perpustakaan ArduinoJSON 5.13.5.
Apa itu JSON?
JSON adalah singkatan dari JavaScript Object Notation. JSON adalah desain standar terbuka berbasis teks yang ringan untuk bertukar data. JSON terutama digunakan untuk membuat cerita bersambung dan mentransmisikan data terstruktur melalui koneksi jaringan - mengirimkan data antara server dan klien. Ini sering digunakan dalam layanan seperti API (Application Programming Interfaces) dan layanan web yang menyediakan data publik.

Dasar-dasar sintaksis JSON
Di JSON, data disusun dengan cara tertentu. JSON menggunakan simbol seperti {},: "" [] dan memiliki sintaks berikut:

  • Data direpresentasikan dalam pasangan kunci / nilai
  • Tanda titik dua (:) memberikan nilai pada kunci
  • pasangan kunci / nilai dipisahkan dengan koma (,)
  • Kurung keriting menahan objek ({})
  • Kurung persegi menahan array ([])

Misalnya, untuk merepresentasikan data dalam JSON, pasangan kunci / nilai datang sebagai berikut:
{"key1":"value1", "key2":"value2", "key3":"value3"}
Contoh JSON
Dalam contoh dunia nyata, Anda mungkin ingin menyusun data tentang pengguna:
{"name":"Rui", "country": "Portugal", "age":24}
Atau dalam proyek IoT, Anda mungkin ingin menyusun data dari sensor Anda:
{"temperature":27.23, "humidity":62.05, "pressure":1013.25}

Di JSON, nilainya bisa berupa objek JSON lain (olahraga) atau array (hewan peliharaan). Sebagai contoh:
{
  "name": "Rui",
  "sports": {
    "outdoor": "hiking",
    "indoor": "swimming"
  },
  "pets": [
    "Max",
    "Dique"
  ]
}
Di sini kami menyusun data tentang pengguna dan kami memiliki beberapa kunci: "nama", "olahraga", dan "hewan peliharaan".
Nama memiliki nilai yang ditetapkan Rui. Rui dapat berlatih berbagai olahraga yang berkaitan dengan tempat mereka berlatih. Jadi, kami membuat objek JSON lain untuk menyimpan olahraga favorit Rui. Objek JSON ini adalah nilai kunci "olahraga".
Kunci "hewan peliharaan" memiliki larik yang berisi nama hewan peliharaan Rui dan memiliki nilai "Max" dan "Dique" di dalamnya.
Sebagian besar API mengembalikan data dalam JSON dan sebagian besar nilai adalah objek JSON sendiri. Contoh berikut menunjukkan data yang disediakan oleh API cuaca.
 
  "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 ini menyediakan banyak informasi. Misalnya, baris pertama menyimpan koordinat dengan garis bujur dan garis lintang.

Arduino dengan perisai Ethernet
Contoh-contoh dalam posting ini menggunakan Arduino dengan perisai Ethernet. Cukup pasang pelindung ke papan Arduino Anda dan hubungkan ke jaringan Anda dengan kabel RJ45 untuk membuat koneksi Internet (seperti yang ditunjukkan pada gambar di bawah).

Catatan: contoh yang diberikan dalam tutorial ini juga berfungsi dengan ESP8266 dan ESP32 dengan perubahan kecil.

Mempersiapkan IDE Arduino
Cara termudah untuk mendekode dan menyandikan string JSON dengan Arduino IDE menggunakan ArduinoJson library 5.13.5 yang dirancang untuk menjadi perpustakaan JSON paling intuitif, dengan jejak terkecil dan manajemen memori paling efisien untuk Arduino.

Ini telah ditulis dengan mempertimbangkan Arduino, tetapi tidak tertaut ke perpustakaan Arduino sehingga Anda dapat menggunakan perpustakaan ini dalam proyek C ++ lainnya. Ada juga situs web dokumentasi untuk perpustakaan dengan contoh-contoh dan dengan referensi API.

fitur

  • Penguraian JSON (komentar didukung)
  • Pengkodean JSON (dengan indentasi opsional)
  • API elegan, sangat mudah digunakan
  • Memperbaiki alokasi memori (nol malloc)
  • Tidak ada duplikasi data (salinan nol)
  • Portable (ditulis dalam C ++ 98)
  • Mandiri (tidak ada ketergantungan eksternal)
  • Jejak kaki kecil
  • Perpustakaan hanya header
  • Lisensi MIT

Cocok dengan

  • Papan Arduino: Uno, Due, Mini, Micro, Yun…
  • ESP8266, ESP32, dan papan WeMos
  • Teensy, papan RedBearLab, Intel Edison, dan Galileo
  • PlatformIO, Partikel dan Energia

Menginstal perpustakaan ArduinoJson
Untuk proyek ini, Anda perlu menginstal perpustakaan ArduinoJson di IDE Arduino Anda:

Decoding JSON - Parse string JSON
Mari kita mulai dengan mendekode / parsing string JSON berikutnya:
{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
Impor perpustakaan ArduinoJson:
#include <ArduinoJson.h>
Arduino JSON menggunakan kumpulan memori yang telah dialokasikan sebelumnya untuk menyimpan pohon JsonObject, ini dilakukan oleh StaticJsonBuffer. Anda dapat menggunakan ArduinoJson Assistant untuk menghitung ukuran buffer yang tepat, tetapi untuk contoh ini 200 sudah cukup.
StaticJsonBuffer<200> jsonBuffer;
Buat array char yang disebut json [] untuk menyimpan contoh string JSON:
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; 
Gunakan fungsi parseObject () untuk memecahkan kode / parsing string JSON ke JsonObject yang disebut root.
JsonObject& root = jsonBuffer.parseObject(json);
Untuk memeriksa apakah decoding / parsing berhasil, Anda dapat memanggil root.success ():
if(!root.success()) {
  Serial.println("parseObject() failed");
  return false;
}
Hasilnya bisa salah karena tiga alasan:

  • string JSON memiliki sintaks yang tidak valid;
  • string JSON tidak mewakili objek;
  • StaticJsonBuffer terlalu kecil - gunakan ArduinoJson Assistant untuk menghitung ukuran buffer.

Sekarang objek atau array ada di memori, Anda dapat mengekstrak data dengan mudah. Cara paling sederhana adalah dengan menggunakan root JsonObject:
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
Anda dapat menggunakan sensor variabel yang didekodekan, waktu, lintang atau bujur dalam logika kode Anda.

OpenWeatherMap API
Untuk contoh nyata menggunakan Arduino dengan perisai Ethernet, kami akan menggunakan API gratis dari OpenWeatherMap untuk meminta ramalan cuaca hari itu untuk lokasi yang Anda pilih.
Belajar menggunakan API adalah keterampilan yang hebat karena memungkinkan Anda mengakses berbagai informasi yang terus berubah, seperti harga saham saat ini, nilai tukar mata uang, berita terbaru, pembaruan lalu lintas, dan banyak lagi.

Menggunakan API
Paket gratis OpenWeatherMap menyediakan semua yang Anda butuhkan sebagai contoh. Untuk menggunakan API, Anda memerlukan kunci API, yang dikenal sebagai APIID. Untuk mendapatkan APIID:

  1. Buka browser dan pergi ke OpenWeatherMap
  2. Tekan tombol Daftar dan buat akun gratis
  3. Setelah akun Anda dibuat, Anda akan disajikan dengan dasbor yang berisi beberapa tab (lihat gambar di bawah)
  4. Pilih tab Kunci API dan salin Kunci unik Anda


Ini adalah kunci unik yang Anda perlukan untuk menarik informasi dari situs. Salin dan tempel kunci ini di suatu tempat, Anda akan membutuhkannya sebentar lagi.

Untuk menarik informasi tentang cuaca di lokasi yang Anda pilih, masukkan URL berikut dengan bagian dalam kurung keriting diganti dengan informasi lokasi yang Anda pilih dan kunci API unik Anda:
http://api.openweathermap.org/data/2.5/weather?q={your city},{your country code}&APPID={your API Key}
Ganti {kota Anda} dengan kota yang Anda inginkan datanya, {kode negara Anda} dengan kode negara untuk kota itu, dan {kunci API Anda} dengan kunci API unik yang kami temukan sebelumnya. Misalnya, URL API kami untuk kota Porto di Portugal, setelah diganti dengan detailnya, adalah:
http://api.openweathermap.org/data/2.5/weather?q=Porto,PT&APPID=801d2603e9f2e1c70e042e4------
Catatan: informasi lebih lanjut tentang penggunaan API untuk mendapatkan informasi cuaca tersedia di sini.

Salin URL Anda ke browser Anda dan itu akan memberi Anda banyak informasi yang sesuai dengan informasi cuaca lokal Anda.

Dalam kasus kami, ini mengembalikan cuaca di Porto, Portugal pada hari penulisan:
{
  "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
  },
  (...)
}
Membuat Permintaan API dengan Arduino
Sekarang Anda memiliki URL yang mengembalikan data cuaca lokal Anda. Anda dapat mengotomatiskan tugas ini dan mengakses data itu dalam proyek Arduino atau ESP8266 Anda. Inilah skrip lengkap yang harus Anda unggah ke Arduino Anda dengan perisai Ethernet untuk mengembalikan suhu dalam Kelvin dan kelembaban:
/*
 * 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);
}
Catatan: pastikan Anda mengganti variabel sumber daya dengan sumber daya URL OpenWeatherMap unik Anda:
const char* resource = "REPLACE_WITH_YOUR_URL_RESOURCE";
Memodifikasi kode untuk proyek Anda
Dalam contoh ini, Arduino melakukan permintaan HTTP GET ke layanan yang diinginkan (dalam hal ini OpenWeatherMap API), tetapi Anda bisa mengubahnya untuk meminta layanan web lainnya. Kami tidak akan menjelaskan kode Arduino baris demi baris.

Untuk proyek ini, penting bagi Anda untuk memahami apa yang perlu Anda ubah dalam kode Arduino untuk memecahkan kode / parsing setiap respons JSON. Ikuti tiga langkah selanjutnya.

LANGKAH # 1 - struct
Buat struktur data yang dapat menyimpan informasi yang ingin Anda ekstrak dari API. Dalam hal ini, kami ingin menyimpan suhu dan kelembaban di array char:
struct clientData {
  char temp[8];
  char humidity[8];
};
LANGKAH # 2 - ukuran JsonBuffer
Pergi ke Asisten ArduinoJson dan salin respons OpenWeatherMap API lengkap ke bidang Input.




Salin Ekspresi yang dihasilkan (lihat gambar sebelumnya), dalam kasus saya:
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)
Anda harus mengedit fungsi readReponseContent () dengan ukuran JsonBuffer yang dihasilkan dari ArduinoJson Assistant untuk mengalokasikan memori yang sesuai untuk mendekode respons JSON dari 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);
Masih di dalam fungsi readReponseContent () Anda perlu menyalin variabel yang Anda butuhkan untuk proyek Anda ke data struct Anda:
strcpy(clientData->temp, root["main"]["temp"]);
strcpy(clientData->humidity, root["main"]["humidity"]);
LANGKAH # 3 - mengakses data yang diterjemahkan
Kemudian, Anda dapat dengan mudah mengakses data JSON yang didekode dalam kode Arduino Anda dan melakukan sesuatu dengannya. Dalam contoh ini kami hanya mencetak suhu di Kelvin dan kelembaban di monitor serial Arduino IDE:
void printclientData(const struct clientData* clientData) {
  Serial.print("Temp = ");
  Serial.println(clientData->temp);
  Serial.print("Humidity = ");
  Serial.println(clientData->humidity);
}
Demonstrasi
Buka monitor serial Arduino IDE pada kecepatan baud 9600 dan Anda akan melihat suhu di Kelvin dan persentase kelembaban yang dicetak di monitor Serial setiap 60 detik.

Anda dapat mengakses informasi lainnya dalam respons OpenWeatherMap API, tetapi untuk tujuan demonstrasi, kami hanya mendekodekan suhu dan kelembaban.

Encoding JSON - Menghasilkan string JSON
Mari kita pelajari cara menyandikan / membuat string JSON berikutnya:
{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
Anda dapat membaca dokumen tentang enconding di sini.
Impor perpustakaan ArduinoJson:
#include <ArduinoJson.h>
Arduino JSON menggunakan kumpulan memori yang telah dialokasikan untuk menyimpan pohon objek, ini dilakukan oleh StaticJsonBuffer. Anda dapat menggunakan ArduinoJson Assistant untuk menghitung ukuran buffer yang tepat, tetapi untuk contoh ini 200 sudah cukup.
StaticJsonBuffer<200> jsonBuffer;
Buat JsonObject yang disebut root yang akan menampung data Anda. Kemudian, tetapkan nilai gps dan 1351824120 masing-masing ke sensor dan kunci waktu:

JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "gps";
root["time"] = 1351824120;
Sangat mungkin bahwa Anda perlu mencetak JSON yang dihasilkan di monitor Seri Anda untuk keperluan debugging, untuk melakukan itu:
root.printTo(Serial);
Setelah informasi Anda dikodekan dalam string JSON, Anda dapat mempostingnya ke perangkat lain atau layanan web seperti yang ditunjukkan pada contoh berikut.

Contoh pengkodean dengan Arduino dan Node-RED
Untuk contoh ini Anda perlu Node-RED atau perangkat lunak serupa yang dapat menerima permintaan HTTP POST. Anda dapat menginstal Node-RED di komputer Anda, tetapi saya sarankan menjalankan Node-RED di Raspberry Pi.

Membuat Flow
Dalam flow ini, Anda akan menerima permintaan HTTP POST dan mencetak data terima di jendela Debug. Ikuti 6 langkah berikutnya untuk membuat aliran Anda:
1) Buka perangkat lunak Node-RED di browser Anda

2. Seret node input HTTP dan node debug
3. 3) Edit the HTTP input by adding the POST method and the /json-post-example URL

4) Anda dapat meninggalkan pengaturan default untuk node debug

5) Hubungkan node Anda

6) Untuk menyimpan aplikasi Anda, Anda perlu mengklik tombol deploy di sudut kanan atas

Aplikasi Anda disimpan dan siap.
Kirim data JSON dengan Arduino
Setelah Node-RED disiapkan untuk menerima permintaan POST di URL / json-post-example, Anda dapat menggunakan contoh kode berikut pada Arduino dengan perisai Ethernet untuk mengirim data ke sana.
/*
 * 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);
}
Catatan: pastikan Anda mengganti variabel server dengan alamat IP Raspberry Pi Anda:
const char* server = "REPLACE_WITH_YOUR_RASPBERRY_PI_IP_ADDRESS";
Memodifikasi kode untuk proyek Anda
Dalam contoh ini, Arduino melakukan permintaan HTTP POST ke Node-RED, tetapi Anda bisa mengubahnya untuk membuat permintaan layanan web atau server lain. Kami tidak akan menjelaskan kode Arduino baris demi baris. Untuk proyek ini, penting bagi Anda untuk memahami apa yang perlu Anda ubah dalam kode Arduino untuk menyandikan / membuat permintaan JSON.

fungsi sendRequest ()
Untuk proyek ini, Anda dapat memodifikasi fungsi sendRequest () dengan struktur data JSON Anda sendiri:
bool sendRequest(const char* host, const char* resource) {
Mulailah dengan memesan ruang memori untuk data JSON Anda. Anda dapat menggunakan ArduinoJson Assistant untuk menghitung ukuran buffer yang tepat, tetapi untuk contoh ini 200 sudah cukup.
StaticJsonBuffer<200> jsonBuffer;
Buat JsonObject yang disebut root yang akan menampung data Anda dan menetapkan nilai ke kunci Anda (dalam contoh ini kita memiliki kunci sensor):
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "dht11";
Untuk menyimpan data di dalam array, Anda melakukan hal berikut:
JsonObject& data = root.createNestedObject("data");
data.set("temperature", "30.1");
data.set("humidity", "70.1");
Cetak string JSON yang dihasilkan di monitor serial Arduino IDE untuk keperluan debugging:
root.printTo(Serial);
Fungsi sendRequest () lainnya adalah permintaan 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);
Perhatikan bahwa Anda bisa menggunakan root.measureLength () untuk menentukan panjang JSON yang Anda hasilkan. Root.printTo (klien) mengirim data JSON ke klien Ethernet.

Demonstrasi
Buka monitor serial Arduino IDE dengan kecepatan baud 9600 dan Anda akan melihat objek JSON yang dicetak dalam monitor serial setiap 60 detik.

Di tab debug Node-RED Anda akan melihat objek JSON yang sama diterima setiap 60 detik:

Terakhir, Anda membuat fungsi di Node-RED yang melakukan sesuatu yang berguna dengan data yang diterima, tetapi untuk tujuan demonstrasi, kami hanya mencetak data sampel.










Artikel Terkait

Previous
Next Post »