Interpret the JSON response of a WebService that was called by the Arduino

1

How do I interpret information from a WebService that was called by Arduino?

The WebService returns a JSON and needs to interpret it. An example of the answer can be seen below:

[{"valor":"10"}] 

The code below, obtained from this site , shows the call and the interpretation, but a byte is read by time, and therefore I have questions about how I could do this for the return in JSON.

The part that reads one byte at a time can be seen below:

if (client.available()) {
  char c = client.read();
  Serial.print(c);
}

Full Code:

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "www.google.com";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 177);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /search?q=arduino HTTP/1.1");
    client.println("Host: www.google.com");
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while (true);
  }
}
    
asked by anonymous 02.12.2015 / 14:53

1 answer

2

Unlike in high-level languages such as Python and PHP, in C (especially in Arduino) when making a request, a character will be returned per character from the web service and there are no ready-to-use functions.

In case, if you print this in your serial, it will seem that everything has arrived at a single time, but make no mistake. To receive data from a web service you need to read the data received, byte by byte, save in a buffer. First you must filter the headers, since they are usually not useful, when you receive two /r/n you will know that the HTTP header is gone, so buffer the body of your response.

When the client completes the request, perform a parser in the buffer fetching its information. It's really all at hand, it does not have functions ready for this kind of situation and all the libraries I've used to parse JSON in C are heavy and spend almost all Arduino memory.

Example of how I get the response value and saved in a buffer

[... monte de código acima...]
while (http.connected()) {
            while (http.available()) {

                char read_char = http.read();
                Serial.print(read_char); /* Imprime resposta do servidor */

                if (read_char != '\n' && newLine != 1) {
                  resposta[i] = read_char;
                  i++;
                  resposta[i] = '
[... monte de código acima...]
while (http.connected()) {
            while (http.available()) {

                char read_char = http.read();
                Serial.print(read_char); /* Imprime resposta do servidor */

                if (read_char != '\n' && newLine != 1) {
                  resposta[i] = read_char;
                  i++;
                  resposta[i] = '%pre%';
                }

                if (read_char == '\n') {
                  newLine = 1;
                }
            }

            i = 0;
        }
[... monte de código abaixo....]
'; } if (read_char == '\n') { newLine = 1; } } i = 0; } [... monte de código abaixo....]

After that I have in the response variable what the server returned me, then I use strtok to break the response into pieces

In your example, you have the statement char c = client.read(); , that's where you'll get the answer from the server, the problem is that it only has one character, so you'll have to go throwing it in a matrix to get the whole read the answer. Then, at another point, when interpreting what arrived from the server, it reads this array of characters (string) and search for what you want

    
02.12.2015 / 16:46