Parsing JSON from serialized data

Hi,
I have an arduino+ethernet shield that connects to my website where it returns the following:

//////////////////////////////////////////
HTTP/1.1 200 OK
Date: Wed, 30 Jul 2014 03:20:10 GMT
Server: Apache mod_fcgid/2.3.10-dev
Last-Modified: Tue, 29 Jul 2014 05:53:54 GMT
ETag: "92441da-d-4ff4eaa2fe7ea"
Accept-Ranges: bytes
Content-Length: 13
Connection: close
Content-Type: application/json

{"win":"yes"}
//////////////////////////////////////////

How can I parse {"win":"yes"} out of the serialized data in arduino?

thanks. Cheers.

I did a similar project where I needed to parse out ON from a XML document on a server. This was my approach.

#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 };
char server[] = "XXXXXXXXXXXXXX";    // name address  (using DNS)

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

// 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;

String content = String();    // Empty string to store the GET request string that is later modified
String value;

// numeric IP address
byte serverIP[] = {xxx.xxx.xx.xxx };

void setup() 
{
  Ethernet.begin(mac);  // Get an unused ip address from the network using DHCP
 
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  delay(1000);
  //client.connect(serverIP, 80);
  while (!Serial) 
  {
    ; // wait for serial port to connect. 
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) 
  {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to configure using IP address instead of DHCP:
    Ethernet.begin(mac,ip);
  }
  // give the Ethernet shield time to initialize: (don´t change he value of the delay, otherwise it wont work)
  delay(4000);
}

void loop()
{
  boolean printed = true; 
    
  Serial.println("connecting...");
  // if you get a connection, report back via serial:
  if (client.connect(serverIP, 80)) 
  {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET xxxxx HTTP/1.1");
    client.println("Host: xxxxxxxxxxx");
    client.println("Connection: close");
    client.println();
  } 
  else 
  {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
    
    // if there are incoming bytes available 
    // from the server, read them and add to the string:
   while(printed)
   {
    if (client.available()) 
    {
      char c = client.read();   // Read one byte 
      content += String(c);   // Make it o a string and add it to the result string...
    }
    
    // if the server's disconnected, stop the client:
    if (!client.connected()) 
    {
      Serial.println(content);
      // Find the <Value> and </Value> tags and make a substring of the content between the two

      int startValue = content.indexOf("<Value>");
      int endValue = content.indexOf("</Value>");
      value = content.substring(startValue + 7, endValue);    // + 7 to make the index start after the <Value> tag
      Serial.println(value);                                  // The string/content between the <Value> and </Value> tags
      Serial.println();
      Serial.println("disconnecting.");
      client.stop();

      printed = false;      // When you reach this, you got what you wanted and can start over 
    }
   }
    delay(3000);     // Decide how often you want to retrieve new values (x seconds * 1000)
}

You would want to change the indexOf(""); To indexOf("{"); And To } and make the substring between startvalue and endvalue +1 or something, you would have to experiment a little :slight_smile:

Serial.println(value) should print the parsed string you want

modernrockstar:
How can I parse {"win":"yes"} out of the serialized data in arduino?

Do you want both fields, or just the "yes" string?

For each field you want to keep, you need to read and discard everything up to the start of that field and then read and buffer everything up to the end of the field. Since the fields are delimited by unique character sequences {", ":", "} that is easy to do. You can do it either using a little state machine to keep track of where you are in the parsing sequence, or by buffering the whole lot and using strstr() to detect where the delimiters are within the buffer and then using strncpy() to extract the part you want to keep into a separate buffer.

If you only want to know whether the value is "yes" or "no" it gets even easier - you can just use strstr() to test whether the input buffer contains "win":"yes" or "win":"no".