Pages: [1] 2   Go Down
Author Topic: Display time  (Read 9622 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 250
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I am trying to find a way to display the time on a LCD screen. Probably I can't know what time is it without using some sort of external hardware? So what is the easyest way to get time display on arduino?
« Last Edit: February 17, 2009, 02:02:28 pm by roli » Logged


London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Probably the easiest way to manage dates and times without external hardware is to use the DateTime library here: http://www.arduino.cc/playground/Code/DateTime

You will need a way to set the clock,  the example code uses the serial port to get time from a PC, but you can also set the time using buttons.  I recently saw a very clever clock that used tilt sensors for setting the time: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1233339782/4

Driving a typical text LCD with output from the library is simple,  in the example sketch, change the calls from Serial.print to calls to print to the LCD
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 250
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you!

Now I just need to figure out how to set time at the time of uploading the sketch to the arduino. I don't need serial communication and/or buttons. And I only need hours and minutes. So any hint about that? I don't know how to set the time and then display it.
Logged


London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is a simple sketch that displays the hour/minute/seconds on an lcd. It uses the LiquidCrystal library that is distributed with the arduino and I suggest you get the LCD example 'hello world' sketch going first and when you have something displaying on the lcd you can try this sketch to display a digital clock.

Have fun!
Code:
#include <LiquidCrystal.h>
#include <DateTime.h>

// simple sketch to display a digital clock on an LCD
// see the LiquidCrystal documentation for more info on this

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

void setup(){
  DateTime.sync(1230768000); // set jan 1 2009 as the default time
}

void  loop(){    
  if(DateTime.available()) {
    unsigned long prevtime = DateTime.now();
    while( prevtime == DateTime.now() )  // wait for the second to rollover
      ;
    DateTime.available(); //refresh the Date and time properties
    digitalClockDisplay( );   // update digital clock  
  }
}

void printDigits(byte digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits,DEC);
}

void digitalClockDisplay(){
  lcd.home();
  // digital clock display of current time
  lcd.print(DateTime.Hour,DEC);  
  printDigits(DateTime.Minute);  
  printDigits(DateTime.Second);  
}

I have not run this sketch so let me know how you get on
« Last Edit: February 17, 2009, 03:47:29 pm by mem » Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 250
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I figured it out a few minutes ago myself. But thanks for this! Now just to integrate this into my other functions. It is a little strange that after using this the other parts of my program are running slower.
Logged


London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The example sketch I posted above wastes a lot of time doing nothing !

as long as you call the following functions in your loop when you want the time updated you should be fine:
    DateTime.available(); //refresh the Date and time properties
    digitalClockDisplay( );   // update digital clock
« Last Edit: February 17, 2009, 04:51:29 pm by mem » Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 250
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So this part:
   DateTime.available(); //refresh the Date and time properties
Needs to be in the home screen function?  Or can I call this only when I need to display the time?  Because I am using functions and the home screen (where the time is) gets called when the user selects it. So does this have to be in the loop or can it be in the home function? And I am using my own formatting to display the time so I don't need digitalClockDisplay.
Logged


London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You only need to call DateTime.available just before you display the time.

The purpose of that function is to update the internal time counter and take a snapshot of the time properties so that subsequent calls to get the time properties will be up to date and consistent .  
« Last Edit: February 17, 2009, 05:56:09 pm by mem » Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 250
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great! Working like it should now!
Logged


London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good to hear you have it going. Please post more about your project when you have it finished
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 250
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I will!

Just another question. If I need someday to set the time using buttons, I can use something like this?

     DateTime.sync(DateTime.makeTime(0, 40, 10, 18, 2, 2009));  
Logged


London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
DateTime.sync(DateTime.makeTime(0, 40, 10, 18, 2, 2009));
 
Yep, thats how you can do it  smiley-wink

Have fun!
« Last Edit: February 18, 2009, 05:00:52 am by mem » Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 250
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great! I just added the ability to set the time when arduino starts. For that I am using a potenciometer.

If anyone is interested - here is the code for function that sets time:
Code:
void nastaviuro()
{
  char buffer[2]; //this is a buffer for printing on a screen
  lcd.clear(); //clear the display
  lcd.printIn("Sekunde: "); //Print Sekunde -> Seconds: in english
  int sekunde1 = vnos_stevila(); //get a first digit of seconds and store it in variable sekunde1
  lcd.cursorTo(2,0); //Move a cursor to second row, first column
  itoa(sekunde1,buffer,10); //Convert integer sekunde1 to char and store it in the buffer
  lcd.printIn(buffer); //Print the buffer
  int sekunde2 = vnos_stevila(); //get the second digit of seconds and store it in variable sekunde2
  itoa(sekunde2,buffer,10);
  lcd.cursorTo(1,0);
  lcd.printIn("               "); //Clear the first line of the screen
  lcd.cursorTo(1,0);
  lcd.printIn("Minute: "); //Print Minute -> Minutes in english
  lcd.cursorTo(2,1);
  lcd.printIn(buffer);
  lcd.printIn(":");
  int minute1 = vnos_stevila();
  itoa(minute1,buffer,10);
  lcd.cursorTo(2,3);
  lcd.printIn(buffer);
  int minute2 = vnos_stevila();
  itoa(minute2,buffer,10);
  lcd.cursorTo(2,4);
  lcd.printIn(buffer);
  lcd.printIn(":");
  lcd.cursorTo(1,0);
  lcd.printIn("               ");
  lcd.cursorTo(1,0);
  lcd.printIn("Ure: "); //Print ure -> Hours in english
  int ure1 = vnos_stevila();
  itoa(ure1,buffer,10);
  lcd.cursorTo(2,6);
  lcd.printIn(buffer);
  int ure2 = vnos_stevila();
  itoa(ure2,buffer,10);
  lcd.cursorTo(2,7);
  lcd.printIn(buffer);
  delay(3000); // Wait 3 seconds
  
  lcd.clear();
  
  lcd.printIn("Dan:"); //Print dan <- Day in english
  int dan1 = vnos_stevila();
  itoa(dan1,buffer,10);
  lcd.cursorTo(2,0);
  lcd.printIn(buffer);
  int dan2 = vnos_stevila();
  itoa(dan2,buffer,10);
  lcd.cursorTo(2,1);
  lcd.printIn(buffer);
  lcd.printIn(".");
  lcd.cursorTo(1,0);
  lcd.printIn("               ");
  lcd.cursorTo(1,0);
  lcd.printIn("Mesec: "); //print mesec ->  month in english
  int mesec1 = vnos_stevila();
  itoa(mesec1,buffer,10);
  lcd.cursorTo(2,3);
  lcd.printIn(buffer);
  int mesec2 = vnos_stevila();
  itoa(mesec2,buffer,10);
  lcd.cursorTo(2,4);
  lcd.printIn(buffer);
  lcd.printIn(".");
  lcd.cursorTo(1,0);
  lcd.printIn("               ");
  lcd.cursorTo(1,0);
  lcd.printIn("Leto: "); //Print leto -> year in english
  int leto1 = vnos_stevila();
  itoa(leto1,buffer,10);
  lcd.cursorTo(2,6);
  lcd.printIn(buffer);
  int leto2 = vnos_stevila();
  itoa(leto2,buffer,10);
  lcd.cursorTo(2,7);
  lcd.printIn(buffer);
  int leto3 = vnos_stevila();
  itoa(leto3,buffer,10);
  lcd.cursorTo(2,8);
  lcd.printIn(buffer);
  int leto4 = vnos_stevila();
  itoa(leto4,buffer,10);
  lcd.cursorTo(2,9);
  lcd.printIn(buffer);
  delay(3000);
  
  char sekunde3[6]; //Create a char array for seconds
  char sekunde4[2];
  char minute3[6];
  char minute4[2];
  char ure3[6];
  char ure4[2];
  char dan3[6];
  char dan4[2];
  char mesec3[6];
  char mesec4[2];
  char leto5[12];
  char leto6[2];
  char leto7[2];
  char leto8[2];
  itoa(sekunde1,sekunde3,10); //Converts sekunde1 to char and store them in sekunde3
  itoa(sekunde2,sekunde4,10);
  itoa(minute1,minute3,10);
  itoa(minute2,minute4,10);
  itoa(ure1,ure3,10);
  itoa(ure2,ure4,10);
  itoa(dan1,dan3,10);
  itoa(dan2,dan4,10);
  itoa(mesec1,mesec3,10);
  itoa(mesec2,mesec4,10);
  itoa(leto1,leto5,10);
  itoa(leto2,leto6,10);
  itoa(leto3,leto7,10);
  itoa(leto4,leto8,10);
  strcat(sekunde3,sekunde4); //Combines two digits of seconds and stores them in sekunde3
  strcat(minute3,minute4);
  strcat(ure3,ure4);
  strcat(dan3,dan4);
  strcat(mesec3,mesec4);
  strcat(leto5,leto6);
  strcat(leto5,leto7);
  strcat(leto5,leto8);
  
  //Displays this:
  // HH:MM:SS
  // DD.MM.YYYY
  lcd.clear();
  lcd.cursorTo(1,6);
  lcd.printIn(ure3);
  lcd.printIn(":");
  lcd.printIn(minute3);
  lcd.printIn(":");
  lcd.printIn(sekunde3);
  lcd.cursorTo(2,6);
  lcd.printIn(dan3);
  lcd.printIn(".");
  lcd.printIn(mesec3);
  lcd.printIn(".");
  lcd.printIn(leto5);
  delay(5000);
  

  int ure = atoi(ure3); //converts char back to integer
  int minute = atoi(minute3);
  int sekunde = atoi(sekunde3);
  int dan = atoi(dan3);
  int mesec = atoi(mesec3);
  int leto = atoi(leto5);
  
  DateTime.sync(DateTime.makeTime(sekunde, minute, ure, dan, mesec, leto));  //sets the time
  ura_nastavljena = true; //The time is now set
  
}

The ura_nastavljena part just indicates that the clock has been set so my code doesn't ask me to set the time again. You can use that or delete it.


And here is the code for numeric input using one potenciometer and one button:
Code:
int vnos_stevila()
{
  while(1) //Create a loop
  {
      int vrni = 0; //Number to return
      int dobi = analogRead(1); //Get a value from potenciometer on analog pin 1
      int gumbi = 0; //Here is stored a value from a button

      
      if (dobi <=102) //If input from a potenciometer is between 0 and 102 then variable vrni is 0
      {
          vrni = 0;
      }
      else if (dobi <= 204)
      {
          vrni = 1;
      }
      else if (dobi <= 306)
      {
          vrni = 2;
      }
      else if (dobi <= 408)
      {
          vrni = 3;
      }
      else if (dobi <= 510)
      {
          vrni = 4;
      }
      else if (dobi <= 612)
      {
          vrni = 5;
      }
      else if (dobi <= 714)
      {
          vrni = 6;
      }
      else if (dobi <= 816)
      {
          vrni = 7;
      }
      else if (dobi <= 918)
      {
          vrni = 8;
      }
      else if (dobi <= 1023)
      {
          vrni = 9;
      }

      char znak[2]; //declare a variable znak
      itoa(vrni, znak, 10); //convert a variable vrni to char and store it in znak
      lcd.cursorTo(2,14); //Move screen cursor to second row, 14 column
      delay(100); //wait
      lcd.printIn(">"); //A little marker for nicer input
      lcd.printIn(znak); //Print the current value
      gumbi = digitalRead(gumb); //Read the value from a button
      
      if (gumbi == 1) //If button was pressed, return the current value
      {
          return vrni;
      }
  }
}

Variable names are in slovenian language but the comments are in english so probably you can understand it. The code is VERY unoptimised and takes a lot of RAM. But it works for me! I am using LCD4Bit library to write on the screen.

the only question now is -> Will this library display the right time for a whole month? +/- 5min
« Last Edit: February 18, 2009, 08:25:13 am by roli » Logged


Connecticut, US
Offline Offline
Edison Member
*
Karma: 2
Posts: 1036
Whatduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
char buffer[[glow]2[/glow]]; //this is a buffer for printing on a screen
itoa(sekunde1,[glow]buffer[/glow],10);

Dangerous!  You don't give enough space in your character buffer to fit the number.  If the number of seconds is 10, the buffer needs at least 3 bytes of space, the '1', the '0', and the NUL terminator.  If you have numbers larger than 99 (like your year "ledo"), or smaller than 0, you need even more space.
« Last Edit: February 18, 2009, 08:49:11 am by halley » Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 250
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buffer can only store numbers up to 9. No more! The same goes for the others. leto5 -> combines 4 digits and is 12 places long.
Logged


Pages: [1] 2   Go Up
Jump to: