GithubHelp home page GithubHelp logo

interactive-matter / ajson Goto Github PK

View Code? Open in Web Editor NEW
566.0 566.0 136.0 443 KB

aJson is an Arduino library to enable JSON processing with Arduino. It easily enables you to decode, create, manipulate and encode JSON directly from and to data structures.

Home Page: http://interactive-matter.org/2010/08/ajson-handle-json-with-arduino/

Arduino 22.75% C 8.52% C++ 68.73%

ajson's People

Contributors

elafargue avatar interactive-matter avatar ivankravets avatar justjoheinz avatar lasselukkari avatar lolsborn avatar nickdademo avatar pasky avatar probonopd avatar shazeline avatar sudar avatar thomasaw avatar tinacolemannextcentury avatar zsalzbank avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ajson's Issues

JSON string not parsing properly

Hi, I have been trying to parse this string using aJson

{ "songs": [ { "name": "Song Of Time", "notes": [69, 62, 65, 69, 62, 65, 69, 72, 71, 67, 65, 67, 69, 62, 60, 64, 62], "times": [600, 900, 600, 600, 900, 600, 300, 300, 600, 600, 300, 300, 600, 600, 300, 300, 900], "nunchuck": [3, 1, 2, 3, 1, 2] } ] }

using this code

aJsonObject* root = aJson.parse(songText);
  aJsonObject* songData = aJson.getObjectItem(root, "songs");
  aJsonObject* song = aJson.getArrayItem(songData, 0);
  aJsonObject* songName = aJson.getObjectItem(song, "name");
  songs[0].name = songName->valuestring;
  aJsonObject* noteData = aJson.getObjectItem(song, "notes");
  aJsonObject* timeData = aJson.getObjectItem(song, "times"); 
  int numberNotes = aJson.getArraySize(noteData);
  for (int i = 0; i < numberNotes; i++) {
    aJsonObject* note = aJson.getArrayItem(noteData, i);
    aJsonObject* time = aJson.getArrayItem(timeData, i);
    songs[0].notes.push_back(note->valueint);
    songs[0].notes.push_back(time->valueint);
  }
  aJsonObject* nunchuckData = aJson.getObjectItem(song, "nunchuck");
  int numberNunchuck = aJson.getArraySize(nunchuckData);
  for (int i = 0; i < numberNunchuck; i++) {
    aJsonObject* note = aJson.getArrayItem(nunchuckData, i);
    songs[0].nunchuck_notes.push_back(note->valueint);
  }

And have been getting an empty string for the name, and usually identical random numbers for the other two. I am not sure what the issue is here, but I don't think it is memory as I had 651 bytes of memory remaining when I checked. Could it be the extra whitespace in the string?

Not able to parse a string

In the following simplified example, I can load an aJsonObject "root" but when I parse the string created json_string, I cant get back any object items.
Arduino Mega, latest IDE and aJason lib from here.

include <aJSON.h>

char *tmp;
char *stringptr;
//stringptr = "{"response":{"status":"OK","uid":"3","sid":"6283"}}";
char *json_string = "{"name": "Jack ("Bee") Nimble","format": {"type": "rect","width": 1920,"height": 1080,"interlace": false,"frame rate": 24}}";
//stringptr = json;

void setup(void) {
Serial.begin(9600);
}

void loop(void) {

aJsonObject* root = aJson.createObject();
aJson.addItemToObject(root, "name", aJson.createItem(
"Jack ("Bee") Nimble"));
aJson.addItemToObject(root, "response", aJson.createItem(
"ok"));
aJson.addItemToObject(root, "status", aJson.createItem(
"ok"));
aJson.addItemToObject(root, "uid", aJson.createItem(
"ok"));
aJson.addItemToObject(root, "sid", aJson.createItem(
"sid"));

// Parsing...
aJsonObject* jsonObject = aJson.parse(json_string);
// Printing...
tmp = aJson.print(jsonObject);
Serial.println(tmp);

aJsonObject* name = aJson.getObjectItem(jsonObject, "name"); // Can get object for "root" but not parsed "jsonObject"
if (name != NULL) {
Serial.println(name->valuestring);
}
}

aJson.deleteItem issue

When calling aJson.deleteItem multiple times, the Arduino sketch crashes. To replicate, try running the following:

String test = String("{ \"name\": \"Jack Nimble\", \"format\": { \"type\": \"rect\", \"width\": 1920, \"height\": 1080, \"interlace\": false, \"frame rate\": 24 } }");

Serial.println("Parse JSON 1");
aJsonObject* json = aJson.parse(test);
aJson.deleteItem(json);

Serial.println("Parse JSON 2");
aJsonObject* json2 = aJson.parse(test);
aJson.deleteItem(json2);

Serial.println("Parse JSON 3");
aJsonObject* json3 = aJson.parse(test);
aJson.deleteItem(json3);

Serial.println("Parse JSON 4");
aJsonObject* json4 = aJson.parse(test);
aJson.deleteItem(json4);

Serial.println("Parse complete");

Typically, this fails on the second deleteItem call.

Parse from EthernetClient?

I noticed there's a way to parse from a FILE*, but is there a way to parse from an EthernetClient?

I have this set up with a TCP server, and it would be great to have this parse as data comes in. Right now I'm just mallocing a char* big enough for the data and passing that in to aJson.parse (I'm using a WebSocket-like protocol, so I know the size), but it would be great to have aJson handle that for me. That way less memory needs to be allocated at a time.

What do you think?

aJson.deleteItem(root) does not free the used memory

I tried to parse the input from Serial and then free the memory with deleteItem.
But I don't get it back.

**** sketch begin ******
extern uint8_t* __brkval;
extern uint8_t __heap_start;

include "aJSON.h"

void setup() {
Serial.begin(9600);
Serial.println("aJsonMemChecker");
}

void loop() {
if (Serial.available()) {
char input[101];
readln (&Serial, input, 100);
Serial.println(input);

aJsonObject* root;
printFreeRam("before parsing");
root = aJson.parse(input);
printFreeRam("after parsing");
aJson.deleteItem(root);
printFreeRam("after freeing");

}
}

int freeRAM () {
int v;
int mem = ((__brkval == 0) ? (int) &__heap_start : (int) __brkval);
return ((int) &v - mem);
}

void printFreeRam(const char* msg) {
Serial.print(msg);
Serial.print(" free RAM: ");
Serial.println(freeRAM());
}

void readln(Stream stream, char *buffer, uint8_t buflen) {
int length = stream -> readBytesUntil('\n', buffer, buflen);
buffer[length] = '\0';
}
*
** sketch end ******

**** console begin ******
aJsonMemChecker
{}
before parsing free RAM: 1336
after parsing free RAM: 1321
after freeing free RAM: 1321
{"plug":{"name":"B","code":"11111","set":"on"}}
before parsing free RAM: 1321
after parsing free RAM: 1209
after freeing free RAM: 1209
{"plug":{"name":"B","code":"11111","set":"on"}}
before parsing free RAM: 1209
after parsing free RAM: 1209
after freeing free RAM: 1209
{}
before parsing free RAM: 1209
after parsing free RAM: 1209
after freeing free RAM: 1209
**** console end ******

I expect to have 1336 Bytes available in each loop.
But aJson require more memory in depending of the input string in parse().

Used arduino is Duemilanove with 328P.

Dictionary support

Often the key names are repeated in many different objects. For example you have an array of objects where each object contains the same keys. Currently all the key values point to separate strings when they could be the same string in the memory.

I have created a fork where the user can supply a dictionary in form of NULL terminated string array:
the changes can be seen here: lasselukkari@498fac5

Is this something you think would be usefull to others too?

Changing numbers

Hey Marcus,

This is Marcus here too. hehe.

I am trying to change a simple int value, but I don't know what I am doing wrong. The test code is:

root = aJson.createObject();
readings = aJson.createObject();

aJson.addItemToObject(root, "readings", readings);
aJson.addNumberToObject(readings, "ldrvalue", 0);

Serial.println(aJson.print(root));

aJsonObject* readings = aJson.getObjectItem(root, "readings");
aJsonObject* ldrvalue = aJson.getObjectItem(readings, "ldrvalue");
ldrvalue->value.number.valueint = 180;

Serial.println(aJson.print(root));

The output show:

{"readings":{"ldrvalue":0}}
{"readings":{"ldrvalue":?}}

It didn't change to 180. :(

If I declare it as string I can successfully change this string, but no luck with int.

What am I doing wrong?

Thanks.

Marcus Ferreira

Can't print null-values

The aJson.print function fails to output null-values properly. The problem seems to be a typo in line 582 in aJson.cpp:
result = fprintf(stream, PSTR("null"));
Which should instead read:
result = fprintf_P(stream, PSTR("null"));

floats with numbers after the dot (e.g., 40.5) are parsed incorrectly

We found another issue in the aJSON lib: floats with numbers after the dot (e.g., 40.5) are parsed incorrectly. Our fix:

In file aJSON.cpp in function aJsonClass::parseNumber (Line 130) changed

unsigned char scale = 0;

to

int scale = 0;

Mind, though, that we have not tested this fix with numbers containing exponents.

Compiling Default Examples Code Wrong

compiling default examples show me next errors:
.../Arduino/libraries/aJson/aJSON.h:242: error: a class-key must be used when declaring a friend
.../Arduino/libraries/aJson/aJSON.h:242: error: friend declaration does not name a class or function

Im using arduino uno board

Negative integers parsed incorrectly on Arduino Due

I haven't tested this on a non-Due, but on the Due, a negative number is parsed as a big positive integer, so I'm guessing this has to do with the word size differences. I need to fix it sooner rather than later, so as soon as I come up with something, I'll submit a pull request. Just wanted to bring it up.

Port to SAM3X8E (Ardunio Due)

The library does not compile for the new ARM-Based boards. The issue is probably some dependence on the avr progmem library.

Array (using square brackets) supported ?

Hi there,

Is this json supported:

{
"id": 1,
"name": "A green door",
"tags": [
{ "color" : "green", "code" : "00FF00" },
{ "color" : "red", "code" : "FF0000" }
]
}

Specifically, is the "tags" array supported ?

Any examples on how to parse and traverse this example using aJson would be great :)

Thanks!

aJson.parse changing value of double

I have a 5 digit precision double that I'm trying to parse and it seems to get munged by the parse method. The following test code shows the problem. The output will be:

Full string={"laserWavelen":638.12345}
Total json={"laserWavelen":638.12360}

The last two digits always seem to get screwed up. Any ideas how to fix this?

include <aJSON.h>

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
char json_string[] = "{"laserWavelen":638.12345}\0";

aJsonObject* jsonObject = aJson.parse(json_string);

Serial.print("Full string=");
Serial.println( json_string );

Serial.print("Total json=");
char *p = aJson.print(jsonObject);
if (p != NULL) {
Serial.println(p);
free(p);
}
else
Serial.println("NULL!");

aJson.deleteItem(jsonObject);

delay(5000);
}

Add addStringToObject with String to aJSON Library

Add addStringToObject with String to aJSON library. Up to now, it only accepts const char* s.

    void addBooleanToObject(aJsonObject* object, const char* name, bool b);
    void addTrueToObject(aJsonObject* object, const char* name);
    void addFalseToObject(aJsonObject* object, const char* name);
    void addNumberToObject(aJsonObject* object, const char* name, int n);
    void addNumberToObject(aJsonObject* object, const char* name, double n);
    void addStringToObject(aJsonObject* object, const char* name, const char* s);

From Energia project

ERROR

d:/program files/arduino-1.0.4/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr5\libc.a(malloc.o): In function malloc': (.text+0x0): multiple definition ofmalloc'
core.a(malloc.c.o):D:\Program Files\arduino-1.0.4\hardware\arduino\cores\arduino/malloc.c:82: first defined here
d:/program files/arduino-1.0.4/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr5\libc.a(malloc.o): In function free': (.text+0x154): multiple definition offree'
core.a(malloc.c.o):D:\Program Files\arduino-1.0.4\hardware\arduino\cores\arduino/malloc.c:194: first defined here

valuefloat returns 0.00

  aJsonObject* sBoard = aJson.createObject();
  aJsonObject* sensorType = aJson.createObject();

  aJsonObject* sBoard = aJson.createObject();
  aJsonObject* sensorType = aJson.createObject();

  aJson.addItemToObject(sBoard, "name", aJson.createItem("SensorBoardOne"));
  aJson.addItemToObject(sBoard, "Sensor", sensorType);

  aJson.addNumberToObject(sensorType, "ph", 5.33);
  aJson.addNumberToObject(sensorType, "ec", 880);
  aJson.addNumberToObject(sensorType, "temp", 74.68);

  aJsonObject* ph = aJson.getObjectItem(sensorType, "ph");

  Serial.println(ph->valuefloat);

valuefloat returns 0.00. I have never dealt with C structs before and not sure if I setup the syntax correctly. My json structure seems fairly straight forward; however, I am not sure if I am accessing the correct creatObject() for the ph float value. What should I do to get the value of ph?

Problem with floats when printing a Json object

By default, Arduino uses a lightweight version of sprintf that doesn't support floats and doubles. If you create a Json object and add the value a = 12.34, you would expect something like this when calling the print function:
{"a": 12.34}
Instead aJson returns this:
{"a": ?}

On the Arduino forums there are several threads about this limitation, and there seems to be two solutions:

  1. Modify the compiler options so the full sprintf is included. Unfortunately, there is currently no way of altering the compiler options from within the Arduino IDE.
  2. Implement a similar functionality from scratch.

->valuestring appears to have a 256 byte limit.

I'm storing a few KB of data in base64 format in a json file.

The library handles parsing the entire thing perfectly but when it comes to extracting the valuestring from an object, it only returns the first 256 bytes.

I have plenty of free RAM and the program continues to run, just without the full string. Not sure why this is.

objects on arduino

A question about the read me:

This is an object. We're in C. We don't have objects. But we do have structs. Therefore the objects are translated into structs, with all the drawbacks it brings.

If I'm not mistaken, arduino supports a c/c++ implementation and should have not problems with objects and instances.

Wouldn't that make much more sense for a library like this?

Compatibility with Bluetooth Shield

Hi All,

I noticed that I can not use this library in conduction with the Bluetooth shield because of memory issues. Is there any way to reduce the memory foortprint?

stringbuffer or streamhelper causing DHCP to fail

Hi there,

I am having trouble with connecting using DHCP when using aJson. It still connects fine when I am using functions that dont require the utility code, but when I add aJson.parse(), suddenly DHCP doesn't work. I am guessing this is because a certain function or global variable in the utility functions are overriding something used by the EthernetClient module. Is there a fix for this? Thanks in advance :)

PS. This is my code:

#include <aJSON.h>

/*
  Web client

 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 

 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13

 created 18 Dec 2009
 modified 9 Apr 2012
 by David A. Mellis

 */

#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 };
IPAddress server(192,168,1,3); // Local server
char json[1024] = "";
int count = 0;
int start = 0;

// 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 Leonardo only
  }

  // start the Ethernet connection:
  Serial.println("Setting up Ethernet");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  Serial.println("Success!");
  // 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, 5000)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /pattern HTTP/1.0");
    client.println();
  } 
  else {
    // kf 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();    

    // relevant data is stored to json global String

    if (start) {
      json[count++] = c;
    } else {
      if (c == '{') {
        start = 1;
        json[count++] = c;
      }
    }
  }


  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    json[count] = '\0';
    Serial.println(json);
    start = 0;
    count = 0;

    //Parse JSON
    aJsonObject* root = aJson.createObject();
    root = aJson.parse(json); //removing this line makes DHCP work

    // do nothing forevermore:
    for(;;)
      ;
  }
}

Spaces after valuestring cannot be skipped

A Json string like:

{"name":value" }

cannot be parsed correctly, the spaces after the value didn't be skipped.

To resolve this problem, in aJSON.cpp, add a line after 766 before 767:

skip(stream);

Problem freeing memory

Hi!
I'm trying to make an arduino Sketch which loads the Ethernet configuration from a JSON encoded file on the SD card using the aJson library. For that I pass an aJsonObject pointer to a subroutine called parse_SDfile. The problem is that each time the subroutine is called the amount of free memory decreases until the Arduino gets blocked.
I've tried several approaches (pass the pointer by reference, pass a pointer to the pointer, try to copy the pointer contents...) none of them working.
I don't know is a problem with the library, with the compiler or with my code itself, but I hope you could help me to solve this issue.
My code:

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

#include <aJSON.h>

const byte SDchip_select = 4; //depends on shield type
uint8_t mac[6] = {0x90, 0xA2, 0xDA, 0x0D, 0x23, 0x47};

void SD_setup(){
    pinMode(53, OUTPUT);     // change this to 10 for a non mega
    if (!SD.begin(SDchip_select)){
        Serial.println("SD initialization failed.");
    }
    else{
        Serial.println("SD OK.");
    }
}

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

void get_json_array(aJsonObject* json_array, uint8_t array_obj[], unsigned int array_size){
    for(unsigned char i = 0; i < array_size; i++ ){
        array_obj[i] = aJson.getArrayItem(json_array, i)->valueint;
    }
}

short int parse_SDfile(char* filename, aJsonObject** parsed_json)
{
    File SD_file = SD.open(filename);
    aJsonStream SD_stream(&SD_file);
    //aJsonObject* temp_json;

    if(SD_stream.available())
    {
        *parsed_json = aJson.parse(&SD_stream);

        //another approach trying to copy the contents of the ajson pointer
        //*parsed_json = aJson.parse(&SD_stream);
        //*parsed_json = *temp_json;
        //aJson.deleteItem(temp_json);
        return 0;
    }
    else
    {
        Serial.print(F("Error parsing file: "));
        Serial.println(filename);
        return -1;
    }

    SD_file.close();
}

void ethernet_setup(char* filename)
{
    Serial.println("Starting ethernet config");

    aJsonObject* ethconfig_json;
    aJsonObject* DHCP_json;
    aJsonObject* ip_json;
    aJsonObject* dns_json;
    aJsonObject* gateway_json;
    aJsonObject* subnet_json;

    bool DHCP;
    uint8_t ip_array[4];
    uint8_t dns_array[4];
    uint8_t gateway_array[4];
    uint8_t subnet_array[4];

    if(parse_SDfile(filename, &ethconfig_json) < 0)
    {
        return;
    }

    DHCP_json = aJson.getObjectItem(ethconfig_json, "DHCP");
    DHCP = DHCP_json->valuebool;

    if(!DHCP){
        //Get the ethernet config parameters from json object
        ip_json = aJson.getObjectItem(ethconfig_json, "ip");
        get_json_array(ip_json, ip_array, 4);

        dns_json = aJson.getObjectItem(ethconfig_json, "dns");
        get_json_array(dns_json, dns_array, 4);

        gateway_json = aJson.getObjectItem(ethconfig_json, "gateway");
        get_json_array(gateway_json, gateway_array, 4);

        subnet_json = aJson.getObjectItem(ethconfig_json, "subnet");
        get_json_array(subnet_json, subnet_array, 4);

        //Start the ethernet card with the config parameters
        Ethernet.begin(mac, ip_array, dns_array, gateway_array, subnet_array);
    }
    else{    
        Ethernet.begin(mac);
    }

    //delete json object
    aJson.deleteItem(ethconfig_json);

    Serial.println("Ethernet setup end.");
}

void setup() {
    Serial.begin(9600);
    SD_setup();

}

void loop() {
    ethernet_setup("ethconf.ini");
    Serial.println(freeRam());
    delay(200);  
}

The funny thing it's if I replace the subroutine call for the code inside the subroutine everything goes well. Maybe it's a problem with the variables' scope?How could I solve this problem?

Thank you very much!

Array example?

Any chance of getting an example that shows how to work with Arrays? Thanks!

bug on printing added null object

In aJSON.cpp (line 582) the null object is printed with a fprinf i.s.o. fprintf_P, resulting in the wrong out in the aJson.print().

Kind regards.

-- corrected code ---
switch (item->type)
{
case aJson_NULL:
result = fprintf_P(stream, PSTR("null"));
break;

YUN problem with Serial Monitor

On two separate Arduino Yuns on two separate laptops, I can't get MultiLevelParsing Example to Run. I just get no output in the Serial Monitor.

I've checked the Baud Rates. I've run Examples>Json_Serial and the Serial Monitor works fine there.

Any clue?

Could not get multiple results

With the code below, I could not get next result. Only first query result show up then halt right after the first success function "parseJson" .It does not print the "Circle" after the function.

include <aJSON.h>

char jsonString[256];

void setup() {
String js="";
Serial.begin(115200);
Serial.println(jsonString);
Serial.println("Starting to parse");
js+="{";
js+= ""query":{"count":1,"created":"2012-08-04T14:46:03Z","lang":"en-US","results":{"item":{"title":"Handling FTP usernames with @ in them"}}},";
js+= ""circle0":{"x":5,"y":10,"r":15},";
js+= ""string0":{"x":20,"y":25}";
js+="}";
js.toCharArray(jsonString,sizeof(jsonString));
//Serial.println("Circle");
//parseCircle(jsonString);
//Serial.println("String");
//parseString(jsonString);
parseJson(jsonString);
Serial.println("Circle");
}
boolean parseJson(char jsonString){
aJsonObject *root=aJson.parse(jsonString);
if(root!=NULL){
aJsonObject
query = aJson.getObjectItem(root, "query");
if (query != NULL) {
//Serial.println("Parsed successfully 2 " );
aJsonObject* results = aJson.getObjectItem(query, "results");

  if (results != NULL) {
    //Serial.println("Parsed successfully 3 " );
    aJsonObject* item = aJson.getObjectItem(results, "item"); 

    if (item != NULL) {
      //Serial.println("Parsed successfully 4 " );
      aJsonObject* title = aJson.getObjectItem(item, "title"); 

      if (title != NULL) {
        //Serial.println("Parsed successfully 5 " );
        //value = title->valuestring;
        Serial.println(title->valuestring);
        Serial.println("After print?");
        aJson.deleteItem(title);
      }
      aJson.deleteItem(item);
    }
    aJson.deleteItem(results);
  }
  aJson.deleteItem(query);
}
aJson.deleteItem(root);    

}
Serial.println("Out");
return true;
}
boolean parseCircle(char jsonString)
{
aJsonObject
root = aJson.parse(jsonString);
if (root != NULL) {
aJsonObject circle=aJson.getObjectItem(root,"circle0");
if(circle!=NULL){
aJsonObject *x=aJson.getObjectItem(circle,"x");
if(x!=NULL){
if(x->type==aJson_Int){
Serial.print("Circle x:");
Serial.println(x->valueint);
}
aJson.deleteItem(x);
}
else{
Serial.print("Circle x null");
}
aJson.deleteItem(circle);
}
else{
Serial.println("Circle Null");
}
//aJson.deleteItem(root);
}
else{
Serial.println("Circle root null");
}
}
boolean parseString(char *jsonString)
{
aJsonObject
root = aJson.parse(jsonString);
if (root != NULL) {
aJsonObject *string=aJson.getObjectItem(root,"string0");
if(string!=NULL){
aJsonObject *x=aJson.getObjectItem(string,"x");
if(x!=NULL){
if(x->type==aJson_Int){
Serial.print("string0 x:");
Serial.println(x->valueint);
}
aJson.deleteItem(x);
}
else{
Serial.print("String x null");
}
aJson.deleteItem(string);
}
else{
Serial.println("String Null");
}
//aJson.deleteItem(root);
}
else{
Serial.println("String root null");
}
}

void loop() {
// Nothing to do
;
}

Escape slash / too

Hello,

Could you also escape this slash / in parseString? Otherwise, it's lost.
switch (in)
{
case '':
stringBufferAdd('', buffer);
break;
case '/':
stringBufferAdd('/', buffer);
break;
case '"':
stringBufferAdd('"', buffer);
break;

usage with HTTPClient ?

I'm trying to use HTTPClient and aJson in the same sketch. (both from master branch on github)

But HTTPClient use FILE* and aJson use Stream

I can't find a way to use the stream from a HTTPClient getURI to feed a aJson.parse

The example don't work:

HTTPClient client ("192.168.0.x", server, 4567);
FILE* result = client.getURI( UNREAD_URI, NULL, NULL );
aJsonObject* jsonObject = aJson.parse(result);

generate the compilation error:

no matching function for call to 'aJsonClass::parse(__file*&)
aJSON.h:179: note: candidates are: aJsonObject* aJsonClass::parse(aJsonStream*)
aJSON.h:180: note:                 aJsonObject* aJsonClass::parse(aJsonStream*, char**)
aJSON.h:181: note:                 aJsonObject* aJsonClass::parse(char*)

If I create a string from the HTTP stream and feed it to the parse method, it work.

Any idea to resolve this ?

Memory problem with print function

Hello Marcus, maybe i'm doing something wrong but I have a memory problem with the print function to render the JSON object to a string. This results in a unstable device and strange behaviour. Every time the char *json_String=aJson.print(root); command is run I loose some free memory.

My goal: Run a webserver which supplies measurement values in JSON format.

My environment: Arduino 0021 with Duemilanova and ethershield

Sample source displaying the problem:

#include 
#include 
#include 
#include 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,0,177 };
Server server(80);

// OperatingVoltage
float OperatingVoltage=4.732;

// select the input pin for the LM35
int potPin35 = 0;

// select the input pin for the LM335 inside
int potPin335i = 1;

// select the input pin for the LM335 outside
int potPin335o = 2;

// select the input pin for the Light sensor
int potPinLight = 4;

// variable to store the value coming from the sensor 
float temperature = 0;
float volt = 0;

// variable to temporary store results from analog read actions
float val = 0;

char* tmpstr = "";

void setup()
{
  Serial.println ("setup()");
  mem();
  
  // start the Ethernet connection and the server:
  Serial.println ("Ethernet.begin");
  Ethernet.begin(mac, ip);
  Serial.println ("server.begin");
  server.begin();
  
  Serial.println ("Pinmode etc.");
  pinMode(A0, INPUT);
  digitalWrite(A0, LOW);
  analogReference(DEFAULT);
  
  Serial.println ("Serial.begin");
  Serial.begin(9600);
  
  // give the sensor and Ethernet shield time to set up:
  delay(1000);
}

void loop()
{
  // listen for incoming clients
  Client client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) {
          Serial.println ("And we are starting to work for this request");
          mem();
          
          Serial.println ("Let's create the JSON object");
          mem();
          aJsonObject* root = aJson.createObject();
          Serial.println ("After creating the JSON object");
          mem();

          Serial.println ("Let's put some variables in the JSON object");
          mem();
          aJson.addItemToObject(root, "LM35v", aJson.createItem("0.208"));
          aJson.addItemToObject(root, "LM35c", aJson.createItem("20.815"));
          aJson.addItemToObject(root, "LM335v", aJson.createItem("2.928"));
          aJson.addItemToObject(root, "LM335c", aJson.createItem("19.651"));
          aJson.addItemToObject(root, "LM335vOutside", aJson.createItem("2.794"));
          aJson.addItemToObject(root, "LM335cOutside", aJson.createItem("6.237"));
          aJson.addItemToObject(root, "Light", aJson.createItem("62"));
          Serial.println ("After put some variables in the JSON object");
          mem();

          Serial.println ("Before populating the string with the the JSON object");
          mem();
          char *json_String=aJson.print(root);
          Serial.println ("After populating the string with the the JSON object");
          mem();
          
          // send a standard http response header
          Serial.println ("Printing out the web page");
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: application/json");
          client.println();
          client.print(json_String);
          Serial.println ("The JSON string we just printed contains:");
          Serial.println (json_String);
          client.println();

          Serial.println ("Before aJson.deleteItem(root)");
          delay(200);
          mem();
          aJson.deleteItem(root);
          Serial.println ("After aJson.deleteItem(root)");
          mem();
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line                                               
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    Serial.println ("Beore closing down the client connection");
    mem();
    client.stop();
    Serial.println ("After closing down the client connection");
    mem();
    Serial.println ("\n");
  }
}

extern unsigned int __bss_end;
extern void *__brkval;

int get_free_memory()
{
  int free_memory;

  if((int)__brkval == 0)
     free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);

  return free_memory;
}

void mem(void)                
{
  Serial.print("free_memory():");
  Serial.println( get_free_memory() );
  delay(10);
}

Serial output first run:

And we are starting to work for this request
free_memory():765
Let's create the JSON object
free_memory():765
After creating the JSON object
free_memory():750
Let's put some variables in the JSON object
free_memory():750
After put some variables in the JSON object
free_memory():516
Before populating the string with the the JSON object
free_memory():516
After populating the string with the the JSON object
free_memory():359
Printing out the web page
The JSON string we just printed contains:
{"LM35v":"0.208","LM35c":"20.815","LM335v":"2.928","LM335c":"19.651","LM335vOutside":"2.794","LM335cOutside":"6.237","Light":"62"}
Before aJson.deleteItem(root)
free_memory():359
After aJson.deleteItem(root)
free_memory():359
Beore closing down the client connection
free_memory():359
After closing down the client connection
free_memory():359

Serial output second run:

And we are starting to work for this request
free_memory():359
Let's create the JSON object
free_memory():359
After creating the JSON object
free_memory():359
Let's put some variables in the JSON object
free_memory():359
After put some variables in the JSON object
free_memory():359
Before populating the string with the the JSON object
free_memory():359
After populating the string with the the JSON object
free_memory():226
Printing out the web page
The JSON string we just printed contains:
{"LM35v":"0.208","LM35c":"20.815","LM335v":"2.928","LM335c":"19.651","LM335vOutside":"2.794","LM335cOutside":"6.237","Light":"62"}
Before aJson.deleteItem(root)
free_memory():226
After aJson.deleteItem(root)
free_memory():226
Beore closing down the client connection
free_memory():226
After closing down the client connection
free_memory():226

As you can see I'm loosing memory and after I request the webpage four times it will display me garbage or not respond anymore. The problem might be in my excellent programming skills :-) or in your great library. I hop you can help.

Thanks, Janno

Memory Leak in print() function?

I found that when I try to print the JSON string, there's a memory leak. Not sure if it's related to the other issues with memory leak. Try running the following sketch:

#include <aJSON.h>

void setup() {
  Serial.begin(9600);

  freeMem("start 1");
  aJsonObject* root = aJson.createObject();
  aJsonObject *neck;
  aJson.addItemToObject(root, "val",  neck = aJson.createItem(123.45)); 
  Serial.println(aJson.print(root));
  aJson.deleteItem(root);
  freeMem("end 1"); 

  Serial.println();

  freeMem("start 2");
  aJsonObject* root1 = aJson.createObject();
  aJsonObject *neck1;
  aJson.addItemToObject(root1, "val",  neck1 = aJson.createItem("123.45")); 
  Serial.println("{\"val\":123.45}");
  aJson.deleteItem(root1);
  freeMem("end 2"); 
}

void loop() {

}

//Code to print out the free memory

extern unsigned int __heap_start;
extern void *__brkval;

/*
 * The free list structure as maintained by the 
 * avr-libc memory allocation routines.
 */
struct __freelist {
  size_t sz;
  struct __freelist *nx;
};

/* The head of the free list structure */
extern struct __freelist *__flp;

/* Calculates the size of the free list */
int freeListSize() {
  struct __freelist* current;
  int total = 0;

  for (current = __flp; current; current = current->nx) {
    total += 2; /* Add two bytes for the memory block's header  */
    total += (int) current->sz;
  }
  return total;
}

int freeMemory() {
  int free_memory;

  if ((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__heap_start);
  } else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
    free_memory += freeListSize();
  }
  return free_memory;
}

void freeMem(char* message) {
  Serial.print(message);
  Serial.print(": ");
  Serial.println(freeMemory());
}

I'm going to see if i can find a fix but thought I'd post to let you know. If anyone can recommend a clean fix, i'm all ears!

have problem to parsing json string larger than 240 bytes

Hi, I have problem to parsing a json string (see below) that is larger than 240 bytes. It seems no problem if if reduce the size of json string. For example, I have no problem to parse, if I limit the array size to 5, i.e. delete all the array element after 5th.

Is there any size limit on the json string to be handled?

Thanks

Compatibility with SD.h

I tried to use the aJson and SD libraries at the same time, but it doesn't.
I get wrong Json objects by just including the SD.h library on my sketch

Any ideas why?

Best Regards
Guilherme

Can you create a very simple sketch that follows the filtering example described in the readme?

I will be the first to admit that I am not a strong programmer in C/C++. I could really use an example sketch that uses the "Filtering while parsing" method described in the README.md file. It would help me through the following problem

I was getting an error while compiling that the "scalar object requires one element in initializer". To my understanding, the use of the char** is a pointer to a pointer but I honestly don't know what is needed to initialize this correctly:
char** jsonFilter = {"name,"format","height","width",NULL};

Also of note, there is a missing close quote after {"name in the README file.

Example code wrong

The example code in the README, section "3. Creating JSON Objects from code" refers to a function aJson.createString("Jack ("Bee") Nimble") which doesn't exist in latest release. Problably a left-over.

error: no matching function for call to aJsonClass::parse

I'm trying to parse json from a file stream as described in the readme:

File file = SD.open(fileName);
aJsonObject* jsonObject = aJson.parse(file);

but I get this error:
error: no matching function for call to ‘aJsonClass::parse(File&)’

Compile Error With Arduino Uno

I have downloaded and unzipped the library. This is the path where it is:
C:\Program Files (x86)\Arduino\libraries\aJson\aJson

Examples from the aJSON library can be seen, but error while compiling the code.
Error Message: Arduino: 1.6.0 (Windows 7), Board: "Arduino Uno"

Build options changed, rebuilding all

test_jason.ino:4:19: fatal error: aJSON.h: No such file or directory
compilation terminated.
Error compiling.

aJson.delete(root); doesn't compile on arduino 1.0

aJsonObject* root = aJson.createObject();
aJson.addNumberToObject(root, "relaisCpu", ra);
aJson.addNumberToObject(root, "relaisVer", rb);
aJson.addNumberToObject(root, "relaisK", rc);
aJson.addNumberToObject(root, "relaisT", rd);
char* json =aJson.print(root);
aJson.delete(root);

Error return.
In function 'void loop()':
error: expected unqualified-id before 'delete'
error: expected `;' before 'delete'

in the ajson.h file they talk about the deleteItem();
Maybe change that in the documentation or readme file.

Updating a boolean value

I was wondering why the boolean type has been split to aJson_False and aJson_True?

Because of this updating a boolean value may work in an unexpected way.

For example if I update a boolean value directly like this

aJson.getObjectItem(user, "registered")->valuebool = false; // was true before

and the print the obeject it still prints out as "true" because the printValue function only checks for the type and not the actual value.

I have created a fork where the values have been combined to a single type, but I didn't create a pull request yet because I think it's possible that I have just misunderstood something obvious.

there seems to be a memory leak in the “print” method.

  1. there seems to be a memory leak in the “print” method.
  2. there is a peculiar way to handle .999 as .899.

code (run on Arduino Uno and JEELINK):

include

aJsonObject* JSONObject;
aJsonObject* JSONhostCommand;
aJsonObject* JSONhostParameter1;
aJsonObject* JSONhostParameter2;
aJsonObject* JSONhostLength;

int p1=1000;
float p2= 999.99;

void sendFreeRAM(String text) {
Serial.print (“[JL: free RAM ");
Serial.print (text); Serial.print (": ");
Serial.print (freeRAM());
Serial.println (" ]“);
}

int freeRAM () {
extern int __heap_start, *__brkval;
int v;
return (int) &v – (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

void setup() {
Serial.begin(9600);
}

void loop() {
aJsonObject *JSONObjectOut;
JSONObjectOut=aJson.createObject();
aJson.addNumberToObject(JSONObjectOut, “M”, 5);
aJson.addNumberToObject(JSONObjectOut, “P1″, p1);
aJson.addNumberToObject(JSONObjectOut, “P2″, p2);
aJson.addNumberToObject(JSONObjectOut, “L”, 10.199);

sendFreeRAM(“1: JSON”);
Serial.println(aJson.print(JSONObjectOut));

sendFreeRAM(“2: JSON”);
aJson.deleteItem(JSONObjectOut);

sendFreeRAM(“3: JSON”);
}

All memory alloc function in c/c++ are voodoo to me, so I could not find anything in the code. Do you have an idea?

output here is:

[JL: free RAM 1: JSON: 1330 ]
{“M”:5,”P1″:1000,”P2″:999.98999,”L”:10.19900}
[JL: free RAM 2: JSON: 1282 ]
[JL: free RAM 3: JSON: 1282 ]
[JL: free RAM 1: JSON: 1282 ]
{“M”:5,”P1″:1000,”P2″:999.98999,”L”:10.19900}
[JL: free RAM 2: JSON: 1234 ]
[JL: free RAM 3: JSON: 1234 ]
[JL: free RAM 1: JSON: 1234 ]
{“M”:5,”P1″:1000,”P2″:999.98999,”L”:10.19900}
[JL: free RAM 2: JSON: 1186 ]
[JL: free RAM 3: JSON: 1186 ]
[JL: free RAM 1: JSON: 1186 ]
{“M”:5,”P1″:1000,”P2″:999.98999,”L”:10.19900}
[JL: free RAM 2: JSON: 1138 ]
[JL: free RAM 3: JSON: 1138 ]

Demo code issue v1.0, arduino 022

test.cpp: In function 'void setup()':
test:101: error: 'struct aJsonObject' has no member named 'value'

line 101 is:

Serial.println(name->value.valuestring);

Problem with number value

Hi,
i'm trying to parse a Facebook OpenGraph JSON object (an example below).
As you can see the "likes" element have a number value without double-quote, in this case aJson return an unexpected and random value. All other string element value works correctly.

Can you investigate into this glitch?

JSON example (from http://graph.facebook.com/50595864761):

{
"id": "50595864761",
"name": "GitHub",
"picture": "http://profile.ak.fbcdn.net/hprofile-ak-snc4/50232_50595864761_2145_s.jpg",
"link": "http://www.facebook.com/pages/GitHub/50595864761",
"likes": 7607,
"category": "Website",
"is_published": true,
"website": "https://github.com/",
"founded": "2008",
"company_overview": "Absolutely the best way to work on software with other people.",
"talking_about_count": 178
}

Compatibility with SdFatLib

Not really an issue, but a feature. It would be very powerful to add compatibility to parse() with file streams of the SdFat Library found here http://code.google.com/p/sdfatlib/ . In the API fstream is for reading/writing, ifstream is for reading, ofstream is for writing. This would be particularly useful for Arduino web server applications using ajax and json. Thanks for the great library!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.