Having Trouble with Spark.variable()

Hello,

I’m observing odd behavior when making a GET request with curl to a Photon: the returned “result” property contains the correct string, but is missing the data. The Photon code is as follows:

#include "Adafruit_Sensor.h"
#include "Adafruit_LSM303_U.h"
#include "math.h"

#define VOLT_READ_PIN A0
#define R1 10000
#define R2 3300
#define COIL_RESISTANCE 13.2

#define JOULE_LED_PIN D7
#define LED_PIN D2

unsigned long lastCalc;
int calcInterval = 100;
double v, p, e, AccelX, AccelY, AccelZ, MagX, MagY, MagZ;
int lastJoule = 0;
int ledState = 0;
unsigned long pubMillis;
int pubInterval = 1000;

char tileStr[200];

Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(54321);
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345);

//Function declarations
int ledToggle(String args);
int power_charge(String args);

void setup() {
  pinMode(VOLT_READ_PIN, INPUT);
  pinMode(JOULE_LED_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);

  /* Initialise the accelerometer */
  if(!accel.begin()) {
      /* There was a problem detecting the ADXL345 ... check your connections */
      Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
      //Error handler
      Spark.publish("Sensor_Error","LSM303_Accelerometer not detected!", 60, PRIVATE);
      while(1);
  }
  /* Initialise the magnetometer */
  if(!mag.begin()) {
      /* There was a problem detecting the LSM303 ... check your connections */
      Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
      //Error handler
      Spark.publish("Sensor_Error","LSM303_Magnetometer not detected!", 60, PRIVATE);
      while(1);
  }
  
  Spark.variable("Tile_Data", &tileStr, STRING);
  Spark.function("ledToggle",ledToggle);
  Spark.function("PWR_CHRG",power_charge);
  
  Serial.begin(115200);

  lastCalc = millis();
  pubMillis = millis();
}

void loop() {
  if (millis() - lastCalc >= calcInterval) {
      readGenData();
      readAccelMagData();

      lastCalc = millis();

      //Print debugging information
      
      Serial.print("V_i: ");
      Serial.print(v);
      Serial.print(" | ");
      Serial.print("P: ");
      Serial.print(p);
      Serial.print(" | ");
      Serial.print("E: ");
      Serial.println(e); Serial.println();

      Serial.print("A: ["); Serial.print(AccelX); Serial.print(", "); Serial.print(AccelY); Serial.print(", "); Serial.print(AccelZ); Serial.println("]");
      Serial.print("M: ["); Serial.print(MagX); Serial.print(", "); Serial.print(MagY); Serial.print(", "); Serial.print(MagZ); Serial.println("]"); Serial.println();
      
  }

  if(millis() - pubMillis >= pubInterval) {
      tilePub();
      
      pubMillis = millis();
  }
  
}

void readGenData() {
  /*Read generator performance data*/
  double pinVal = analogRead(VOLT_READ_PIN) * 3.34 / 4096.0;
  v = (pinVal * (R1 + R2))/R2;

  p = pow(v,2) / (COIL_RESISTANCE * 3);

  double t = (millis() - lastCalc) / 1000.0;

  e += (p * t);

  if ((int) e > lastJoule) {
      lastJoule = (int) e;
      digitalWrite(JOULE_LED_PIN, HIGH);
      delay(1);
      digitalWrite(JOULE_LED_PIN, LOW);
  }
}

void readAccelMagData() {
  /*Get a new sensor event*/
  sensors_event_t accelEvent;
  sensors_event_t magEvent;

  accel.getEvent(&accelEvent);
  mag.getEvent(&magEvent);

  AccelX = accelEvent.acceleration.x;
  AccelY = accelEvent.acceleration.y;
  AccelZ = accelEvent.acceleration.z;

  MagX = magEvent.magnetic.x;
  MagY = magEvent.magnetic.y;
  MagZ = magEvent.magnetic.z;
}


int ledToggle(String args) {
  digitalWrite(LED_PIN, !ledState);
  ledState = !ledState;
  
  return 1;
}

int power_charge(String args) {
  return 1;
}

void tilePub() {
  sprintf(tileStr, "{\"v\":%3.2f,\"p\":%3.2f,\"e\":%3.2f,\"a\":[%3.2f, %3.2f, %3.2f],\"m\":[%3.2f, %3.2f, %3.2f]}", v, p, e, AccelX, AccelY, AccelZ, MagX, MagY, MagZ);
  Spark.publish("Tile_Data", "{\"Data\": \"New\"}", 60, PRIVATE);
}

My curl response is this:

{
  "cmd": "VarReturn",
  "name": "Tile_Data",
  "result": "{\"v\":,\"p\":,\"e\":,\"a\":[, , ],\"m\":[, , ]}",
  "coreInfo": {
    "last_app": "",
    "last_heard": "2015-09-02T05:04:01.844Z",
    "connected": true,
    "last_handshake_at": "2015-09-02T04:52:10.155Z",
    "deviceID": "<<deviceID>>",
    "product_id": 6
  }

Printing the data to the terminal works as expected, but I can’t get it returned with a GET request.

Thank you for your help!

Which GET request are you hitting? You should be using SSE instead for publish

This is your problem: you don't need the "&" for tileStr. It is already the right sort of thing to be used as a Spark.variable.

  Spark.variable("Tile_Data", tileStr, STRING);

Thanks @bko. I removed the ‘&’, but the response is still the same: the majority of the string contents is returned, but the variable data is not.

It looks like you are running into the issue with sprintf of floats/doubles on Photon. The fix is in place for the next release but it did not get into 0.4.4.

As a work-around you can use Arduino String objects.

Ah ok. That makes sense. I have similar code running on a Core and haven’t flashed new firmware in a couple of months, and it works as expected. I’ll look into the string objects.

Thank you!

Is there an estimate on the next firmware release date?

Very soon! Certainly within the next week for 0.4.5.

1 Like