I am trying to update a variable with the attached code but when I read the variable it it always shows high.I know the if statement is working because the LED flashes. Can you help me understand what I am doing wrong in my code below?
Best regards,
Clive
//Test spark.variable
int periodSlice = 10000;
char *status;
unsigned long lastRun = 0;
int state = 1;
int ledPin = D7;
void setup()
{
pinMode(ledPin, OUTPUT);
}
void loop()
{
Spark.variable("LED_State", status, STRING);
if ((millis() - lastRun < periodSlice && lastRun != 0) && millis() >= lastRun) return; //Check once every periodSlice, unless we havent checked yet, or if time since overflow of millis is less than last time we checked
lastRun = millis();
//Toggle LED
digitalWrite(ledPin, state);
if (state == 1)
{
status = "HIGH";
state = 0;
}
else
{
status = "LOW";
state = 1;
}
}
Spark.variable goes in the setup. It shouldn’t be called every loop
You can expose your state variable directly. You don’t need a second status variable. See modified code below. TBH it isn’t tested so feel free to come back with issues
int periodSlice = 10000;
unsigned long lastRun = 0;
int state = 1;
int ledPin = D7;
void setup()
{
pinMode(ledPin, OUTPUT);
Spark.variable("state", &state, INT);
}
void loop()
{
if ((millis() - lastRun < periodSlice && lastRun != 0) && millis() >= lastRun) return; //Check once every periodSlice, unless we havent checked yet, or if time since overflow of millis is less than last time we checked
lastRun = millis();
//Toggle LED
digitalWrite(ledPin, state);
if (state == 1)
{
state = 0;
}
else
{
state = 1;
}
}
Many thanks for this it works but gives me the inverse of what I am looking for. That is why I set up the secondary variable. I can fix that in my local code so no issue really.
May I ask can a bool be advertised with spark.variable too?
Sorry I set up a second int that mirrors this and use it in the variable it works great. I tried again with a string and it only ever shows high, in my original code have I done something wrong in defining or utilising the char *variable and string?
@casm, I guess your problem with the string version comes from your use of an uninitialized pointer char*.
With your code you might even corrupt some memory you haven’t claimed propperly.
Try to declare char status[5]; and use strcpy(status, "HIGH"); and strcpy(status, "LOW"); instead.
As I understand it with your code, the string assignment status = "HIGH"; does not actually copy the four chars (plus one zero terminator '/0') into the place *status is pointing at, but rather moves the pointer to the memory location where the compiler had placed the ´"HIGH"´ literal at compile time.
When later on "LOW" is assigned the pointer gets redirected again, but by that time the Spark.variable() call will not touch the already saved pointer anymore and so it will always return the contents of the original mem location.
@ScruffR is correct! Because you are only passing the initial pointer’s value (what it is pointing to ie, a memory address) to Spark.variable() when you attempt to “GET” the variable using the cloud the spark only knows to return what’s at the memory address. Changing the pointer’s value later using assignment like
status = "High"
changes the pointers value only. If the spark api allowed us to instead pass the pointer’s memory location (&status) and then deferenced that (twice I think?) when doing the GET then what you attempted to do @casm would work!
Here’s an updated code snippet that does what you want (I think) using what @ScruffR suggested.
int periodSlice = 10000;
char status[5] = "INIT";
unsigned long lastRun = 0;
int state = 1;
void setup()
{
Spark.variable("LED_State", status, STRING);
RGB.control(true);
}
void loop()
{
if ((millis() - lastRun < periodSlice && lastRun != 0) && millis() >= lastRun) return; //Check once every periodSlice, unless we havent checked yet, or if time since overflow of millis is less than last time we checked
lastRun = millis();
if (state == 1)
{
strcpy(status, "HIGH");
state = 0;
RGB.color(255, 255, 0);
}
else
{
strcpy(status, "LOW");
state = 1;
RGB.color(0, 255, 255);
}
}
Attached is the final working code should anyone need it. many thanks to both of you.
best regards,
Clive
int periodSlice = 600000;
unsigned long lastRun = 0;
int state = 1;
char status[5];
int ledPin = D7;
void setup()
{
pinMode(ledPin, OUTPUT);
Spark.variable("LED_state", status, STRING);
}
void loop()
{
if ((millis() - lastRun < periodSlice && lastRun != 0) && millis() >= lastRun) return; //Check once every periodSlice, unless we havent checked yet, or if time since overflow of millis is less than last time we checked
lastRun = millis();
//Toggle LED
digitalWrite(ledPin, state);
if (state == 1)
{
state = 0;
strcpy(status, "ON");
}
else
{
state = 1;
strcpy(status, "OFF");
}
}