Timer with millis() works for a while, then the control is completely ignored

I am working on a project which sends and receives multiple data over bluetooth with the hc-05 bluetooth module and a phone app I made with MIT app inventor. I think the problem is with my arduino code.

int last_time = 0;
bool first_time = true;
void loop() 
{
  TakeBluetoothInput();
  if(first_time == true || (millis() - last_time) >= 5000 ){ //waits five seconds and runs instantly if this is the first time the statement is running
    SendData(); //sends the data 
    last_time = millis(); //sets lasttime to millis
    first_time = false; //it already ran once so I set the bool false in order to control only with the millis() last time part
  }
}

I think this is the problematic part, after a while it ignores the millis() - last_time control and just runs the code inside without delay

here is the full code if needed:

//temperature and moisture values
float temp_1 = 1;
float moist_1 = 2;
float temp_2 = 3;
float moist_2 = 4;
float temp_3 = 5;
float moist_3 = 6;

int motor_speed;                          //sets the main motor speed
int servo_pos;                             //sets the servo position

bool first_time = true;                   //explained further ahead
String BT_input;                          // to store input character received via BT.       
String BT_input2;                         //to get the first word from the input 

int last_time = 0;
void setup()  
{  
  Serial.begin(9600);                      //default baud rate of module
  while (!Serial) 
  {
     // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() 

{
  TakeBluetoothInput();
  if(first_time == true || (millis() - last_time) >= 5000 ){ //waits five seconds and runs instantly if this is the first time the statement is running
    SendData(); //sends the data 
    last_time = millis(); //sets lasttime to millis
    first_time = false; //it already ran once so I set the bool false in order to control only with the millis() last time part
  }
}

void TakeBluetoothInput(){
  if (Serial.available())
    {   
        BT_input = Serial.readString();   // read input string from phone 
        BT_input2 = getValue(BT_input, ' ', 0); // set a string to the first word from input
        if(BT_input2 == "Motor"){     //Check if the first word is Motor
          motor_speed = getValue(BT_input, ' ', 3).toInt(); // If it is, then we check the set the motor speed to the received value
        }
        else if(BT_input == "Open Water"){ //if the first word isn't water, we check if the whole input is "Open Water"
          servo_pos = 0; // if it is set the servo pos to 0 to open the water
        }
        else if(BT_input == "Close Water"){ //if the input is close water
          servo_pos = 180; //we set the servo pos to 180 to close the water
        }
        else{} //if there is another input we ignore it


    }   
 
}

void SendData(){ //sends the temp and moisture values
  Serial.print(temp_1);
  Serial.print("|");
  Serial.print(moist_1);
  Serial.print("|");
  Serial.print(temp_2);
  Serial.print("|");
  Serial.print(moist_2);
  Serial.print("|");
  Serial.print(temp_3);
  Serial.print("|");
  Serial.println(moist_3);
}


String getValue(String data, char separator, int index) //gets the desired item with index from the string after splitting it by a delimeter
{
    int found = 0;
    int strIndex[] = { 0, -1 };
    int maxIndex = data.length() - 1;

    for (int i = 0; i <= maxIndex && found <= index; i++) {
        if (data.charAt(i) == separator || i == maxIndex) {
            found++;
            strIndex[0] = strIndex[1] + 1;
            strIndex[1] = (i == maxIndex) ? i+1 : i;
        }
    }
    return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

Have you tried printing what you receive before testing it ?

   else if (BT_input == "Open Water") //if the first word isn't water, we check if the whole input is "Open Water"

The comment does not match the code. Which is correct ?

The problem is almost certainly with the last_time variable. It should be an unsigned long rather than an int because that is what millis() returns, and an unsigned long will not fit in an int so after about 32000 milliseconds there is a problem

Thank you very much it works perfectly now.

The comment was supposed to be "if the first word isn't motor". Thanks for the heads up!! Have a nice day!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.