Cores variables: Empty Braces/Brackets

Every once in a while, my core will “go dumb” and seemingly forget its firmware. It still responds to the basic GET request, and gives me something like this:
{
“id”: “Are Ids secret?”,
“name”: “Helios”,
“variables”: {},
“functions”: []
}

but after a hard reset, outputs the desired:
{
“id”: “”,
“name”: “Helios”,
“variables”: {
“photovoltage”: “int32”,
“Lights”: “int32”,
“Time”: “int32”,
“Triggered”: “int32”
},
“functions”: [
“FadeLightsTo”,
“Goodnight”
]

I am unsure after how long it takes for my core to “go dumb” but a reflash or a hard reset will seemingly fix it. The LED looks normal after it has “gone dumb” so I think that the connection is still good.

Please advise. (I didn’t think the other related known bugs were like this one, but if someone could direct me that would be nice as well!)

As a small update, it just happened after 45 minutes post reset.

Hi @tristansokol,

Hmm. This is very interesting to me as a bug. I’d love to track this down a bit further. Could you put something in your code that say, blinks D7 or something, and see if that blinking stops as well when the core ‘goes dumb’, or if that keeps running? That would help me identify if it’s an issue with software on the server, or on the core.

Thanks,
David

Also if you can share your code or some part of it, that would be very helpful for debugging this issue.

1 Like

@Dave
The code currently uses pwm to control my ceiling lights, so its pretty obvious when the error occurs (my lights turn off). So to answer your question, the blinking stops.

Hi @tristansokol,

Cool, that’s very helpful! That would indicate that the firmware is running into a bug and maybe crashing / trying to fail back to good firmware. Indeed, if you could share your code, maybe we can help track down the issue.

Thanks!
David

Sorry @Dave, I was busy typing this up.
edit, making the code section look better

I noticed the problems seemed to be happening around the 15 minute mark of every hour, which corresponded to an event in my code. I am using the core to turn on my lights at 6:15 every day (dawn simulation) and am using an exponential equation to slowly ramp up the lights pwm from the 15 min to 30 min mark.

after commenting pow(1.44,rtc.minuteString(currentTime).toInt()-15); I haven’t had an issue in ~4 hours. So maybe I am doing something wrong with math, or some kind of math overflow.

Here is my code (or at least the relevant part, there is some more stuff with a PIR sensor). I am using the real time clock library used here: https://community.spark.io/t/real-time-clock-library-for-spark/2925

    #include "SparkTime.h"
    #include <math.h>
    //Helios V5 Adding Real Time clock
    
    
    //Lights variables
    int lightout = 0;
    
    int  lightControl(int amount){
        //sets each of the light strips to specified amount.
        lightout = amount;
        if(amount == 000){
            digitalWrite(A1,LOW);
            digitalWrite(A4,LOW);
            digitalWrite(A6,LOW);
            // take control of the LED
            RGB.control(true);
            
            // red, green, blue, 0-255
            RGB.color(0, 0, 0);
    
        }else if(amount == 255){
            digitalWrite(A1,HIGH);
            digitalWrite(A4,HIGH);
            digitalWrite(A6,HIGH);
            // resume normal LED operation
            RGB.control(false);
        }else {
            analogWrite(A1, amount);
            analogWrite(A4, amount);
            analogWrite(A6, amount); 
        }
        return lightout;
    }
    
    //dummy readable variable
    int photovoltage = 0;
    
    int nowtime;
    
    int val;
    //testing fuction for the pir sensor
    void blink(void);
    
    //sparktime stuff
    UDP UDPClient;
    SparkTime rtc;
    
    unsigned long currentTime;
    unsigned long lastTime = 0UL;
    String timeStr;
    
    
    void setup() {
      //Register Spark function
      Spark.function("FadeLightsTo", FadeLightsTo);
      Spark.function("Goodnight",Goodnight);
    
    pinMode(A1, OUTPUT);
    pinMode(A4, OUTPUT);
    pinMode(A6, OUTPUT);
    
      Spark.variable("photovoltage", &photovoltage, INT);
      Spark.variable("Lights", &lightout, INT);
      Spark.variable("Time", &nowtime, INT);
      Spark.variable("Triggered", &timesince, INT);
      
    pinMode(D0, INPUT);
    pinMode(D1, OUTPUT);
    
      rtc.begin(&UDPClient, "north-america.pool.ntp.org");
      rtc.setTimeZone(-5); // gmt offset
    }
    
    // This routine loops forever 
    void loop() 
    {

    if (rtc.hour(currentTime)==6  && rtc.minute(currentTime) >15 && rtc.minute(currentTime)<30 && rtc.dayOfWeek(currentTime)<6){
        double temmp = 0;
        temmp = pow(1.44,rtc.minuteString(currentTime).toInt()-15);
        lightControl(temmp);
    }
////Naughty Line//////////////////////////////////////////////
    //photovoltage = pow(1.44,rtc.minuteString(currentTime).toInt()-15);
//////////////////////////////////////////////////////////////////
        currentTime = rtc.now();
        if (currentTime != lastTime) {
    	timeStr = "";
    	timeStr += rtc.hourString(currentTime);
    	timeStr += ":";
    	timeStr += rtc.minuteString(currentTime);
    	timeStr += ":";
    	timeStr += rtc.secondString(currentTime);	
    	timeStr += " ";	
    	timeStr += rtc.AMPMString(currentTime);
    	timeStr = "";
    	timeStr += rtc.hourString(currentTime);
    	timeStr += rtc.minuteString(currentTime);
    	timeStr += rtc.secondString(currentTime);	
//I haven't figured out how to read String variables from the core, so I toint a string.
    	nowtime = timeStr.toInt();
          lastTime = currentTime;
        }
    }
    int FadeLightsTo(String command){
        
        int previous = lightout;
        int newtemp = command.substring(0,3).toInt();
        
        
        if (previous > newtemp){
            for(int j = previous;j>=newtemp;j--){
                lightControl(j); 
                delay(10);
            }
        }else if (newtemp >previous){
            for(int j = previous;j<=newtemp;j++){
                lightControl(j); 
                delay(10);
            }
        }
    
    return lightout;
    }
    int Goodnight(String command){
        for(int j = lightout;j>=0;j--){
            lightControl(j); 
            delay(90);
        }
    }
2 Likes

Hi @tristansokol

It looks like you have a an exponential for temp (temmp = pow(…)) and one for photovoltage. The one for temmp is guarded by if time is between 6:15 and 6:30, so (minutes - 15) is always between 0 and 15. But the photovoltage equation is not guarded by an if, so when the time is 6:05 or 4:05, (minutes - 15), photovoltage can be negative, so could get gettting a zero or an underflow error from pow(), I am not sure which.

I would just do pow(1.44, rtc.minute(currentTime)-15) rather than do the string toInt() thing, but what you have is fine. If you need to cast rtc.minute which returns uint8_t (byte) you can.

What are you trying to do with photovoltage? I am not sure I how you are using it. Does it just belong inside the if statement?

As to Strings:

If you want to Arduino Strings as class variables, you can easily copy them to C strings like this:

char sparkVarString[128];
String myString;

void setup() {
  Spark.variable("myStringVar", &sparkVarString, STRING);
}

void loop() {
  myString.toCharArray(sparkVarString,128);  // copy into C string
}
1 Like

Thank you so much, and good catch!

1 Like

Also, just as a general clue about this behavior. If you see that unexpectedly your Core has no functions or variables, that probably means there was a hard fault (a bug in your firmware code) that caused the watchdog to reset the Core and stop running the user setup and loop. We have been discussing a better way to manage this, but that’s the current behavior.