0

I am making a clock on my Arduino Uno using the time library http://playground.arduino.cc/Code/Time

I let the user set a time. Which is then converted to seconds and used in the

setTime(s);

function. When the value is over 9:10h, the seconds evaluate to 4 294 941 360 seconds (= 1 193 039.27 hours)

A code snippet:

void timeChange() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Change time");
  lcd.setCursor(0, 1);
  lcd.print("00:00");
  int hoursSet    = 0; //Stores the hours added.
  int minutesSet  = 0; //Stores the minutes added.
  String printTime;
  bool timeComplete = false;
  while (!timeComplete) {
    int buttonVal = analogRead(A0);
    if (buttonVal >= 490 && buttonVal <= 520) { //Indicates button 3 is pressed. It's function is to add one hour to the time.
      hoursSet = (hoursSet + 1) % 24; //Adds one hour to the hours.
      delay(100);
    } else if (buttonVal >= 5 && buttonVal <= 10) { //Indicates button 4 is pressed. It's function si to add 5 minutes to the time.
      minutesSet = (minutesSet + 5) % 60; //Adds minutes to the minutes.
      delay(100);
    }

    lcd.setCursor(0,1);
    String strHr = String(hoursSet);
    String strMn = String(minutesSet);
    if(strHr.length() == 2){
      lcd.print(hoursSet);
    } else if(strHr.length() == 1) {
      lcd.print("0");
      lcd.setCursor(1, 1);
      lcd.print(hoursSet);
    }

    lcd.setCursor(2,1);
    lcd.print(":");
    lcd.setCursor(3,1);
    if(strMn.length() == 2){
      lcd.print(minutesSet);
    } else if(strMn.length() == 1) {
      lcd.print("0");
      lcd.setCursor(4, 1);
      lcd.print(minutesSet);
    }
    delay(100);

    if (buttonVal >= 990 && buttonVal <= 1010) { //if button 2 is pressed again, the timecomeplete is set to true, and the script continues.
      timeIsSet = true;
      timeComplete = true;
    }
  }
  lcd.clear(); //Clear the screen
  lcd.setCursor(0, 0);
  lcd.print("The time"); //Print text, move cursor and print the time
  lcd.setCursor(0, 1);
  String strHr = String(hoursSet);
  String strMn = String(minutesSet);
  if(strHr.length() == 2){
    lcd.print(hoursSet);
  } else if(strHr.length() == 1) {
    lcd.print("0");
    lcd.setCursor(1, 1);
    lcd.print(hoursSet);
  }
  lcd.setCursor(2,1);
  lcd.print(":");
  lcd.setCursor(3,1);
  if(strMn.length() == 2){
    lcd.print(minutesSet);
  } else if(strMn.length() == 1) {
    lcd.print("0");
    lcd.setCursor(4, 1);
    lcd.print(minutesSet);
  }
  lcd.print(" is saved!");
  setTime((hoursSet * 3600) + (minutesSet * 60));
  timeIsSet = true;
  delay(5000); //Wait five, seconds then proceed

}

Added this to the code:

      Serial.print("hours ");
  Serial.println(hoursSet);
  Serial.print("hours in s ");
  Serial.println(hoursSet * 3600);
  Serial.print("minutes ");
  Serial.println(minutesSet);
  Serial.print("minutes in s ");
  Serial.println(minutesSet * 60);
  Serial.print("Combined:  ");
  Serial.println( (hoursSet * 3600) + (minutesSet * 60) );

When I input 5:15 it results in:

hours 5 hours in s 18000 minutes 15 minutes in s 900 Combined: 18900

When I input 9:15 it results in:

hours 9 hours in s 32400 minutes 15 minutes in s 900 Combined: -32236

So, it looks like the library only holds an Int. But that seems odd, as the function expects seconds.

2 Answers2

4

Here's a hint: 32767 seconds is 9 hours, 6 minutes and 7 seconds.

What is the largest value that an int can hold?


EDIT: I can't add comments on this computer (old browser), so I have to respond to your question here. time_t is an unsigned 32-bit value, but all of your input values are signed 16-bit values. When you take a product like 3600*10, you get a bit pattern of 1000110010100000, which is 36000 when interpreted as an unsigned value, but is -29536 when interpreted as a signed value.

When assigned to a time_t, the value is sign-extended to 32 bits, which makes it 11111111111111111000110010100000, which is 4294937760 when interpreted as an unsigned value.

If you want to write a statement like

time_t x = (hoursSet * 3600) + (minutesSet * 60);

you need to type-cast your input arguments to the correct type first:

time_t x = ((time_t)hoursSet * 3600) + ((time_t)minutesSet * 60);
Dave Tweed
  • 463
  • 1
  • 4
  • 10
0

Changing this:

  time_t x = (hoursSet * 3600) + (minutesSet * 60);

To this:

  time_t x = ((unsigned long)hoursSet * 3600) + (minutesSet * 60);

Has solved the problem