[SOLVED] Spark variables not returning (timeout)

I have been diligently following the Spark.variable example but cannot get a variable to return. The error message back is “Timed out”. The code is shown below. The same code also allows a relay to be switched on/off via the relay board. This works fine. It is only trying to get the variable “sensor” that times out. Any ideas anyone?

int RELAY1 = D0;
int RELAY2 = D1;
int RELAY3 = D2;
int RELAY4 = D3;
int iSensor = A1;
int iSensorVal = 0;
char *vSensorStatus = "test";

void setup() {
   //Initilize the relay control pins as output
   pinMode(RELAY1, OUTPUT);
   pinMode(RELAY2, OUTPUT);
   pinMode(RELAY3, OUTPUT);
   pinMode(RELAY4, OUTPUT);
   
   // Initialise the sensor pin
   pinMode(iSensor, INPUT); // sets pin as input
   
   // Initialize all relays to an OFF state
   digitalWrite(RELAY1, LOW);
   digitalWrite(RELAY2, LOW);
   digitalWrite(RELAY3, LOW);
   digitalWrite(RELAY4, LOW);

   //register the Spark function
   Spark.function("relay", relayControl);
   
   //register the core variables
   Spark.variable("sensor", vSensorStatus, STRING);
}

void loop() {
    iSensorVal = analogRead(iSensor);       // read the input pin
    if((4060 < iSensorVal)) {        
        digitalWrite(RELAY2, 1);
        vSensorStatus = "closed";
        
    }
    else {
        digitalWrite(RELAY2, 0);
        vSensorStatus = "open";
    }
    delay(500);
}

// command format r1,HIGH
int relayControl(String command)
{
  int relayState = 0;
  // parse the relay number
  int relayNumber = command.charAt(1) - '0';
  // do a sanity check
  if (relayNumber < 1 || relayNumber > 4) return -1;

  // find out the state of the relay
  if (command.substring(3,7) == "HIGH") relayState = 1;
  else if (command.substring(3,6) == "LOW") relayState = 0;
  else return -1;

  // write to the appropriate relay
  digitalWrite(relayNumber-1, relayState);
  
  return 1;
}

The PHP code used to generate the CURL requests is as follows:

$vSparkIOURL = "https://api.spark.io/v1/devices/" . $vSparkIODevice . "/sensor";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,$vSparkIOURL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,"access_token=" . $vSparkIOAccessToken);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

and yes, the $vSparkIODevice and $vSparkIOAccessToken variables are correct!!

I’m not sure about the time out, but one problem lies in the way you declare an use your vSensorStatus variable.

The way you do declare it places the string literal into flash and lets the pointer refer to it.
When you then change the string you are actually redirecting the pointer to another location in flash (wherever build had put the other literals) but Spark.variable will still point to the old location.

I think you should rather do this

char vSensorStatus[8] = "test";
...
void loop()
{
  ...
  strcpy(vSensorStatus, "closed");
  ...
  strcpy(vSensorStatus, "open");
  ...
}

BTW: For analogRead() you don’t need to set pinMode() this is done inside the read function (AN_INPUT)

3 Likes

You want a GET request for a variable, not a POST request.

And @ScruffR beat me to it on the char array problems!

3 Likes

Thank-you to ScruffR & bko - I can now get the variables each and every time! Working example below for anyone else with the same question.

int RELAY1 = D0;
int RELAY2 = D1;
int RELAY3 = D2;
int RELAY4 = D3;
int iSensor = A1;
int iSensorVal = 0;
char vSensorStatus[8] = "test";

TCPClient client;

void setup() {
   //Initilize the relay control pins as output
   pinMode(RELAY1, OUTPUT);
   pinMode(RELAY2, OUTPUT);
   pinMode(RELAY3, OUTPUT);
   pinMode(RELAY4, OUTPUT);

   // Initialise the sensor pin
   //pinMode(iSensor, INPUT); // sets pin as input

   // Initialize all relays to an OFF state
   digitalWrite(RELAY1, LOW);
   digitalWrite(RELAY2, LOW);
   digitalWrite(RELAY3, LOW);
   digitalWrite(RELAY4, LOW);

//register the Spark function
   Spark.function("relay", relayControl);

   //register the core variables
   Spark.variable("sensor", vSensorStatus, STRING);
}

void loop() {
    iSensorVal = analogRead(iSensor);       // read the input pin
    if((4060 < iSensorVal)) {        
        digitalWrite(RELAY2, 1);
        strcpy(vSensorStatus, "closed");

    }
    else {
        digitalWrite(RELAY2, 0);
        strcpy(vSensorStatus, "open");
    }
    delay(500);
}

// command format r1,HIGH
int relayControl(String command)
{
  int relayState = 0;
  // parse the relay number
  int relayNumber = command.charAt(1) - '0';
  // do a sanity check
  if (relayNumber < 1 || relayNumber > 4) return -1;

  // find out the state of the relay
  if (command.substring(3,7) == "HIGH") relayState = 1;
  else if (command.substring(3,6) == "LOW") relayState = 0;
  else return -1;

  // write to the appropriate relay
  digitalWrite(relayNumber-1, relayState);
  
  return 1;
}

PHP:

<?php    
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://api.spark.io/v1/devices/0987654321.../sensor?access_token=123456789abcdef...");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_close($ch);
?>
3 Likes

Glad to hear that it works now :+1:


BTW: If you want to get the attention of a particular member of the community you’d use the @ like in @emjx, then we get a notification.
And we also like receiving :heart_decoration: likes if we were able to help :wink:

3 Likes

@ScruffR - duly noted :slight_smile: - posts liked!!

1 Like

I’ve been so bold to mark this solved :wink:
Hope this is OK for you.

1 Like