Problem with making an good JSON string...

First of all, I’m enjoying this project. I build my nanodeRF and a sensorshield (from martin K, prototype PCB) and it looks great.
I'm planning to make an extended blog post on my fresh website: www.bluemotica.nl for it. You can see the first photo’s of it there.

But now the hardware part is working great, I'm shifting to the software sketches.
The first test sketches are working OK and I get good read-outs from my sensors (1 CT,voltage,Temp (DS18B) LDR and Hall-sensors). I will write an article about that "build" ride later on.

I made my own github repository for my sketches and I uploaded my first "sensor base" stuff (that's how I named my nanodeRF with sensing_shield ontop) you can get it here: github.com/alco28/Sensor_base.git



But now my question. I'm not familiar with C++ programming but I'm learning quick...I think...

I'm using some parts of the orginal emonBASE and emonTX sketches for my project. So far so good.
But I'm looking in the dark at the JSON stuff and can't see an good post or artikel on this site for an decent explain?

It's starting at rownummer 265 at my sketch (NanodeRF_sensing.ino)

 

 

  //Make an JSON String and post it to the server
 #ifdef JSON             // activated by JSON DEFINE PARAM
 
// emontx = *(PayloadTX*)                                            // NEED IT???
 Serial.println();                                                  // print emontx data to serial
 Serial.print("emonTx data rx");
 str.print(",power1:");           str.print(emontx.realPower);      // Add power reading
 str.print(",voltage:");          str.print(emontx.Vrms);           // Add voltage reading
 str.print(",temperature:");      str.print(emontx.Temp1/100.0);    // Add voltage reading

 
ether.packetLoop(ether.packetReceive());                           // ??? WHATS THIS SYNTAX ?? count packages? OR???
   
str.print("}\0");  //  End of json string
Serial.print("2 "); Serial.println(str.buf); // print to serial json string
 
// To point to your account just enter your WRITE APIKEY
// server:06cc8cd3437f02d62272f7b663d4a70d (demo/demo)

ethernet_requests ++;                // counter for enternet request
ether.browseUrl(PSTR("/emoncms/api/post.json?apikey=06cc8cd3437f02d62272f7b663d4a70d&json="),str.buf, website, my_callback );

str.reset();                                                   // Reset json string  GOOD POSITION???

 

My question, do I set the serial readings (str.print) in a good way? and how do I get that right in the JSON string en past it though the emonCMS ??? I can't find an good explanation for the ether.browse,URL and PSTR (post string??) commands to..

So can somebody help me by explain it or alter my script to work right?
This sketch works fine WITHOUT the json part enabled..good serial.println communication. but it's getting meshy when I enable the JSON part (define JSON..Uncommand) ..no posting, no good serial.println communications (only some strange text..WEB..)

 

and after this problem there is an part called my_callback VOID...maybe there this part is a problem??? just guessing...I don't have an emonGLCD so I can't get the time from there, but the emoncms is working.

 

Robert Wall's picture

Re: Problem with making an good JSON string...

The format for the JSON string is:  {key1:value1,key2:value2} etc.

If you look at a Nanode example sketch (e.g. NanodeRF_Power_RTCrelay_GLCDtemp.ino) and analyse it, you will see the JSON string is written like this. It is written in parts, I have brought all the parts together:

          str.reset();                                                                                // Reset json string     
          str.print("{rf_fail:0");                                                                // RF received so no failure
          str.print(",power1:");     str.print(emontx.power1);                // Add power reading
          str.print(",power2:");     str.print(emontx.power2);                // Add power reading
          str.print(",power3:");     str.print(emontx.power3);                // Add power reading
          str.print(",voltage:");      str.print(emontx.voltage);                // Add emontx battery voltage reading
          str.print(",temperature:"); 
          str.print(emonglcd.temperature/100.0);
          str.print("}\0");                                                                         //  End of json string
 

So the complete string actually looks something like this:

          "{rf_fail:0,power1:123.45,power2:234.56,power3:345.67,voltage:234.56,temperature:23.4}\0"

You print to the string very much in the normal way - see the Arduino Language Reference ( ..../reference/Serial.html) for Serial - Print. The variable 'str' is an instance of the PacketBuffer class, which is defined near the top of the sketch.

"Payload" is the data string received from the emonTx - its format must be the same in both the Nanode and the emonTx.

The Ethernet controller is set up with

"  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) { .... "

and

"  ether.packetLoop(ether.packetReceive());" checks for and handles incoming data. Here: http://jeelabs.org/2011/06/19/ethercard-library-api/ is where you will find details.

 

alco's picture

Re: Problem with making an good JSON string...

Hi Robert,

Tnx again for you quick reaction. but I know how the str.print workes and my ethernet is working OK (I think, because I can get an IP,it finds my emoncms/webserver also and dns lookes good..).

It's just the SEND part that I don't get. yes, the packetbuffer is created by this complex (for me..) part at the top of my and also the orginal emonbase sketch:

// ***** The PacketBuffer class is used to generate the json string that is send though ethernet - JeeLabs *****
class PacketBuffer : public Print {
public:
PacketBuffer () : fill (0) {}
const char* buffer() { return buf; }
byte length() { return fill; }
void reset()
{
memset(buf,NULL,sizeof(buf));
fill = 0;
}
virtual size_t write (uint8_t ch)
{ if (fill < sizeof buf) buf[fill++] = ch; }
byte fill;
char buf[150];
private:
};
PacketBuffer str;

So if I read this code. It lookes to me that it make an empty buffer for 150 characters that can be filled with the sensor data. But how does the str.prints from the sensors (like str.print(",power1:");   str.print(emontx.realPower); ) getting into this buffer ?

and why do I get the strange reading in my serial monitor? I don't have an compile error..can upload it but I don't see an data package to be send..

Can somebody take a quick look to my sketch and help me find that enoring bug that causes the strange serial communcation?

P.S. I don't have a fysical emontx and emonbase. just 1 nanodeRF with all the sensorsconnected to it. so I don't use the RFM12B wireless chip or an emonGLCD to monitor..

TrystanLea's picture

Re: Problem with making an good JSON string...

 Hello Alco

Try extending the buffer size to 200 or 250. The str.print inherits the .print from the standard arduino print class. Its one of Jean Claud Wippler's great innovations: http://jeelabs.org/2010/09/29/sending-strings-in-packets/

Robert Wall's picture

Re: Problem with making an good JSON string...

What you have quoted there is the class definition. You should not need to change that at all. The print method is not defined here, it has been inherited. That is what  ": public Print"  in  "class PacketBuffer : public Print ..."  tells us.

I think "and why do I get the strange reading in my serial monitor" is because you are not writing your string correctly. I think you should reset the string first, then where is the part that writes the opening '{' ?  You need to begin:

          str.reset();                                                                                // Reset json string     
          str.print("{power1:");           str.print(emontx.realPower); // Add power reading
-------------------^

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.