]> git.piffa.net Git - arduino/blob - books/pdummies/APFD_Chapter7_ArduinoClock/APFD_Chapter7_ArduinoClock.ino
first commit
[arduino] / books / pdummies / APFD_Chapter7_ArduinoClock / APFD_Chapter7_ArduinoClock.ino
1 /* Arduino Projects for Dummies
2  * by Brock Craft 
3  *
4  * Chapter 7: Building an Arduino Clock
5  * An alarm clock that uses the Adafruit Industries DS1307 RTC Breakout board
6  * and a 16x2 Parallel LCD Display
7  *
8  * Uses the default Wire and LiquitCrystal libraries
9  * and the Adafruit RTC library
10  *
11  * v0.1 30.04.2013
12  * Adapted from http://www.adafruit.com/products/746
13 */
14
15 #include <Wire.h>          // I2C Wire Library for communicating with the DS1307 RTC
16 #include "RTClib.h"        // Date and time functions for the DS1307 RTC connected
17 #include <LiquidCrystal.h> // Display functions for the LCD Display 
18
19 RTC_DS1307 rtc;                         // Create a realtime clock called rtc
20 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // Create an LCD called lcd 
21
22 DateTime now;        // Creates a DateTime object called now so that we can read from the RTC module
23
24 boolean displayAlarmSet = false;  // Whether we are in the show time mode or show alarm set mode
25 boolean alarm = false;   // Whether the alarm is set or not
26 boolean armed = false;   // Whether the alarm is armed or not
27
28 int alarmHrs = 12;   // You can set the alarm time in code, here
29 int alarmMins = 00;
30
31 // User input to set alarm time
32 const int alarmSetPin=6;           // Used to change to alarm set mode
33 const int incrementAlarmHrsPin=7;  // Used to increment the alarm hours in alarm set mode
34 const int incrementAlarmMinsPin=8; // Used to increment the alarm minutes in alarm set mode
35 const int piezoPin = 9;            // Used for the piezoelectric sounder
36 const int alarmArmedPin=10;        // Use to enable the alarm to go off
37
38
39 void setup () {
40   Wire.begin();      // Enables the communication for the LCD
41   rtc.begin();       // Enables the RTC
42   lcd.begin(16, 2);  // Enables he LCD
43   lcd.print("  It's Alive!");    // Print a message, centered, to the LCD to confirm is working
44   delay(1000);                    // Wait a moment so we can read it
45   lcd.clear();       // Clear the LCD
46
47   // Set several pins for input and output
48   pinMode(alarmSetPin, INPUT);   
49   pinMode(incrementAlarmHrsPin, INPUT);
50   pinMode(incrementAlarmMinsPin, INPUT);
51   pinMode(piezoPin, OUTPUT);
52   pinMode(alarmArmedPin, INPUT);
53   
54 }
55
56 void loop () {
57   now = rtc.now(); // Get the current time
58  
59   int alarmArmed=digitalRead(alarmArmedPin);
60   if (alarmArmed==HIGH){
61    armed=true;
62   } else {
63    armed=false;
64   }
65
66   // Determine whether to sound the alarm or not
67  if(armed){        // If the alarm is armed and...
68   if (!alarm){     // If we are not currently sounding the alarm
69     checkAlarm();  // Check to see if it is the time it should be triggered
70   } 
71   else {
72     soundAlarm();  // Otherwise, we should be sounding the alarm, so do it.
73   }
74 }
75   // Check whether we are in Alarm Set mode
76   int setMode = digitalRead(alarmSetPin);  // Read the pin that the switch is on 
77   if (setMode==HIGH){      // If the pin is high
78     displayAlarmSet=true;  // Set displayAlarmSet true. It's used by updateDisplay to switch between showing alarm or current time
79     setAlarm();            // Go read the switches to set the alarm
80   }
81   else {                   // If we aren't in set mode
82     displayAlarmSet=false; // We are not is net mode so make sure the flag is correct
83   }
84
85   // Refresh the display
86   updateDisplay();
87 }
88
89 // Update the display with either the current time or the time the alarm is set for
90 void updateDisplay(){
91    
92    if(displayAlarmSet){   // If we are in alarm set mode, DISPLAY ALARM SET TEXT
93     lcd.setCursor(0, 0);  // Set the cursor at the column zero, upper row
94     lcd.print("Set alarm time: ");
95     lcd.setCursor(4, 1);  // Move the cursor to column four, lower row
96     lcd.print(" ");       // Write over digits of the time that was previously displayed
97     lcd.setCursor(5, 1);  // Move to the next column so the time will be centered
98     if (alarmHrs<10){     // Integers of 0-9 are only one digit. If so...
99       lcd.print(0);       // ... add a zero in front of it     
100     }  
101     lcd.print(alarmHrs);  // Print the current alarm hour
102     lcd.setCursor(7, 1);  // Move to the next column
103     lcd.print(":");       // And print the colon
104     lcd.setCursor(8, 1);  // Move to the next column
105     if (alarmMins<10){    // Integers of 0-9 are only one digit. If so...
106       lcd.print(0);       // ... add a zero in front of it
107     }  
108     lcd.print(alarmMins); // Print the current alarm minutes
109     lcd.setCursor(10, 1); // Move to the next column
110     lcd.print("  ");      // Write spaces over the digits of time previously displayed
111   } 
112   else {                  // If we are in NOT alarm set mode, DISPLAY CURRENT TIME
113
114     int h = now.hour();   // Get the hours right now and store them in an integer called h
115     int m = now.minute(); // Get the minutes right now and store them in an integer called m
116     int s = now.second(); // Get the seconds right now and store them in an integer called s
117
118     lcd.setCursor(0, 0);  // Set the cursor at the column zero, upper row...
119     if(armed){
120       lcd.print("* The time is: ");
121     }
122     else {
123       lcd.print("  The time is: ");  // ...with spaces to clear characters from setting alarm. 
124     }
125     lcd.setCursor(4, 1);  // Move the cursor to column four, lower row
126
127     if (h<10){            // Add a zero, if necessary, as above
128       lcd.print(0); 
129     }  
130     lcd.print(h);         // Display the current hour  
131     lcd.setCursor(6, 1);  // Move to the next column
132     lcd.print(":");       // And print the colon
133     lcd.setCursor(7, 1);  // Move to the next column
134     if (m<10){            // Add a zero, if necessary, as above
135       lcd.print(0); 
136     }  
137     lcd.print(m);         // Display the current minute
138     lcd.setCursor(9, 1);  // Move to the next column
139     lcd.print(":");       // And print the colon
140     lcd.setCursor(10, 1); // Move to the next column
141     if (s<10){            // Add a zero, if necessary, as above
142       lcd.print(0);
143     }  
144     lcd.print(s);         // Display the current second
145   }
146
147 }
148
149 // Check whether to sound the alarm
150 void checkAlarm(){
151   if(alarmHrs==now.hour() && alarmMins==now.minute() && now.second()==0){  // If the alarm time is now, and it's zero seconds
152     alarm=true;  // set the alarm flag to be true. The next time the main loop executes, the alarm will be activated
153   } 
154 }
155
156 // Increment hours or minutes
157 void setAlarm(){
158   int hrs=digitalRead(incrementAlarmHrsPin); 
159   int mins=digitalRead(incrementAlarmMinsPin);
160
161   if (hrs==HIGH){    // If the hours switch is pressed
162     alarmHrs+=1;     // Increment the hours upward
163     delay(200);      // Wait a moment between incrementing the numbers
164     if(alarmHrs>23){ // if the hour is over 23, set it back to 0
165       alarmHrs=0; 
166     }
167   }
168   if (mins==HIGH){    // If the minutes switch is pressed
169     alarmMins+=1;     // Increment the minutes upward
170     delay(200);       // Wait a moment between incrementing the numbers
171     if(alarmMins>59){ // if the minute is over 59, set it back to 0
172       alarmMins=0; 
173     }
174   }
175 }
176
177 void soundAlarm() {
178   float alarmFrequency=1400;  // The value for the alarm tone in Hz
179   float period = (1.0 / alarmFrequency) * 1000000;
180   long beepDuration=250000;   // the time in microseconds
181   long elapsedTime = 0;
182
183   while (elapsedTime < beepDuration) {
184     digitalWrite(piezoPin,HIGH);
185     delayMicroseconds(period / 2);
186     digitalWrite(piezoPin, LOW);
187     delayMicroseconds(period / 2);
188     elapsedTime += (period);
189   }
190   digitalWrite(piezoPin, LOW);         
191   delayMicroseconds(beepDuration);
192
193   // Listend for either button to be pressed and if so, turn off the alarm
194   int hrs=digitalRead(incrementAlarmHrsPin); 
195   int mins=digitalRead(incrementAlarmMinsPin);
196
197   if (hrs==HIGH || mins==HIGH){
198     alarm=false;
199   }
200 }
201
202