0% found this document useful (0 votes)
25 views

7 Using Time and Dates

The document discusses techniques for handling time delays, time measurement, and real-world times and dates in Arduino. It covers the built-in delay() and millis() functions, and introduces additional methods like using variables to represent durations longer than milliseconds and measuring pulse lengths with microsecond accuracy using pulseIn(). Examples are provided to illustrate creating delays of various durations, measuring elapsed time, and blinking an LED on a repeating interval while performing other tasks.

Uploaded by

Adrian Jidveian
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views

7 Using Time and Dates

The document discusses techniques for handling time delays, time measurement, and real-world times and dates in Arduino. It covers the built-in delay() and millis() functions, and introduces additional methods like using variables to represent durations longer than milliseconds and measuring pulse lengths with microsecond accuracy using pulseIn(). Examples are provided to illustrate creating delays of various durations, measuring elapsed time, and blinking an LED on a repeating interval while performing other tasks.

Uploaded by

Adrian Jidveian
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

CHAPTER 12

Using Time and Dates

12.0 Introduction
0DQDJLQJWLPHLVDIXQGDPHQWDOHOHPHQWRILQWHUDFWLYHFRPSXWLQJ7KLVFKDSWHUFRYHUV
EXLOWLQ$UGXLQRIXQFWLRQVDQGLQWURGXFHVPDQ\DGGLWLRQDOWHFKQLTXHVIRUKDQGOLQJ
WLPHGHOD\VWLPHPHDVXUHPHQWDQGUHDOZRUOGWLPHVDQGGDWHV

12.1 Creating Delays


Problem
<RXZDQW\RXUVNHWFKWRSDXVHIRUVRPHSHULRGRIWLPH7KLVPD\EHVRPHQXPEHURI
PLOOLVHFRQGVRUDWLPHJLYHQLQVHFRQGVPLQXWHVKRXUVRUGD\V

Solution
7KH $UGXLQR delay IXQFWLRQ LV XVHG LQ PDQ\ VNHWFKHV WKURXJKRXW WKLV ERRN delay
SDXVHVDVNHWFKIRUWKHQXPEHURIPLOOLVHFRQGVVSHFLILHGDVDSDUDPHWHU 7KHUHDUH
PLOOLVHFRQGVLQRQHVHFRQG 7KHVNHWFKWKDWIROORZVVKRZVKRZ\RXFDQXVH
delayWRJHWDOPRVWDQ\LQWHUYDO
/*
* delay sketch
*/

const long oneSecond = 1000; // a second is a thousand milliseconds


const long oneMinute = oneSecond * 60;
const long oneHour = oneMinute * 60;
const long oneDay = oneHour * 24;

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

367
void loop()
{
Serial.println("delay for 1 millisecond");
delay(1);
Serial.println("delay for 1 second");
delay(oneSecond);
Serial.println("delay for 1 minute");
delay(oneMinute);
Serial.println("delay for 1 hour");
delay(oneHour);
Serial.println("delay for 1 day");
delay(oneDay);
Serial.println("Ready to start over");
}

Discussion
7KHdelayIXQFWLRQKDVDUDQJHIURPRQHRQHWKRXVDQGWKRIDVHFRQGWRDURXQGGD\V
MXVWOHVVWKDQGD\VLIXVLQJDQXQVLJQHGORQJYDULDEOHW\SHVHH&KDSWHUIRUPRUH
RQYDULDEOHW\SHV 
7KHdelayIXQFWLRQSDXVHVWKHH[HFXWLRQRI\RXUVNHWFKIRUWKHGXUDWLRQRIWKHGHOD\
,I\RXQHHGWRSHUIRUPRWKHUWDVNVZLWKLQWKHGHOD\SHULRGXVLQJmillisDVH[SODLQHG
LQ5HFLSHLVPRUHVXLWDEOH
<RXFDQXVHdelayMicrosecondsWRGHOD\VKRUWSHULRGV7KHUHDUHPLFURVHFRQGV
LQRQHPLOOLVHFRQGDQGPLOOLRQPLFURVHFRQGVLQRQHVHFRQGdelayMicrosecondsZLOO
SDXVHIURPRQHPLFURVHFRQGWRDURXQGPLOOLVHFRQGVEXWIRUGHOD\VORQJHUWKDQD
IHZWKRXVDQGPLFURVHFRQGV\RXVKRXOGXVHdelayLQVWHDG
delayMicroseconds(10); // delay for 10 microseconds

delayDQG delayMicrosecondsZLOOGHOD\IRUDWOHDVWWKHDPRXQWRIWLPH
JLYHQDVWKHSDUDPHWHUEXWWKH\FRXOGGHOD\DOLWWOHORQJHULILQWHUUXSWV
RFFXUZLWKLQWKHGHOD\WLPH

See Also
7KH$UGXLQRUHIHUHQFHIRUdelayKWWSZZZDUGXLQRFFHQ5HIHUHQFH'HOD\

12.2 Using millis to Determine Duration


Problem
<RXZDQWWRNQRZKRZPXFKWLPHKDVHODSVHGVLQFHDQHYHQWKDSSHQHGIRUH[DPSOH
KRZORQJDVZLWFKKDVEHHQKHOGGRZQ

368 | Chapter 12: Using Time and Dates


Solution
$UGXLQRKDVDIXQFWLRQQDPHG millis VKRUWIRUPLOOLVHFRQGV WKDWLVXVHGLQWKHIRO
ORZLQJVNHWFKWRSULQWKRZORQJDEXWWRQZDVSUHVVHG VHH5HFLSHIRUGHWDLOVRQ
KRZWRFRQQHFWWKHVZLWFK 
/*
millisDuration sketch
returns the number of milliseconds that a button has been pressed
*/

const int switchPin = 2; // the number of the input pin

long startTime; // the value returned from millis when the switch is pressed
long duration; // variable to store the duration

void setup()
{
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH); // turn on pull-up resistor
Serial.begin(9600);
}

void loop()
{
if(digitalRead(switchPin) == LOW)
{
// here if the switch is pressed
startTime = millis();
while(digitalRead(switchPin) == LOW)
; // wait while the switch is still pressed
long duration = millis() - startTime;
Serial.println(duration);
}
}

Discussion
7KHmillisIXQFWLRQUHWXUQVWKHQXPEHURIPLOOLVHFRQGVVLQFHWKHFXUUHQWVNHWFKVWDUWHG
UXQQLQJ7KLVQXPEHUZLOORYHUIORZ JREDFNWR]HUR LQDSSUR[LPDWHO\GD\V
%\VWRULQJWKHVWDUWWLPHIRUDQHYHQW\RXFDQGHWHUPLQHWKHGXUDWLRQRIWKHHYHQWE\
VXEWUDFWLQJWKHVWDUWWLPHIURPWKHFXUUHQWWLPHDVVKRZQKHUH
long duration = millis() - startTime;

<RXFDQFUHDWH\RXURZQGHOD\IXQFWLRQXVLQJ millisWKDWFDQFRQWLQXHWRGRRWKHU
WKLQJVZKLOHFKHFNLQJUHSHDWHGO\WRVHHLIWKHGHOD\SHULRGKDVSDVVHG2QHH[DPSOHRI
WKLVFDQEHIRXQGLQWKH%OLQN:LWKRXW'HOD\VNHWFKSURYLGHGZLWKWKH$UGXLQRGLVWUL
EXWLRQ+HUHLVWKHORRSFRGHLQWKDWVNHWFK

12.2 Using millis to Determine Duration | 369


void loop()
{
// here is where you'd put code that needs to be running all the time...

7KHQH[WOLQHFKHFNVWRVHHLIWKHGHVLUHGLQWHUYDOKDVSDVVHG
if (millis() - previousMillis > interval)
{
// save the last time you blinked the LED

,I WKH LQWHUYDO KDV SDVVHG WKH FXUUHQW millis YDOXH LV VDYHG LQ WKH YDULDEOH
previousMillis
previousMillis = millis();

// if the LED is off turn it on and vice versa:


if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// set the LED with the ledState of the variable:


digitalWrite(ledPin, ledState);
}
}

+HUHLVDZD\WRSDFNDJHWKLVORJLFLQWRDIXQFWLRQQDPHG myDelayWKDWZLOOGHOD\WKH
FRGHLQloopEXWFDQSHUIRUPVRPHDFWLRQGXULQJWKHGHOD\SHULRG<RXFDQFXVWRPL]H
WKHIXQFWLRQDOLW\IRU\RXUDSSOLFDWLRQEXWLQWKLVH[DPSOHDQ/('LVIODVKHGILYHWLPHV
SHUVHFRQGHYHQZKLOHWKHSULQWVWDWHPHQWLQloopLVGHOD\HGIRUIRXUVHFRQGLQWHUYDOV
// blink an LED for a set amount of time
const int ledPin = 13; // the number of the LED pin

int ledState = LOW; // ledState used to set the LED


long previousMillis = 0; // will store last time LED was updated

void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}

void loop()
{
Serial.println(millis() / 1000); // print the number of elapsed seconds every
four seconds
// wait four seconds (but at the same time, quickly blink an LED)
myDelay(4000);
}

// duration is delay time in milliseconds


void myDelay(unsigned long duration)
{
unsigned long start = millis();

370 | Chapter 12: Using Time and Dates


while (millis() - start <= duration)
{
blink(100); // blink the LED inside the while loop
}
}

// interval is the time that the LED is on and off


void blink(long interval)
{
if (millis() - previousMillis > interval)
{
// save the last time you blinked the LED
previousMillis = millis();
// if the LED is off turn it on and vice versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);
}
}

<RXFDQSXWFRGHLQWKH myDelayIXQFWLRQIRUDQDFWLRQWKDW\RXZDQWWRKDSSHQUH
SHDWHGO\ZKLOHWKHIXQFWLRQZDLWVIRUWKHVSHFLILHGWLPHWRHODSVH
$QRWKHUDSSURDFKLVWRXVHDWKLUGSDUW\OLEUDU\DYDLODEOHIURPWKH$UGXLQR3OD\JURXQG
FDOOHG7LPHG$FWLRQ KWWSZZZDUGXLQRFFSOD\JURXQG&RGH7LPHG$FWLRQ 
#include <TimedAction.h>

//this initializes a TimedAction class that will change the state of an LED
every second.
TimedAction timedAction = TimedAction(NO_PREDELAY,1000,blink);

const int ledPin = 13; // the number of the LED pin


boolean ledState = false;

void setup()
{
pinMode(ledPin,OUTPUT);
digitalWrite(ledPin,ledState);
}

void loop()
{
timedAction.check();
}

void blink()
{
if (ledState == LOW)
ledState = HIGH;
else

12.2 Using millis to Determine Duration | 371


ledState = LOW;

ledState ? ledState=false : ledState=true;


digitalWrite(ledPin,ledState);
}

See Also
7KH$UGXLQRUHIHUHQFHIRUmillisKWWSZZZDUGXLQRFFHQ5HIHUHQFH0LOOLV

12.3 More Precisely Measuring the Duration of a Pulse


Problem
<RXZDQWWRGHWHUPLQHWKHGXUDWLRQRIDSXOVHZLWKPLFURVHFRQGDFFXUDF\IRUH[DPSOH
WRPHDVXUHWKHH[DFWWLPHEHWZHHQWZREXWWRQSUHVVHV

Solution
7KHpulseInIXQFWLRQUHWXUQVWKHGXUDWLRQLQPLFURVHFRQGVIRUDFKDQJLQJVLJQDORQD
GLJLWDOSLQ7KLVVNHWFKSULQWVWKHWLPHWKDWWKHYROWDJHRQDGLJLWDOSLQLVKHOGLOWE\D
EXWWRQSUHVV$VLQ5HFLSHWKLVXVHVWKHZLULQJVKRZQLQ5HFLSH
/*
PulseIn sketch
uses pulseIn to display how long a switch is pressed and released
*/

const int inputPin = 2; // input pin for the switch

long val;

void setup()
{
pinMode(inputPin, INPUT);
digitalWrite(inputPin,HIGH); // turn on internal pull-up on the inputPin
Serial.begin(9600);
Serial.println("Press and release switch");
}

void loop()
{

val = pulseIn(inputPin, LOW);


if( val != 0) // timeout returns 0
{
Serial.print("switch pressed for ");
Serial.print(val);
Serial.println(" microseconds");
}
}

372 | Chapter 12: Using Time and Dates


Discussion
pulseInFDQPHDVXUHKRZORQJDSXOVHLVHLWKHUHIGHRULOW
pulseIn(pin, HIGH); // returns microseconds that pulse is HIGH
pulseIn(pin, LOW) // returns microseconds that pulse is LOW

7KHpulseInIXQFWLRQZDLWVIRUWKHSXOVHWRVWDUW RUIRUDWLPHRXWLIWKHUHLVQRSXOVH 
%\GHIDXOWLWZLOOVWRSZDLWLQJDIWHURQHVHFRQGEXW\RXFDQFKDQJHWKDWE\VSHFLI\LQJ
WKHWLPHWRZDLWLQPLFURVHFRQGVDVDWKLUGSDUDPHWHU QRWHWKDWPLFURVHFRQGV
HTXDOVPLOOLVHFRQG 
pulseIn(pin, HIGH, 5000); // wait 5 milliseconds for the pulse to start

7KHWLPHRXWYDOXHRQO\PDWWHUVLIWKHSXOVHGRHVQRWVWDUWZLWKLQWKH
JLYHQSHULRG2QFHWKHVWDUWRIDSXOVHLVGHWHFWHGWKHIXQFWLRQZLOOVWDUW
WLPLQJDQGZLOOQRWUHWXUQXQWLOWKHSXOVHHQGV

pulseInFDQPHDVXUHYDOXHVEHWZHHQDURXQGPLFURVHFRQGVWRWKUHHPLQXWHVLQGX
UDWLRQEXWWKHYDOXHRIORQJSXOVHVPD\QRWEHYHU\DFFXUDWH

See Also
7KH$UGXLQRUHIHUHQFHIRUpulseInKWWSZZZDUGXLQRFFHQ5HIHUHQFH3XOVH,Q
5HFLSHVKRZV pulseInXVHGWRPHDVXUHWKHSXOVHZLGWKRIDQXOWUDVRQLFGLVWDQFH
VHQVRU
5HFLSHSURYLGHVPRUHLQIRUPDWLRQRQXVLQJKDUGZDUHLQWHUUXSWV

12.4 Using Arduino As a Clock


Problem
<RXZDQWWRXVHWKHWLPHRIGD\ KRXUVPLQXWHVDQGVHFRQGV LQDVNHWFKDQG\RX
GRQWZDQWWRFRQQHFWH[WHUQDOKDUGZDUH

Solution
7KLVVNHWFKXVHVWKH7LPHOLEUDU\WRGLVSOD\WKHWLPHRIGD\
/*
* Time sketch
*
*/

#include <Time.h>

12.4 Using Arduino As a Clock | 373


void setup()
{
Serial.begin(9600);
setTime(12,0,0,1,1,11); // set time to noon Jan 1 2011
}

void loop()
{
digitalClockDisplay();
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 clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}

Discussion
7KH7LPHOLEUDU\HQDEOHV\RXWRNHHSWUDFNRIWKHGDWHDQGWLPH$VWDQGDUG$UGXLQR
ERDUGXVHVDTXDUW]FU\VWDOIRUWLPLQJDQGWKLVLVDFFXUDWHWRDFRXSOHRIVHFRQGVSHU
GD\EXWLWGRHVQRWKDYHDEDWWHU\WRUHPHPEHUWKHWLPHZKHQSRZHULVVZLWFKHGRII
7KHUHIRUHWLPHZLOOUHVWDUWIURPHDFKWLPHDVNHWFKVWDUWVVR\RXQHHGWRVHWWKHWLPH
XVLQJWKHsetTimeIXQFWLRQ7KHVNHWFKVHWVWKHWLPHWRQRRQRQ-DQXDU\HDFKWLPHLW
VWDUWV

7KH7LPHOLEUDU\XVHVDVWDQGDUGNQRZQDV8QL[ DOVRFDOOHG326,;
WLPH7KHYDOXHVUHSUHVHQWWKHQXPEHURIHODSVHGVHFRQGVVLQFH-DQXDU\
([SHULHQFHG&SURJUDPPHUVPD\UHFRJQL]HWKDWWKLVLVWKHVDPH
DVWKHtime_tXVHGLQWKH,62VWDQGDUG&OLEUDU\IRUVWRULQJWLPHYDOXHV

2IFRXUVHLWVPRUHXVHIXOWRVHWWKHWLPHWR\RXUFXUUHQWORFDOWLPHLQVWHDGRIDIL[HG
YDOXH 7KH IROORZLQJ VNHWFK JHWV WKH QXPHULFDO WLPH YDOXH WKH QXPEHU RI HODSVHG
VHFRQGVVLQFH-DQXDU\ IURPWKHVHULDOSRUWWRVHWWKHWLPH<RXFDQHQWHUD

374 | Chapter 12: Using Time and Dates


YDOXHXVLQJWKH6HULDO0RQLWRU WKHFXUUHQW8QL[WLPHFDQEHIRXQGRQDQXPEHURI
ZHEVLWHVXVLQJWKH*RRJOHVHDUFKWHUPV8QL[WLPHFRQYHUW 
/*
* TimeSerial sketch
* 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 2011
T 1293883200
*
* A Processing example sketch to automatically send the messages is included in
the download
*/

#include <Time.h>

#define TIME_MSG_LEN 11 // time sync consists of a HEADER followed by ten


ascii digits
#define TIME_HEADER 'T' // Header tag for serial time sync message

void setup() {
Serial.begin(9600);
Serial.println("Waiting for time sync message");
}

void loop(){
if(Serial.available() )
{
processSyncMessage();
}
if(timeStatus()!= timeNotSet)
{
// here if the time has been set
digitalClockDisplay();
}
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();
}

12.4 Using Arduino As a Clock | 375


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() {
// if time sync available from serial port, update time and return true
// time message consists of a header and ten ascii digits
while(Serial.available() >= TIME_MSG_LEN ){
char c = Serial.read() ;
Serial.print(c);
if( c == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
c = Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
setTime(pctime); // Sync clock to the time received on serial port
}
}
}

7KHFRGHWRGLVSOD\WKHWLPHDQGGDWHLVWKHVDPHDVEHIRUHEXWQRZWKHVNHWFKZDLWV
WRUHFHLYHWKHWLPHIURPWKHVHULDOSRUW6HHWKH'LVFXVVLRQLQ5HFLSHLI\RXDUHQRW
IDPLOLDUZLWKKRZWRUHFHLYHQXPHULFGDWDXVLQJWKHVHULDOSRUW
$SURFHVVLQJVNHWFKQDPHG6\QF$UGXLQR&ORFNLVLQFOXGHGZLWKWKH7LPHOLEUDU\H[
DPSOHV LWVLQWKH7LPH([DPSOHV3URFHVVLQJ6\QF$UGXLQR&ORFNIROGHU 7KLV3URFHVV
LQJVNHWFKZLOOVHQGWKHFXUUHQWWLPHIURP\RXUFRPSXWHUWR$UGXLQRDWWKHFOLFNRID
PRXVH5XQ6\QF$UGXLQR&ORFNLQ3URFHVVLQJHQVXULQJWKDWWKHVHULDOSRUWLVWKHRQH
FRQQHFWHGWR$UGXLQR &KDSWHUGHVFULEHVKRZWRUXQD3URFHVVLQJVNHWFKWKDWWDONV
WR $UGXLQR  <RX VKRXOG VHH WKH PHVVDJH Waiting for time sync message VHQW E\
$UGXLQRDQGGLVSOD\HGLQWKH3URFHVVLQJWH[WDUHD WKHEODFNDUHDIRUWH[WPHVVDJHVDW
WKHERWWRPRIWKH3URFHVVLQJ,'( &OLFNWKH3URFHVVLQJDSSOLFDWLRQZLQGRZ LWVD
SL[HOJUD\VTXDUH DQG\RXVKRXOGVHHWKHWH[WDUHDGLVSOD\WKHWLPHDVSULQWHGE\WKH
$UGXLQRVNHWFK
<RXFDQDOVRVHWWKHFORFNIURPWKH6HULDO0RQLWRULI\RXFDQJHWWKHFXUUHQW8QL[WLPH
KWWSZZZHSRFKFRQYHUWHUFRPLVRQHRIPDQ\ZHEVLWHVWKDWSURYLGHWKHWLPHLQWKLV
IRUPDW&RS\WKHGLJLWQXPEHULQGLFDWHGDVWKHFXUUHQW8QL[WLPHDQGSDVWHWKLV
LQWRWKH6HULDO0RQLWRU6HQGZLQGRZ3UHFHGHWKHQXPEHUZLWKWKHOHWWHU7DQGFOLFN
6HQG)RUH[DPSOHLI\RXVHQGWKLV
T1282041639

376 | Chapter 12: Using Time and Dates


$UGXLQRVKRXOGUHVSRQGE\GLVSOD\LQJWKHWLPHHYHU\VHFRQG
10:40:49 17 8 2010
10:40:50 17 8 2010
10:40:51 17 8 2010
10:40:52 17 8 2010
10:40:53 17 8 2010
10:40:54 17 8 2010
. . .

<RXFDQDOVRVHWWKHWLPHXVLQJEXWWRQVRURWKHULQSXWGHYLFHVVXFKDVWLOWVHQVRUVD
MR\VWLFNRUDURWDU\HQFRGHU
7KHIROORZLQJVNHWFKXVHVWZREXWWRQVWRPRYHWKHFORFNKDQGVIRUZDUGRUEDFNZDUG
)LJXUHVKRZVWKHFRQQHFWLRQV VHH5HFLSHLI\RXQHHGKHOSXVLQJVZLWFKHV 
/*
AdjustClockTime sketch
buttons on pins 2 and 3 adjust the time
*/

#include <Time.h>

const int btnForward = 2; // button to move time forward


const int btnBack = 3; // button to move time back

unsigned long prevtime; // when the clock was last displayed

void setup()
{
digitalWrite(btnForward, HIGH); // enable internal pull-up resistors
digitalWrite(btnBack, HIGH);
setTime(12,0,0,1,1,11); // start with the time set to noon Jan 1 2011
Serial.begin(9600);
Serial.println("ready");
}

void loop()
{
prevtime = now(); // note the time
while( prevtime == now() ) // stay in this loop till the second changes
{
// check if the set button pressed while waiting for second to roll over
if(checkSetTime())
prevtime = now(); // time changed so reset start time
}
digitalClockDisplay();
}

7KH VNHWFK XVHV WKH VDPH digitalClockDisplay DQG printDigits IXQFWLRQV IURP
5HFLSHVRFRS\WKRVHSULRUWRUXQQLQJWKHVNHWFK

12.4 Using Arduino As a Clock | 377


)LJXUH7ZREXWWRQVXVHGWRDGMXVWWKHWLPH
+HUHLVDYDULDWLRQRQWKLVVNHWFKWKDWXVHVWKHSRVLWLRQRIDYDULDEOHUHVLVWRUWRGHWHUPLQH
WKHGLUHFWLRQDQGUDWHRIDGMXVWPHQWZKHQDVZLWFKLVSUHVVHG
#include <Time.h>

const int potPin = 0; // pot to determine direction and speed


const int buttonPin = 2; // button enables time adjustment

unsigned long prevtime; // when the clock was last displayed

void setup()
{
digitalWrite(buttonPin, HIGH); // enable internal pull-up resistors
setTime(12,0,0,1,1,11); // start with the time set to noon Jan 1 2011
Serial.begin(9600);
}

void loop()
{
prevtime = now(); // note the time
while( prevtime == now() ) // stay in this loop till the second changes
{
// check if the set button pressed while waiting for second to roll over
if(checkSetTime())
prevtime = now(); // time changed so reset start time
}
digitalClockDisplay();
}

// functions checks to see if the time should be adjusted


// returns true if time was changed
boolean checkSetTime()

378 | Chapter 12: Using Time and Dates


{
int value; // a value read from the pot
int step; // the number of seconds to move (backwards if negative)
boolean isTimeAdjusted = false; // set to true if the time is adjusted

while(digitalRead(buttonPin)== LOW)
{
// here while button is pressed
value = analogRead(potPin); // read the pot value
step = map(value, 0,1023, 10, -10); // map value to the desired range
if( step != 0)
{
adjustTime(step);
isTimeAdjusted = true; // to tell the user that the time has changed
digitalClockDisplay(); // update clock
delay(100);
}
}
return isTimeAdjusted;
}

7KHSUHFHGLQJVNHWFKXVHVWKHVDPH digitalClockDisplayDQG printDigitsIXQFWLRQV


IURP5HFLSHVRFRS\WKRVHSULRUWRUXQQLQJWKHVNHWFK)LJXUHVKRZVKRZ
WKHYDULDEOHUHVLVWRUDQGVZLWFKDUHFRQQHFWHG

)LJXUH$YDULDEOHUHVLVWRUXVHGWRDGMXVWWKHWLPH

12.4 Using Arduino As a Clock | 379


$OOWKHVHH[DPSOHVSULQWWRWKHVHULDOSRUWEXW\RXFDQSULQWWKHRXWSXWWR/('VRU
/&'V7KHGRZQORDGIRUWKH*UDSKLFDO/&'FRYHUHGLQ5HFLSHFRQWDLQVH[DPSOH
VNHWFKHVIRUGLVSOD\LQJDQGVHWWLQJWLPHXVLQJDQDQDORJFORFNGLVSOD\GUDZQRQWKH
/&'
7KH7LPHOLEUDU\LQFOXGHVFRQYHQLHQFHIXQFWLRQVIRUFRQYHUWLQJWRDQGIURPYDULRXV
WLPHIRUPDWV)RUH[DPSOH\RXFDQILQGRXWKRZPXFKWLPHKDVHODSVHGVLQFHWKHVWDUW
RIWKHGD\DQGKRZPXFKWLPHUHPDLQVXQWLOWKHGD\VHQG<RXFDQORRNLQ7LPHKLQ
WKHOLEUDULHVIROGHUIRUWKHFRPSOHWHOLVW0RUHGHWDLOVDUHDYDLODEOHLQ&KDSWHU
dayOfWeek( now() ); //the day of the week (Sunday is day 1)
elapsedSecsToday( now() ); // returns the number of seconds since the start
of today
nextMidnight( now() ); // how much time to the end of the day
elapsedSecsThisWeek( now() ); // how much time has elapsed since the start of
the week

<RXFDQDOVRSULQWWH[WVWULQJVIRUWKHGD\VDQGPRQWKVKHUHLVDYDULDWLRQRQWKHGLJLWDO
FORFNGLVSOD\FRGHWKDWSULQWVWKHQDPHVRIWKHGD\DQGPRQWK
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(dayStr(weekday())); // print the day of the week
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(monthShortStr(month())); // print the month (abbreviated)
Serial.print(" ");
Serial.print(year());
Serial.println();
}

See Also
$UGXLQR7LPHOLEUDU\UHIHUHQFHKWWSZZZDUGXLQRFFSOD\JURXQG&RGH7LPH
:LNLSHGLDDUWLFOHRQ8QL[WLPHKWWSHQZLNLSHGLDRUJZLNL8QL[BWLPH
KWWSZZZHSRFKFRQYHUWHUFRP DQG KWWSZZZRQOLQHFRQYHUVLRQFRPXQL[BWLPHKWP
DUHWZRSRSXODU8QL[WLPHFRQYHUVLRQWRROV

12.5 Creating an Alarm to Periodically Call a Function


Problem
<RXZDQWWRSHUIRUPVRPHDFWLRQRQVSHFLILFGD\VDQGDWVSHFLILFWLPHVRIWKHGD\

380 | Chapter 12: Using Time and Dates


Solution
7LPH$ODUPVLVDFRPSDQLRQOLEUDU\LQFOXGHGLQWKH7LPHOLEUDU\GRZQORDGGLVFXVVHG
LQ5HFLSH LQVWDOOLQJWKH7LPHOLEUDU\ZLOODOVRLQVWDOOWKH7LPH$ODUPVOLEUDU\ 
7LPH$ODUPVPDNHVLWHDV\WRFUHDWHWLPHDQGGDWHDODUPV
/*
* TimeAlarmExample sketch
*
* This example calls alarm functions at 8:30 am and at 5:45 pm (17:45)
* and simulates turning lights on at night and off in the morning
*
* A timer is called every 15 seconds
* Another timer is called once only after 10 seconds
*
* At startup the time is set to Jan 1 2010 8:29 am
*/

#include <Time.h>
#include <TimeAlarms.h>

void setup()
{
Serial.begin(9600);
Serial.println("TimeAlarms Example");
Serial.println("Alarms are triggered daily at 8:30 am and 17:45 pm");
Serial.println("One timer is triggered every 15 seconds");
Serial.println("Another timer is set to trigger only once after 10 seconds");
Serial.println();

setTime(8,29,40,1,1,10); // set time to 8:29:40am Jan 1 2010

Alarm.alarmRepeat(8,30,0, MorningAlarm); // 8:30am every day


Alarm.alarmRepeat(17,45,0,EveningAlarm); // 5:45pm every day

Alarm.timerRepeat(15, RepeatTask); // timer for every 15 seconds


Alarm.timerOnce(10, OnceOnlyTask); // called once after 10 seconds
}

void MorningAlarm()
{
Serial.println("Alarm: - turn lights off");
}

void EveningAlarm()
{
Serial.println("Alarm: - turn lights on");
}

void RepeatTask()
{
Serial.println("15 second timer");
}

void OnceOnlyTask()

12.5 Creating an Alarm to Periodically Call a Function | 381


{
Serial.println("This timer only triggers once");
}

void loop()
{
digitalClockDisplay();
Alarm.delay(1000); // wait one second between clock display
}

void digitalClockDisplay()
{
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
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);
}

Discussion
<RXFDQVFKHGXOHWDVNVWRWULJJHUDWDSDUWLFXODUWLPHRIGD\ WKHVHDUHFDOOHGDODUPV
RUVFKHGXOHWDVNVWRRFFXUDIWHUDQLQWHUYDORIWLPHKDVHODSVHG FDOOHGWLPHUV (DFKRI
WKHVHWDVNVFDQEHFUHDWHGWRFRQWLQXRXVO\UHSHDWRUWRRFFXURQO\RQFH
7RVSHFLI\DQDODUPWRWULJJHUDWDVNUHSHDWHGO\DWDSDUWLFXODUWLPHRIGD\XVH
Alarm.alarmRepeat(8,30,0, MorningAlarm);

7KLVFDOOVWKHIXQFWLRQMorningAlarmDWDPHYHU\GD\
,I\RXZDQWWKHDODUPWRWULJJHURQO\RQFH\RXFDQXVHWKHalarmOncePHWKRG
Alarm.alarmOnce(8,30,0, MorningAlarm);

7KLVFDOOVWKHIXQFWLRQ MorningAlarmDVLQJOHWLPHRQO\ WKHQH[WWLPHLWLVDP


DQGZLOOQRWWULJJHUDJDLQ
7LPHUVWULJJHUWDVNVWKDWRFFXUDIWHUDVSHFLILHGLQWHUYDORIWLPHKDVSDVVHGUDWKHUWKDQ
DWDVSHFLILFWLPHRIGD\7KHWLPHULQWHUYDOFDQEHVSHFLILHGLQDQ\QXPEHURIVHFRQGV
RULQKRXUPLQXWHVDQGVHFRQGV
Alarm.timerRepeat(15, Repeats); // timer task every 15 seconds

7KLVFDOOVWKHRepeatsIXQFWLRQLQ\RXUVNHWFKHYHU\VHFRQGV

382 | Chapter 12: Using Time and Dates


,I\RXZDQWDWLPHUWRWULJJHURQFHRQO\XVHWKHtimerOncePHWKRG
Alarm.timerOnce(10, OnceOnly); // called once after 10 seconds

7KLVFDOOVWKHonceOnlyIXQFWLRQLQDVNHWFKVHFRQGVDIWHUWKHWLPHULVFUHDWHG

<RXU FRGH QHHGV WR FDOO Alarm.delay UHJXODUO\ EHFDXVH WKLV IXQFWLRQ
FKHFNV WKH VWDWH RI DOO WKH VFKHGXOHG HYHQWV )DLOLQJ WR UHJXODUO\ FDOO
Alarm.delayZLOOUHVXOWLQWKHDODUPVQRWEHLQJWULJJHUHG<RXFDQFDOO
Alarm.delay(0) LI \RX QHHG WR VHUYLFH WKH VFKHGXOHU ZLWKRXW D GHOD\
$OZD\VXVH Alarm.delayLQVWHDGRI delayZKHQXVLQJ7LPH$ODUPVLQD
VNHWFK

7KH7LPH$ODUPVOLEUDU\UHTXLUHVWKH7LPHOLEUDU\WREHLQVWDOOHGVHH5HFLSH1R
LQWHUQDORUH[WHUQDOKDUGZDUHLVUHTXLUHGWRXVHWKH7LPH$ODUPVOLEUDU\7KHVFKHGXOHU
GRHVQRWXVHLQWHUUXSWVVRWKHWDVNKDQGOLQJIXQFWLRQLVWKHVDPHDVDQ\RWKHUIXQFWLRQV
\RXFUHDWHLQ\RXUVNHWFK FRGHLQDQLQWHUUXSWKDQGOHUKDVUHVWULFWLRQVWKDWDUHGLV
FXVVHGLQ&KDSWHUEXWWKHVHGRQRWDSSO\WR7LPH$ODUPVIXQFWLRQV 
7LPHULQWHUYDOVFDQUDQJHIURPRQHVHFRQGWRVHYHUDO\HDUV ,I\RXQHHGWLPHULQWHUYDOV
VKRUWHUWKDQRQHVHFRQGWKH7LPHG$FWLRQOLEUDU\E\$OH[DQGHU%UHYLJPD\EHPRUH
VXLWDEOHVHHKWWSZZZDUGXLQRFFSOD\JURXQG&RGH7LPHG$FWLRQ
7DVNVDUHVFKHGXOHGIRUVSHFLILFWLPHVGHVLJQDWHGE\WKHV\VWHPFORFNLQWKH7LPHOLEUDU\
VHH5HFLSHIRUPRUHGHWDLOV ,I\RXFKDQJHWKHV\VWHPWLPH HJE\FDOOLQJ set
Time WKHWULJJHUWLPHVDUHQRWDGMXVWHG)RUH[DPSOHLI\RXXVHsetTimeWRPRYHRQH
KRXUDKHDGDOODODUPVDQGWLPHUVZLOORFFXURQHKRXUVRRQHU,QRWKHUZRUGVLILWV
DQGDWDVNLVVHWWRWULJJHULQWZRKRXUV DW DQGWKHQ\RXFKDQJHWKHFXUUHQW
WLPHWRWKHWDVNZLOOWULJJHULQRQHKRXU,IWKHV\VWHPWLPHLVVHWEDFNZDUGIRU
H[DPSOH WR WKH WDVN ZLOO WULJJHU LQ WKUHH KRXUV LH ZKHQ WKH V\VWHP WLPH
LQGLFDWHV ,IWKHWLPHLVUHVHWWRHDUOLHUWKDQWKHWLPHDWZKLFKDWDVNZDVVFKHGXOHG
WKHWDVNZLOOEHWULJJHUHGLPPHGLDWHO\ DFWXDOO\RQWKHQH[WFDOOWRAlarm.delay 
7KLVLVWKHH[SHFWHGEHKDYLRUIRUDODUPVWDVNVDUHVFKHGXOHGIRUDVSHFLILFWLPHRIGD\
DQGZLOOWULJJHUDWWKDWWLPHEXWWKHHIIHFWRQWLPHUVPD\EHOHVVFOHDU,IDWLPHULV
VFKHGXOHGWRWULJJHULQILYHPLQXWHVWLPHDQGWKHQWKHFORFNLVVHWEDFNE\RQHKRXU
WKDWWLPHUZLOOQRWWULJJHUXQWLORQHKRXUDQGILYHPLQXWHVKDYHHODSVHG HYHQLILWLVD
UHSHDWLQJWLPHUDUHSHDWGRHVQRWJHWUHVFKHGXOHGXQWLODIWHULWWULJJHUV 
8SWRVL[DODUPVDQGWLPHUVFDQEHVFKHGXOHGWRUXQDWWKHVDPHWLPH<RXFDQPRGLI\
WKHOLEUDU\WRHQDEOHPRUHWDVNVWREHVFKHGXOHG5HFLSHVKRZV\RXKRZWRGRWKLV
onceOnlyDODUPVDQGWLPHUVDUHIUHHGZKHQWKH\DUHWULJJHUHGDQG\RXFDQUHVFKHGXOH
WKHVHDVRIWHQDV\RXZDQWVRORQJDVWKHUHDUHQRPRUHWKDQVL[SHQGLQJDWRQHWLPH
7KHIROORZLQJFRGHJLYHVRQHH[DPSOHRIKRZDtimerOnceWDVNFDQEHUHVFKHGXOHG
Alarm.timerOnce(random(10), randomTimer); // trigger after random number of
seconds

12.5 Creating an Alarm to Periodically Call a Function | 383


void randomTimer(){
int period = random(2,10); // get a new random period
Alarm.timerOnce(period, randomTimer); // trigger for another random period
}

12.6 Using a Real-Time Clock


Problem
<RXZDQWWRXVHWKHWLPHRIGD\SURYLGHGE\DUHDOWLPHFORFN 57& ([WHUQDOERDUGV
XVXDOO\KDYHEDWWHU\EDFNXSVRWKHWLPHZLOOEHFRUUHFWHYHQZKHQ$UGXLQRLVUHVHWRU
WXUQHGRII

Solution
7KHVLPSOHVWZD\WRXVHDQ57&LVZLWKDFRPSDQLRQOLEUDU\IRUWKH7LPHOLEUDU\QDPHG
'657&K7KLVUHFLSHLVIRUWKHZLGHO\XVHG'6DQG'657&FKLSV
/*
* TimeRTC sketch
* example code illustrating Time library with real-time clock.
*
*/

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t

void setup() {
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
}

void loop()
{
digitalClockDisplay();
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());

384 | Chapter 12: Using Time and Dates


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);
}

0RVW57&ERDUGVIRU$UGXLQRXVHWKH,&SURWRFROIRUFRPPXQLFDWLQJ VHH&KDS
WHUIRUPRUHRQ,& &RQQHFWWKHOLQHPDUNHG6&/ RU&ORFN WR$UGXLQRDQDORJ
SLQDQG6'$ RU'DWD WRDQDORJSLQDVVKRZQLQ)LJXUH $QDORJSLQV
DQGDUHXVHGIRU,&VHH&KDSWHU 7DNHFDUHWRHQVXUHWKDW\RXFRQQHFWWKH9
SRZHUOLQHDQG*QGSLQVFRUUHFWO\

)LJXUH&RQQHFWLQJDUHDOWLPHFORFN

Discussion
7KHFRGHLVVLPLODUWRRWKHUUHFLSHVXVLQJWKH7LPHOLEUDU\EXWLWJHWVLWVYDOXHIURPWKH
57& UDWKHU WKDQ IURP WKH VHULDO SRUW RU KDUGFRGHG YDOXH 7KH RQO\ DGGLWLRQDO OLQH
QHHGHGLVWKLV
setSyncProvider(RTC.get); // the function to get the time from the RTC

7KHsetSyncProviderIXQFWLRQWHOOVWKH7LPHOLEUDU\KRZLWVKRXOGJHWLQIRUPDWLRQIRU
VHWWLQJ DQGXSGDWLQJ WKHWLPHRTC.getLVDPHWKRGZLWKLQWKH57&OLEUDU\WKDWUHWXUQV
WKHFXUUHQWWLPHLQWKHIRUPDWXVHGE\WKH7LPHOLEUDU\ 8QL[WLPH 

12.6 Using a Real-Time Clock | 385


(DFKWLPH$UGXLQRVWDUWVWKHsetupIXQFWLRQZLOOFDOORTC.getWRVHWWKHWLPHIURPWKH
57&KDUGZDUH
%HIRUH\RXFDQJHWWKHFRUUHFWWLPHIURPWKHPRGXOH\RXQHHGWRVHWLWVWLPH+HUHLV
DVNHWFKWKDWHQDEOHV\RXWRVHWWKHWLPHRQWKH57&KDUGZDUH\RXRQO\QHHGWRGR
WKLVZKHQ\RXILUVWDWWDFKWKHEDWWHU\WRWKH57&ZKHQUHSODFLQJWKHEDWWHU\RULIWKH
WLPHQHHGVWREHFKDQJHG
/*
* TimeRTCSet sketch
* example code illustrating Time library with real-time clock.
*
* RTC is set in response to serial port time message
* A Processing example sketch to set the time is included in the download
*/

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t

void setup() {
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
}

void loop()
{
if(Serial.available())
{
time_t t = processSyncMessage();
if(t >0)
{
RTC.set(t); // set the RTC and the system time to the received value
setTime(t);
}
}
digitalClockDisplay();
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(" ");

386 | Chapter 12: Using Time and Dates


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);
}

/* code to process time sync messages from the serial port */


#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by unix time_t
as ten ascii digits
#define TIME_HEADER 'T' // Header tag for serial time sync message

time_t processSyncMessage() {
// return the time if a valid sync message is received on the serial port.
// time message consists of a header and ten ascii digits
while(Serial.available() >= TIME_MSG_LEN ){
char c = Serial.read() ;
Serial.print(c);
if( c == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
c = Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
return pctime;
}
}
return 0;
}

7KLVVNHWFKLVDOPRVWWKHVDPHDVWKH7LPH6HULDOVNHWFKLQ5HFLSHIRUVHWWLQJWKH
WLPHIURPWKHVHULDOSRUWEXWKHUHWKHIROORZLQJIXQFWLRQLVFDOOHGZKHQDWLPHPHVVDJH
LVUHFHLYHGIURPWKHFRPSXWHUWRVHWWKH57&
RTC.set(t); // set the RTC and the system time to the received value

setTime(t);

7KH 57& FKLS XVHV ,& WR FRPPXQLFDWH ZLWK $UGXLQR ,& LV H[SODLQHG LQ &KDS
WHUVHH5HFLSHLI\RXDUHLQWHUHVWHGLQPRUHGHWDLOVRQ,&FRPPXQLFDWLRQZLWK
WKH57&FKLS

See Also
7KH6SDUN)XQ%2%GDWDVKHHWKWWSVWRUHJUDYLWHFKXVLFUHFOKWPO

12.6 Using a Real-Time Clock | 387


Download from Wow! eBook <www.wowebook.com>

You might also like