From 461e30148cbddf20f54793ddaaa907dfde73ead5 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 11 Dec 2017 15:19:28 +0100 Subject: [PATCH] Reworked all examples --- CHANGELOG.md | 2 +- .../JsonGeneratorExample.ino | 24 +++- examples/JsonHttpClient/JsonHttpClient.ino | 108 +++++++++------ .../JsonParserExample/JsonParserExample.ino | 26 +++- examples/JsonServer/JsonServer.ino | 121 ++++++++++------- examples/JsonUdpBeacon/JsonUdpBeacon.ino | 124 ++++++++++++------ examples/ProgmemExample/ProgmemExample.ino | 30 +++-- examples/StringExample/StringExample.ino | 25 +++- 8 files changed, 308 insertions(+), 152 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a0e4f5..631cf80f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ HEAD * Added a clear error message when compiled as C instead of C++ (issue #629) * Added detection of MPLAB XC compiler (issue #629) * Added detection of Keil ARM Compiler (issue #629) -* Rewrote example `JsonHttpClient.ino` (issue #600) +* Reworked all examples > ### How to use the new feature? > diff --git a/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/examples/JsonGeneratorExample/JsonGeneratorExample.ino index 24aea00d..f4800de8 100644 --- a/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -1,20 +1,21 @@ // ArduinoJson - arduinojson.org // Copyright Benoit Blanchon 2014-2017 // MIT License +// +// This example shows how to generate a JSON document with ArduinoJson. #include void setup() { + // Initialize Serial port Serial.begin(9600); - while (!Serial) { - // wait serial port initialization - } + while (!Serial) continue; // Memory pool for JSON object tree. // // Inside the brackets, 200 is the size of the pool in bytes. - // If the JSON object is more complex, you need to increase that value. - // See http://arduinojson.org/assistant/ + // Don't forget to change this value to match your JSON document. + // See https://arduinojson.org/assistant/ StaticJsonBuffer<200> jsonBuffer; // StaticJsonBuffer allocates memory on the stack, it can be @@ -65,3 +66,16 @@ void setup() { void loop() { // not used in this example } + +// See also +// -------- +// +// The website arduinojson.org contains the documentation for all the functions +// used above. It also includes an FAQ that will help you solve any +// serialization problem. +// Please check it out at: https://arduinojson.org/ +// +// The book "Mastering ArduinoJson" contains a tutorial on serialization. +// It begins with a simple example, like the one above, and then adds more +// features like serializing directly to a file or an HTTP request. +// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index 99bc2544..3f3985f2 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -2,9 +2,10 @@ // Copyright Benoit Blanchon 2014-2017 // MIT License // -// Example of an HTTP client parsing a JSON response. +// This example shows how to parse a JSON document in an HTTP response. +// It uses the Ethernet library, but can be easily adapter for Wifi. // -// This program perform an HTTP GET of arduinojson.org/example.json +// It performs a GET resquest on arduinojson.org/example.json // Here is the expected response: // { // "sensor": "gps", @@ -14,73 +15,98 @@ // 2.302038 // ] // } -// See http://arduinojson.org/assistant/ to compute the size of the buffer. -// -// Disclaimer: the code emphasize the communication between client and server, -// it doesn't claim to be a reference of good coding practices. #include #include #include void setup() { + // Initialize Serial port Serial.begin(9600); - while (!Serial); + while (!Serial) continue; - echo("Initialize Ethernet library"); + // Initialize Ethernet library byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; - Ethernet.begin(mac) || die("Failed to configure Ethernet"); + if (!Ethernet.begin(mac)) { + Serial.println(F("Failed to configure Ethernet")); + return; + } delay(1000); - echo("Connect to HTTP server"); + Serial.println(F("Connecting...")); + + // Connect to HTTP server EthernetClient client; client.setTimeout(10000); - client.connect("arduinojson.org", 80) || die("Connection failed"); + if (!client.connect("arduinojson.org", 80)) { + Serial.println(F("Connection failed")); + return; + } - echo("Send HTTP request"); - client.println("GET /example.json HTTP/1.0"); - client.println("Host: arduinojson.org"); - client.println("Connection: close"); - client.println() || die("Failed to send request"); + Serial.println(F("Connected!")); - echo("Check HTTP status"); + // Send HTTP request + client.println(F("GET /example.json HTTP/1.0")); + client.println(F("Host: arduinojson.org")); + client.println(F("Connection: close")); + if (client.println() == 0) { + Serial.println(F("Failed to send request")); + return; + } + + // Check HTTP status char status[32] = {0}; client.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") != 0) { - echo(status); - die("Unexpected HTTP response"); + Serial.print(F("Unexpected response: ")); + Serial.println(status); + return; } - echo("Skip HTTP headers"); + // Skip HTTP headers char endOfHeaders[] = "\r\n\r\n"; - client.find(endOfHeaders) || die("Invalid response"); + if (!client.find(endOfHeaders)) { + Serial.println(F("Invalid response")); + return; + } - echo("Allocate JsonBuffer"); - const size_t BUFFER_SIZE = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; - DynamicJsonBuffer jsonBuffer(BUFFER_SIZE); + // Allocate JsonBuffer + // (see https://arduinojson.org/assistant/ to compute the capacity) + const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; + DynamicJsonBuffer jsonBuffer(capacity); - echo("Parse JSON object"); + // Parse JSON object JsonObject& root = jsonBuffer.parseObject(client); - if (!root.success()) die("Parsing failed!"); + if (!root.success()) { + Serial.println(F("Parsing failed!")); + return; + } - echo("Extract values"); - echo(root["sensor"].as()); - echo(root["time"].as()); - echo(root["data"][0].as()); - echo(root["data"][1].as()); + // Extract values + Serial.println(F("Response:")); + Serial.println(root["sensor"].as()); + Serial.println(root["time"].as()); + Serial.println(root["data"][0].as()); + Serial.println(root["data"][1].as()); - echo("Disconnect"); + // Disconnect client.stop(); } -void loop() {} - -void echo(const char* message) { - Serial.println(message); +void loop() { + // not used in this example } -bool die(const char* message) { - Serial.println(message); - while (true); // loop forever - return false; -} \ No newline at end of file +// See also +// -------- +// +// The website arduinojson.org contains the documentation for all the functions +// used above. It also includes an FAQ that will help you solve any +// serialization problem. +// Please check it out at: https://arduinojson.org/ +// +// The book "Mastering ArduinoJson" contains a tutorial on deserialization +// showing how to parse the response from Yahoo Weather. In the last chapter, +// it shows how to parse the huge documents from OpenWeatherMap +// and Weather Underground. +// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 7ba96356..0bc803cd 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -1,20 +1,21 @@ // ArduinoJson - arduinojson.org // Copyright Benoit Blanchon 2014-2017 // MIT License +// +// This example shows how to deserialize a JSON document with ArduinoJson. #include void setup() { + // Initialize serial port Serial.begin(9600); - while (!Serial) { - // wait serial port initialization - } + while (!Serial) continue; // Memory pool for JSON object tree. // - // Inside the brackets, 200 is the size of the pool in bytes, - // If the JSON object is more complex, you need to increase that value. - // See http://arduinojson.org/assistant/ + // Inside the brackets, 200 is the size of the pool in bytes. + // Don't forget to change this value to match your JSON document. + // See https://arduinojson.org/assistant/ StaticJsonBuffer<200> jsonBuffer; // StaticJsonBuffer allocates memory on the stack, it can be @@ -62,3 +63,16 @@ void setup() { void loop() { // not used in this example } + +// See also +// -------- +// +// The website arduinojson.org contains the documentation for all the functions +// used above. It also includes an FAQ that will help you solve any +// deserialization problem. +// Please check it out at: https://arduinojson.org/ +// +// The book "Mastering ArduinoJson" contains a tutorial on deserialization. +// It begins with a simple example, like the one above, and then adds more +// features like deserializing directly from a file or an HTTP request. +// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file diff --git a/examples/JsonServer/JsonServer.ino b/examples/JsonServer/JsonServer.ino index 4aed53ba..be8adc38 100644 --- a/examples/JsonServer/JsonServer.ino +++ b/examples/JsonServer/JsonServer.ino @@ -1,76 +1,109 @@ -// Sample Arduino Json Web Server -// Created by Benoit Blanchon. -// Heavily inspired by "Web Server" from David A. Mellis and Tom Igoe +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2017 +// MIT License +// +// This example shows how to implement an HTTP server that sends JSON document +// in the responses. +// It uses the Ethernet library but can be easily adapter for Wifi. +// +// It sends the value of the analog and digital pins. +// The JSON document looks like the following: +// { +// "analog": [ 0, 1, 2, 3, 4, 5 ], +// "digital": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ] +// } #include #include #include byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; -IPAddress ip(192, 168, 0, 177); EthernetServer server(80); -bool readRequest(EthernetClient& client) { - bool currentLineIsBlank = true; - while (client.connected()) { - if (client.available()) { - char c = client.read(); - if (c == '\n' && currentLineIsBlank) { - return true; - } else if (c == '\n') { - currentLineIsBlank = true; - } else if (c != '\r') { - currentLineIsBlank = false; - } - } +void setup() { + // Initialize serial port + Serial.begin(9600); + while (!Serial) continue; + + // Initialize Ethernet libary + if (!Ethernet.begin(mac)) { + Serial.println(F("Failed to initialize Ethernet library")); + return; } - return false; + + // Start to listen + server.begin(); + + Serial.println(F("Server is ready.")); + Serial.print(F("Please connect to http://")); + Serial.println(Ethernet.localIP()); } -JsonObject& prepareResponse(JsonBuffer& jsonBuffer) { +void loop() { + // Wait for an incomming connection + EthernetClient client = server.available(); + + // Do we have a client? + if (!client) return; + + Serial.println(F("New client")); + + // Read the request (we ignore the content in this example) + while (client.available()) client.read(); + + // Allocate JsonBuffer + // Use http://arduinojson.org/assistant/ to compute the right capacity + StaticJsonBuffer<500> jsonBuffer; + + // Create the root object JsonObject& root = jsonBuffer.createObject(); + // Create the "analog" array JsonArray& analogValues = root.createNestedArray("analog"); for (int pin = 0; pin < 6; pin++) { + // Read the analog input int value = analogRead(pin); + + // Add the value at the end of the array analogValues.add(value); } + // Create the "digital" array JsonArray& digitalValues = root.createNestedArray("digital"); for (int pin = 0; pin < 14; pin++) { + // Read the digital input int value = digitalRead(pin); + + // Add the value at the end of the array digitalValues.add(value); } - return root; -} + Serial.print(F("Sending: ")); + root.printTo(Serial); + Serial.println(); -void writeResponse(EthernetClient& client, JsonObject& json) { - client.println("HTTP/1.1 200 OK"); + // Write response headers + client.println("HTTP/1.0 200 OK"); client.println("Content-Type: application/json"); client.println("Connection: close"); client.println(); - json.prettyPrintTo(client); + // Write JSON document + root.prettyPrintTo(client); + + // Disconnect + client.stop(); } -void setup() { - Ethernet.begin(mac, ip); - server.begin(); -} - -void loop() { - EthernetClient client = server.available(); - if (client) { - bool success = readRequest(client); - if (success) { - // Use http://arduinojson.org/assistant/ to - // compute the right size for the buffer - StaticJsonBuffer<500> jsonBuffer; - JsonObject& json = prepareResponse(jsonBuffer); - writeResponse(client, json); - } - delay(1); - client.stop(); - } -} +// See also +// -------- +// +// The website arduinojson.org contains the documentation for all the functions +// used above. It also includes an FAQ that will help you solve any +// serialization problem. +// Please check it out at: https://arduinojson.org/ +// +// The book "Mastering ArduinoJson" contains a tutorial on serialization. +// It begins with a simple example, then adds more features like serializing +// directly to a file or an HTTP client. +// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file diff --git a/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/examples/JsonUdpBeacon/JsonUdpBeacon.ino index 920412d8..95d43ee8 100644 --- a/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -1,57 +1,101 @@ -// Send a JSON object on UDP at regular interval +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2017 +// MIT License // -// You can easily test this program with netcat: -// $ nc -ulp 8888 +// This example shows how to JSON document to a UDP socket. +// At regular interval, it sends a UDP packet that contains the status of +// analog and digital pins. +// The JSON document looks like the following: +// { +// "analog": [ 0, 1, 2, 3, 4, 5 ], +// "digital": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ] +// } // -// by Benoit Blanchon, MIT License 2015-2017 +// If you want to test this program, you need to be able to receive the UDP +// packets. +// For example, you can run netcat on your computer +// $ ncat -ulp 8888 +// See https://nmap.org/ncat/ #include #include #include byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; -IPAddress localIp(192, 168, 0, 177); -IPAddress remoteIp(192, 168, 0, 109); -unsigned int remotePort = 8888; -unsigned localPort = 8888; +IPAddress remoteIp(192, 168, 0, 108); // <- EDIT!!!! +unsigned short remotePort = 8888; +unsigned short localPort = 8888; EthernetUDP udp; -JsonObject& buildJson(JsonBuffer& jsonBuffer) { - JsonObject& root = jsonBuffer.createObject(); - - JsonArray& analogValues = root.createNestedArray("analog"); - for (int pin = 0; pin < 6; pin++) { - int value = analogRead(pin); - analogValues.add(value); - } - - JsonArray& digitalValues = root.createNestedArray("digital"); - for (int pin = 0; pin < 14; pin++) { - int value = digitalRead(pin); - digitalValues.add(value); - } - - return root; -} - -void sendJson(JsonObject& json) { - udp.beginPacket(remoteIp, remotePort); - json.printTo(udp); - udp.println(); - udp.endPacket(); -} - void setup() { - Ethernet.begin(mac, localIp); + // Initialize serial port + Serial.begin(9600); + while (!Serial) continue; + + // Initialize Ethernet libary + if (!Ethernet.begin(mac)) { + Serial.println(F("Failed to initialize Ethernet library")); + return; + } + + // Enable UDP udp.begin(localPort); } void loop() { - delay(1000); + // Allocate JsonBuffer + // Use http://arduinojson.org/assistant/ to compute the right capacity. + StaticJsonBuffer<500> jsonBuffer; - // Use http://arduinojson.org/assistant/ to - // compute the right size for the buffer - StaticJsonBuffer<300> jsonBuffer; - JsonObject& json = buildJson(jsonBuffer); - sendJson(json); + // Create the root object + JsonObject& root = jsonBuffer.createObject(); + + // Create the "analog" array + JsonArray& analogValues = root.createNestedArray("analog"); + for (int pin = 0; pin < 6; pin++) { + // Read the analog input + int value = analogRead(pin); + + // Add the value at the end of the array + analogValues.add(value); + } + + // Create the "digital" array + JsonArray& digitalValues = root.createNestedArray("digital"); + for (int pin = 0; pin < 14; pin++) { + // Read the digital input + int value = digitalRead(pin); + + // Add the value at the end of the array + digitalValues.add(value); + } + + // Log + Serial.print(F("Sending to ")); + Serial.print(remoteIp); + Serial.print(F(" on port ")); + Serial.println(remotePort); + root.printTo(Serial); + + // Send UDP packet + udp.beginPacket(remoteIp, remotePort); + root.printTo(udp); + udp.println(); + udp.endPacket(); + + // Wait + delay(10000); } + +// See also +// -------- +// +// The website arduinojson.org contains the documentation for all the functions +// used above. It also includes an FAQ that will help you solve any +// serialization problem. +// Please check it out at: https://arduinojson.org/ +// +// The book "Mastering ArduinoJson" contains a tutorial on serialization. +// It begins with a simple example, then adds more features like serializing +// directly to a file or any stream. +// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file diff --git a/examples/ProgmemExample/ProgmemExample.ino b/examples/ProgmemExample/ProgmemExample.ino index 2f74ec51..c147e770 100644 --- a/examples/ProgmemExample/ProgmemExample.ino +++ b/examples/ProgmemExample/ProgmemExample.ino @@ -1,18 +1,19 @@ // ArduinoJson - arduinojson.org // Copyright Benoit Blanchon 2014-2017 // MIT License +// +// This example shows the different ways you can use Flash strings with +// ArduinoJson. +// +// Use Flash strings sparingly, because ArduinoJson duplicates them in the +// JsonBuffer. Prefer plain old char*, as they are more efficient in term of +// code size, speed, and memory usage. #include -// About -// ----- -// This example shows the different ways you can use PROGMEM with ArduinoJson. -// Please don't see this as an invitation to use PROGMEM. -// On the contrary, you should always use char[] when possible, it's much more -// efficient in term of code size, speed and memory usage. - void setup() { -#ifdef PROGMEM +#ifdef PROGMEM // <- check that Flash strings are supported + DynamicJsonBuffer jsonBuffer; // You can use a Flash String as your JSON input. @@ -51,3 +52,16 @@ void setup() { void loop() { // not used in this example } + +// See also +// -------- +// +// The website arduinojson.org contains the documentation for all the functions +// used above. It also includes an FAQ that will help you solve any memory +// problem. +// Please check it out at: https://arduinojson.org/ +// +// The book "Mastering ArduinoJson" contains a quick C++ course that explains +// how your microcontroller stores strings in memory. It also tells why you +// should not abuse Flash strings with ArduinoJson. +// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index 3257c05c..495546f0 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -1,16 +1,15 @@ // ArduinoJson - arduinojson.org // Copyright Benoit Blanchon 2014-2017 // MIT License +// +// This example shows the different ways you can use String with ArduinoJson. +// +// Use String objects sparingly, because ArduinoJson duplicates them in the +// JsonBuffer. Prefer plain old char[], as they are more efficient in term of +// code size, speed, and memory usage. #include -// About -// ----- -// This example shows the different ways you can use String with ArduinoJson. -// Please don't see this as an invitation to use String. -// On the contrary, you should always use char[] when possible, it's much more -// efficient in term of code size, speed and memory usage. - void setup() { DynamicJsonBuffer jsonBuffer; @@ -58,3 +57,15 @@ void setup() { void loop() { // not used in this example } + +// See also +// -------- +// +// The website arduinojson.org contains the documentation for all the functions +// used above. It also includes an FAQ that will help you solve any problem. +// Please check it out at: https://arduinojson.org/ +// +// The book "Mastering ArduinoJson" contains a quick C++ course that explains +// how your microcontroller stores strings in memory. On several occasions, it +// shows how you can avoid String in your program. +// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file