Posting long variable

I am posting a 113 character string variable using Particle.Variable about once every 5 seconds or so. The problem is the variable is not always complete on the server when I check it. Sometimes it is trimmed. So generally it is suppose to be:

0.007000,0.001000,0.056000,0.007000,0.001000,0.000000,0.029000,0.004000,0.038000,0.016000,5592.405000,5592.405000

But often times when I check the variable on the Particle server it will be much shorter like:
0.008000,0.008000,0.018000,0.000000,0.008000,0.001000,0.000000,0.001000,

I know this is not the actual length of the string because I print it to the serial port and it is always the exact correct length. Why is the full variable not getting posted?

Here is a snippet of my code:

Particle.variable("readings", varString);
Serial.println(varString);
Serial.println(varString.length());
delay(5000);

As I said varString is always the correct length as I can see in the serial log but it is not always correct on the Particle server.

Ideas?

Hi @IOTrav

The example you posted above is exactly 72 characters long, which is a magic number for some older terminal emulators, shells, etc. I think that is likely a clue to the cause. There are three places for it to be truncated potentially: on the device (which you have ruled out with the serial prints), in the Particle cloud, or in your code that reads from the cloud.

So how are you reading the string?

Have you tried using curl from a command line shell to read it?

Thank you @bko,

I am reading it from my own JavaScript application as well as through the Particle Dev app and getting the same result on both. Since the Particle Dev app is showing the same thing I have to believe that is the actual variable on the server.

Here is the response I get on my get request to the Particle server in my application:

{
  "cmd": "VarReturn",
  "name": "readings",
  "result": "0.008000,0.008000,0.018000,0.000000,0.008000,0.001000,0.000000,0.001000,",
  "coreInfo": {
    "last_app": "",
    "last_heard": "2015-12-04T17:48:02.394Z",
    "connected": true,
    "last_handshake_at": "2015-12-04T17:41:48.906Z",
    "deviceID": "38002c001647343339383037",
    "product_id": 6
  }
}

I have seen even shorter responses like this:

{
  "cmd": "VarReturn",
  "name": "readings",
  "result": "Current_0.008000,0.001000,0.046000,0.001000,",
  "coreInfo": {
    "last_app": "",
    "last_heard": "2015-12-04T17:07:26.056Z",
    "connected": true,
    "last_handshake_at": "2015-12-04T17:00:36.168Z",
    "deviceID": "38002c001647343339383037",
    "product_id": 6
  }
}

So it is not always just 72 characters when it is shorter than expected. This one for example is 44 chars long so it varies.

Looking back at your code snippet, you are not declaring the Particle variable in loop() are you? You must declare them in setup() since there is a message that is sent to the cloud describing all the vars and functions so the cloud knows what to do. I just want to be sure on this point.

Thanks for looking at the raw data. I think we need @Dave to weigh in the cloud side. I know that some folks were using Particle variables for long string data (600+ characters) and not having trouble.

1 Like

Thanks @bko

I had not declared the variable to the Particle server in setup. I am now and running a test to see how it turns out. I will let you know what I find.

Now in setup I have

Particle.variable("readings", "");

Thanks

Hi @IOTrav

That is not going to work–you need to declare the Particle variable so that it points to the memory of the string, so “” or empty string is not right. You need it like this:


String varString;

void setup() {
  Particle.variable("readings", varString);
}

Hi @bko

Understood. Here is the latest code with corrections as suggested:

// This #include statement was automatically added by the Particle IDE.
#include "Current_Monitor/Current_Monitor.h"

CurrentMonitor controller;
double current = 0;
double previousReading = 0;
double voltage = 0;
double kilowattHours = 0.00;
int rawCurrent = 0;
unsigned long upTime = 0;
unsigned long lastReadTime = 0;

String readings = "";

String varString;

void setup() {
    Serial.begin(115200);
	controller.setAddress(0,0,0,0);
	upTime = millis();
	Particle.variable("readings", readings);
// 	for(int i = 1; i <11; i++){
// 	    String varID = "Channel_"+String(i);
// 	    Particle.variable(varID, &current, DOUBLE);
// 	}
	
}

void loop() {
    readings = "";
    for(int i = 1; i < 13; i++){
        //Calculate current
    rawCurrent = controller.readCurrent(i);
	current = rawCurrent/1000.00;
	String reading = String(current)+",";
	readings.concat(reading);

	//Calculate wattage
// 	double wattage = current*124.13;
	
	//Calculate hours
// 	upTime = millis();
// 	double hours = (upTime - lastReadTime)/ (60.00 * 60.00 * 1000.00);
// 	lastReadTime = millis();
	
	//Calculate Kilowatt hours
// 	kilowattHours = kilowattHours + ((wattage * hours)/1000.00);
	
// 	String varID = "Channel_"+String(i);
	
// 	Particle.variable(varID, &current, DOUBLE);
// 	Particle.variable("KW_Hours", &kilowattHours, DOUBLE);
	delay(50);
    }
    // Serial.println(varString);
    Particle.variable("readings", readings);
    Serial.println(readings);
    Serial.println(readings.length());
    delay(5000);
}

That said I am still seeing partial variables on my get requests to the Particle server.

No!
Particle.variables() only get set up once and whenever the underlaying variable gets changed it will be retrievable via the cloud.

It’s like a pointer. You set it up once and whenever the value at the mem location gets changed you just read the same dereference that pointer and will seethe new value.
No Particle.variable() in loop()!

Hey @ScruffR

How did I not know that!!!

Ok, I removed the Particle.Variable post from the loop. See here:

// This #include statement was automatically added by the Particle IDE.
#include "Current_Monitor/Current_Monitor.h"

CurrentMonitor controller;
double current = 0;
double previousReading = 0;
double voltage = 0;
double kilowattHours = 0.00;
int rawCurrent = 0;
unsigned long upTime = 0;
unsigned long lastReadTime = 0;

String readings = "";

String varString;

void setup() {
    Serial.begin(115200);
	controller.setAddress(0,0,0,0);
	upTime = millis();
	Particle.variable("readings", readings);
// 	for(int i = 1; i <11; i++){
// 	    String varID = "Channel_"+String(i);
// 	    Particle.variable(varID, &current, DOUBLE);
// 	}
	
}

void loop() {
    readings = "";
    for(int i = 1; i < 13; i++){
        //Calculate current
    rawCurrent = controller.readCurrent(i);
	current = rawCurrent/1000.00;
	String reading = String(current)+",";
	readings.concat(reading);
	delay(50);
    }
}

I did not realize that the Particle module was posting the variable from memory every time it checked in with the server. That explains perfectly why I am getting partial readings. It is posting while I am still constructing the variable in my for loop I believe. Any ideas how I can prevent this somehow?

It’s not posted just as a pointer does not push the new values each time the memory changes.

You request the current value and this is what you GET.

@ScruffR & @bko

Thanks for everything guys. I have it solved now. I construct a string locally and then set the string pointer to memory for the Particle Variable to that after I am finished constructing it. This way I do not end up with partial readings. The better way would be to set portions of the String pointer as I proceed through the for loop so it is more up to date but this works just as well.

// This #include statement was automatically added by the Particle IDE.
#include "Current_Monitor/Current_Monitor.h"

CurrentMonitor controller;
double current = 0;
double previousReading = 0;
double voltage = 0;
double kilowattHours = 0.00;
int rawCurrent = 0;
unsigned long upTime = 0;
unsigned long lastReadTime = 0;

String readings = "";

String varString;

void setup() {
    Serial.begin(115200);
	controller.setAddress(0,0,0,0);
	upTime = millis();
	Particle.variable("readings", readings);
// 	for(int i = 1; i <11; i++){
// 	    String varID = "Channel_"+String(i);
// 	    Particle.variable(varID, &current, DOUBLE);
// 	}
	
}

void loop() {
    String newReading = "";
    for(int i = 1; i < 13; i++){
        //Calculate current
    rawCurrent = controller.readCurrent(i);
	current = rawCurrent/1000.00;
	String reading = String(current)+",";
	newReading.concat(reading);

	//Calculate wattage
// 	double wattage = current*124.13;
	
	//Calculate hours
// 	upTime = millis();
// 	double hours = (upTime - lastReadTime)/ (60.00 * 60.00 * 1000.00);
// 	lastReadTime = millis();
	
	//Calculate Kilowatt hours
// 	kilowattHours = kilowattHours + ((wattage * hours)/1000.00);
	
// 	String varID = "Channel_"+String(i);
	
// 	Particle.variable(varID, &current, DOUBLE);
// 	Particle.variable("KW_Hours", &kilowattHours, DOUBLE);
	delay(50);
    }
    readings = newReading;
}  

Thanks Again guys.

2 Likes