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.

3
  • And now you know why no one does that. May 19, 2016 at 11:57
  • Well, this is a school project due tomorrow. So I can't do much with this... May 19, 2016 at 12:00
  • What IDE version are you using, that page you've referenced specifically states it doesn't work with 1.61
    – Madivad
    May 19, 2016 at 12:33

2 Answers 2

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);
3
  • Well, I know that is. But as it is a function "setTime" Which expects a second input for the time. And also would take a date like that. May 19, 2016 at 12:07
  • Can I edit the function so that it takes unsigned long? May 19, 2016 at 12:08
  • time_t x = (hoursSet * 3600) + (minutesSet * 60); Serial.println(x); setTime(x); When I try it like that, it returns Combined: 4294937760 (For 10:00) May 19, 2016 at 12:12
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.