Get date and time information from laptop

Hi,

I am a Arduino beginner. I am using Arduino Uno. I working on my first project for which I need to get current date and time from the laptop. I am using the official Arduino Uno kit - which has a cable which attaches to the laptop USB. I have 2 questions:

  1. What code should i write (which will get executed on Arduino) to read current date and time from the laptop?

  2. What do i need to do on the laptop to send the current date and time to Arduino?

I have researched this in the last few days. I found code below but i am not sure of a few things in the code below:

  • should i use Serial.being (9600) or Serial.begin (19200)? AND
  • what do i need to do on the laptop to send the time to Arduino?
  • I can’t find DateTime.h - the website says time.h is the new version. But the DateTime commands don’t work unless I have DateTime.h

Please help.

Thanks.

#include <DateTime.h>

#include <DateTimeStrings.h>


#define TIME_MSG_LEN  11   // time sync to PC is HEADER and unix time_t as ten ascii digits
#define TIME_HEADER  255   // Header tag for serial time sync message

void setup(){
 Serial.begin(19200); 
}

void  loop(){  
 getPCtime();   // try to get time sync from pc        
 if(DateTime.available()) { // update clocks if time has been synced
   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

   // send our time to an app listening on the serial port
   Serial.print( TIME_HEADER,BYTE); // this is the header for the current time
   Serial.println(DateTime.now());      
 } 
}

void getPCtime() {
 // if time available from serial port, sync the DateTime library
 while(Serial.available() >=  TIME_MSG_LEN ){  // time message
   if( Serial.read() == TIME_HEADER ) {        
     time_t pctime = 0;
     for(int i=0; i < TIME_MSG_LEN -1; i++){   
       char c= Serial.read();          
       if( c >= '0' && c <= '9')   
         pctime = (10 * pctime) + (c - '0') ; // convert digits to a number            
     }   
     DateTime.sync(pctime);   // Sync DateTime clock to the time received on the serial port
   }  
 }
}

void digitalClockDisplay(){
 // digital clock display of current time
 Serial.print(DateTime.Hour,DEC);  
 printDigits(DateTime.Minute);  
 printDigits(DateTime.Second); 
 Serial.print(" "); 
 Serial.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
 Serial.print(" ");  
 Serial.print(DateTimeStrings.monthStr(DateTime.Month));  
 Serial.print(" ");
 Serial.println(DateTime.Day, DEC);   
}

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

The DateTime library doesn't work in IDE 1.6.1 (and newer?). Get the new library instead.

The DateTime variable looks specific to the old library, check the supplied samples for the new library for all changes.

Your sketch expects a PC program that sends the current time to the USB (COM) port, and then reads (echoes?) whatever the Arduino sends back. Do you have such a program already?

How often do you want to update the time on the Arduino?

There must be a program running on the PC that can collect the time from the PC's clock and send the data to the Arduino in a format that is usable by the Arduino.

It may actually be simpler to get a Real Time Clock (RTC) module for the Arduino and then it would have its own time source.

...R

I think you should think about what you are doing, and why. It seems a pointless waste of time - just an alternative display for the PC clock, for display where? Oh yes, on the PC. This is not the sort of thing you would want to show your friends.

There are better things you can do with Arduino, and indeed better things you can do with the PC.

If Arduino really needs to know the time, it makes more sense to use an RTC, as Robin suggests. Furthermore, if you do that, you can disconnect Arduino from the PC, which goes quite some way to prove the value of doing it.

I submit that Arduino only needs to know the time if it is being used to tell you the time now, i.e. be a clock, or if it needs to tell you when something happened. In the case of the former, it makes more sense to be disconnected from the PC - and use an RTC. In the case of the latter, you have two options.

  1. Stand alone: record the event from wherever and the time from an RTC on Arduino.

  2. Connected to PC: record the event from Arduino and time from the PC clock on PC. If this is the case, you can do it with any PC terminal programme, no RTC needed.

http://playground.arduino.cc/Code/DateTime

http://playground.arduino.cc/code/time

This is newer version of code using time library

/* 
 * TimeSerial.pde
 * example code illustrating Time library set through serial port messages.
 *
 * Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970)
 * you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2013
 T1357041600  
 *
 * A Processing example sketch to automatically send the messages is included in the download
 * On Linux, you can use "date +T%s\n > /dev/ttyACM0" (UTC time zone)
 */ 
 
#include <TimeLib.h>

#define TIME_HEADER  "T"   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 

void setup()  {
  Serial.begin(9600);
  while (!Serial) ; // Needed for Leonardo only
  pinMode(13, OUTPUT);
  setSyncProvider( requestSync);  //set function to call when sync required
  Serial.println("Waiting for sync message");
}

void loop(){    
  if (Serial.available()) {
    processSyncMessage();
  }
  if (timeStatus()!= timeNotSet) {
    digitalClockDisplay();  
  }
  if (timeStatus() == timeSet) {
    digitalWrite(13, HIGH); // LED on if synced
  } else {
    digitalWrite(13, LOW);  // LED off if needs refresh
  }
  delay(1000);
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

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


void processSyncMessage() {
  unsigned long pctime;
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013

  if(Serial.find(TIME_HEADER)) {
     pctime = Serial.parseInt();
     if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013)
       setTime(pctime); // Sync Arduino clock to the time received on the serial port
     }
  }
}

time_t requestSync()
{
  Serial.write(TIME_REQUEST);  
  return 0; // the time will be sent later in response to serial mesg
}

Arduino Time library

Alarms library

SyncArduinoClock is a Processing sketch that responds from the PC to Arduino requests for
time synchronization messages.

/**
 * SyncArduinoClock. 
 *
 * portIndex must be set to the port connected to the Arduino
 * 
 * The current time is sent in response to request message from Arduino 
 * or by clicking the display window 
 *
 * The time message is 11 ASCII text characters; a header (the letter 'T')
 * followed by the ten digit system time (unix time)
 */
 

import processing.serial.*;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;

public static final short portIndex = 0;  // select the com port, 0 is the first port
public static final String TIME_HEADER = "T"; //header for arduino serial time message 
public static final char TIME_REQUEST = 7;  // ASCII bell character 
public static final char LF = 10;     // ASCII linefeed
public static final char CR = 13;     // ASCII linefeed
Serial myPort;     // Create object from Serial class

void setup() {  
  size(200, 200);
  println(Serial.list());
  println(" Connecting to -> " + Serial.list()[portIndex]);
  myPort = new Serial(this,Serial.list()[portIndex], 9600);
  println(getTimeNow());
}

void draw()
{
  textSize(20);
  textAlign(CENTER);
  fill(0);
  text("Click to send\nTime Sync", 0, 75, 200, 175);
  if ( myPort.available() > 0) {  // If data is available,
    char val = char(myPort.read());         // read it and store it in val
    if(val == TIME_REQUEST){
       long t = getTimeNow();
       sendTimeMessage(TIME_HEADER, t);   
    }
    else
    { 
       if(val == LF)
           ; //igonore
       else if(val == CR)           
         println();
       else  
         print(val); // echo everying but time request
    }
  }  
}

void mousePressed() {  
  sendTimeMessage( TIME_HEADER, getTimeNow());   
}


void sendTimeMessage(String header, long time) {  
  String timeStr = String.valueOf(time);  
  myPort.write(header);  // send header and time to arduino
  myPort.write(timeStr); 
  myPort.write('\n');  
}

long getTimeNow(){
  // java time is in ms, we want secs    
  Date d = new Date();
  Calendar cal = new GregorianCalendar();
  long current = d.getTime()/1000;
  long timezone = cal.get(cal.ZONE_OFFSET)/1000;
  long daylight = cal.get(cal.DST_OFFSET)/1000;
  return current + timezone + daylight; 
}

http://playground.arduino.cc/Interfacing/Processing

Hello All for the helpful replies. I finally found a program called "gobetwino" on the web - which runs on the laptop. This program sends current TIME and DATE based on requests from Arduino. I wrote simple code using Serial.read () for the Arudino to run and it works perfectly. So, my problem is resolved.

I did not do a good job of explaining why i needed to find out the current time in my previous post. Here are the details:

I am trying to build a sun tracking solar panel. The movement of the solar panel is controlled by a servo motor which is controlled by the Arduino. In order for Arduino to know how much the servo motor should move, i needed the current date and time, and the sunrise and sunset time for my location. I found the library sunrise.h - which gives me sunrise and sunset time for my location. But, I still needed current time - which is why i asked the question.

Now, I have finally figured it out - on how to get current date and time from the laptop.

So, thank you all for the help !!!

Arduino rocks.

If you already have an controller for moving the panel, you can add sensors for true sun position determination in your next version.

Hah! That's interesting. While I said

I submit that Arduino only needs to know the time if it is being used to tell you the time now, i.e. be a clock, or if it needs to tell you when something happened. In the case of the former, it makes more sense to be disconnected from the PC - and use an RTC.

I now realise I should have said

I submit that Arduino only needs to know the time if it is being used to tell you the time now, i.e. be a clock, or if it needs to tell you when something happened, or it needs to know the time in order to perform a task.

In the third case it probably again makes more sense to use an RTC, but that depends on whether you can find better things to do with your laptop and/or are prepared to pay $2.50 for an RTC.

Since the sun's path is entirely predictable, I submit it makes as sense to use time to control a collector as use sensors.

Yep, an RTC makes sense. I will add it in - in my next version. Thanks !!

Can you post how you were able to get the time from the Serial to the Arduino?