Out of heap memory

I have been working on a program that acts as an alarm clock which then opens my blinds. It seems like my core is running out of heap memory (According to the red flashes). Here is my code:

    //declare variables for the motor pins
int turnD = D3; // turn DOWN
int turnU = D2; // Turn UP
int sensor = D6; // Hall Effect sensor input
bool isUp = false; // If up or not
int upcounter = 0;
int maxSteps = 1980;
bool partWayDownGoUp = false;
bool partWayGoDown = false;
int downTime = 1980;
String alarmTime = "";
String currentTime = "";
bool alarmEnabled = true;
String PassCommand = "";
String semi = ":";
String AM = " AM";
String PM = " PM";

//////////////////////////////////////////////////////////////////////////////
void setup() {
    // setup function to act on Spark API calls
    Spark.function("Blind", BlindControl);
    Spark.function("SetTime", setTimer);
    Spark.function("isTimerEnabled", checkTimerState);
    //declare the motor pins as outputs
    pinMode(sensor, INPUT);
    pinMode(turnU, OUTPUT);
    pinMode(turnD, OUTPUT);
    digitalWrite(turnU, HIGH);
    digitalWrite(turnD, HIGH);
    setBlindsUp();
}

//////////////////////////////////////////////////////////////////////////////

void loop(){
    getCurrentTime();
    if(alarmTime.equals(currentTime)){
        PassCommand = "Open";
        BlindControl(PassCommand);  
    }
    delay(300);
}

int BlindControl(String command){
   if (command=="Open") {
       while(isUp == false){
            goUp();
            Spark.process();
            delay(100);
            if(command =="Close"){
                partWayGoDown = true;
                break;
            }
       }
       digitalWrite(turnU, HIGH);
   }
   if(partWayGoDown == true){
       goDown();
   }
   if (command=="Close" && isUp == true) {
       goDown();
   }
   return 1;
}

int setTimer(String alarmSetTime){
    alarmTime = alarmSetTime;
    return 1;
}

int checkTimerState(String state){
    if(state == "On"){
        alarmEnabled = true;
    }
    else if(state == "Off"){
        alarmEnabled = false;
    }
    else{
        alarmEnabled = false;
    }
    return 1;
}

//////////////////////////////////////////////////////////////////////////////

void goUp(){
    digitalWrite(turnU, LOW);
    isUp = checkPosition();
    delay(100);
    upcounter += 100;
}

//////////////////////////////////////////////////////////////////////////////

void goDown(){//find out why this is fireing twice
    digitalWrite(turnD, LOW);
    if(partWayGoDown = true){
        downTime = 198000 - upcounter;
    }
    for (int i = 0; i < 4; i++){
        delay(downTime/4);
    }
    digitalWrite(turnD, HIGH);
    isUp = false;
    downTime = 198000;
    partWayGoDown = false;
}

//////////////////////////////////////////////////////////////////////////////

bool checkPosition(){
    bool isUpOrNot = false;
    if(digitalRead(sensor) == LOW){
        isUpOrNot = true;
    }
    else if(digitalRead(sensor) == HIGH){
        isUpOrNot = false;
    }
    return isUpOrNot;
}

//////////////////////////////////////////////////////////////////////////////

void setBlindsUp(){
    while(digitalRead(sensor) == HIGH){
        digitalWrite(turnU, LOW);
    }
    digitalWrite(turnU, HIGH);
    isUp = true;
}

//////////////////////////////////////////////////////////////////////////////

void getCurrentTime(){
    **currentTime = "";**
    int unixTime = Time.now(); //Returns Unix Time (Seconds)
    int hour = Time.hour(unixTime);
    String hourSTR = String(hour);
    int min = Time.minute(unixTime);
    String minSTR = String(min);
    int sec = Time.second(unixTime);
    String secSTR = String(sec);
    bool isAm = Time.isAM();
    
    if(isAm == true){
        currentTime.concat(hourSTR);
        currentTime.concat(semi);
        currentTime.concat(minSTR);
        currentTime.concat(semi);
        currentTime.concat(secSTR);
        currentTime.concat(AM);
    }
    else{
        currentTime.concat(hourSTR);
        currentTime.concat(semi);
        currentTime.concat(minSTR);
        currentTime.concat(semi);
        currentTime.concat(secSTR);
        currentTime.concat(PM);
    }
}

This problem started happening primarily when I added the last function and its implemented it into the loop

Hi @Jaybuilder98

It looks to me like you meant to say:

void getCurrentTime() {
    currentTime = ""; //clear the global String
    ...

As it stands you are concat’ing and concat’ing to that String object and it just fills up memory near I can see.

That function defines local string variable “current” (which is unused). Also does quite lot operations on currentTime, which may lead to losts of reallocations. Both of these may led to heap fragmentation.

I would try using unix timestamp instead of string for time. And if you really need time in a string variable, I would avoud String class completely and use char[] buffer instead. But that is just my preferences, I am sure you can go away with String class if careful.

@Jaybuilder98, you may also want to consider @bko’s fantastic TimeAlarms library on the IDE :smile:

Ok so it looks like my problem was that I wasn’t reseting the currentTime variable back to nothing each time the function got called. Because of that is just kept getting larger and larger and larger :slight_smile: