Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * LCD Alarm Clock with Temperature
- *
- * Arduino powered alarm clock that shows the time and temperature
- * Alarm can be set. Alarm creates tone at piezo and flashes LED
- *
- * Settings controlled with two buttons:
- * - button 1: set time
- * - button 1: cycle hr/min/24hr
- * - button 2: increment
- * - button 2: set alarm
- * - button 1: cycle hr/min/on-off
- * - button 2: increment
- *
- * pin configuration outlined in comments below
- *
- * Adjustments:
- * - Fixed millis() rollover causing reset to 0:00. Now using
- * millisSinceMidnight and reset to 0 each day at midnight
- * - Fixed bug resulting in clock slowing down over time due
- * to modulus operation between call to millis() and subsequent
- * setting of prevMillis = millis()
- * - Optimised by changing % operations to branching operations
- * where possible
- * - fixed incremental speed change of hr/min etc
- *
- * Mark Ruff, Jan 2015
- */
- #include <LiquidCrystal.h>
- // GLOBALS
- // ARDUINO PINS
- const int button1 = 6; // push buttons
- const int button2 = 7;
- const int tempPin = A0; // temperature monitor
- const int alarmPin = 8; // piezo
- const int alarmLedPin = 13; // LED
- // LCD
- // moved pin 11->10 and 3->9 to avoid interference from tone()
- LiquidCrystal lcd(12,10,5,4,9,2);
- // Byte blocks for additional icons to display in lcd
- // loading in setup()
- byte alarmIcon[8] = {
- B00100,
- B01110,
- B01110,
- B01110,
- B11111,
- B00100,
- B00000,
- };
- byte heartIcon[8] = {
- B00000,
- B01010,
- B11111,
- B11111,
- B11111,
- B01110,
- B00100,
- };
- byte noteIcon[8] = {
- B00100,
- B00110,
- B00101,
- B00101,
- B00100,
- B11100,
- B11100,
- };
- // TIME SETTINGS
- // millisSinceMidnight, used to calculate the time, updated
- // using interval millis() - prevMillis each cycle
- unsigned long int millisSinceMidnight = 0;
- unsigned long int prevMillis = 0;
- int interval; // used to store millis() - prevMillis
- int hour24 = false; // 24 hour time
- // For setting the time
- // - 0 = not settingm time
- // - 1 = setting Hours
- // - 2 = setting Minutes
- // - 3 = setting am/pm
- int setTimeMode;
- int adjustedHour;
- int adjustedMinute;
- // For the flashing colon :
- int colonFrequency = 1000; // flash every 2 seconds
- int colonTimer = 0;
- bool colonOn = true;
- // For blinking digits during time / alarm set
- int blinkOnTime = 1000;
- int blinkOffTime = 333;
- int blinkTimer = 0;
- bool blinkOn = true;
- // for slowing increasing speed at which hrs/mins increment
- // based on how long button held
- int buttonPressedTimer = 0;
- int speed1Max = 1500; // 2 seconds
- int speed1Delay = 300;
- int speed2Max = 3000; //
- int speed2Delay = 150;
- int speed3Delay = 75;
- // ALARM SETTINGS
- bool alarmOn = false;
- int alarmHour = 0;
- int alarmMinute = 0;
- // For setting the alarm (mode similar to setTime Mode
- int setAlarmMode;
- // frequencies (notes) used by the alarm
- int notes[] = {261, 294, 329, 349, 392, 440, 493, 523};
- // TEMPERATURE SETTINGS
- // How often to update the temperature
- int tempFrequency = 10000;
- int tempTimer = 0;
- // BUTTON SETTINGS
- // Held button: current state HIGH and prev state HIGH
- // Pressed button: current state LOW and prev state HIGH
- // - Pressed is really released button
- // Pressed time is used to vary the speed when incrementing
- // the time or alarm
- int button1State = LOW;
- int button2State = LOW;
- int prevButton1State = LOW;
- int prevButton2State = LOW;
- bool button1Pressed = false;
- bool button1Held = false;
- bool button2Pressed = false;
- bool button2Held = false;
- int button1PressedTime = 0;
- int button2PressedTime = 0;
- void setup() {
- // pins
- pinMode(button1, INPUT);
- pinMode(button2, INPUT);
- pinMode(tempPin, INPUT);
- pinMode(alarmPin, OUTPUT);
- pinMode(alarmLedPin, OUTPUT);
- digitalWrite(alarmLedPin, LOW);
- // lcd
- lcd.begin(16,2 );
- // three characters (defined above)
- lcd.createChar(0, alarmIcon);
- lcd.createChar(1, heartIcon);
- lcd.createChar(2, noteIcon);
- // print the welcome message
- welcomeMessage();
- // write the temperature, because we don't do it every loop
- writeTemp();
- }
- void loop() {
- // Time keeping
- interval = millis() - prevMillis;
- prevMillis = millis();
- // capture button presses
- // HELD = while button depressed
- // PRESSED = after release (reading falling edge)
- button1State = digitalRead(button1);
- button2State = digitalRead(button2);
- if(button1State == HIGH && prevButton1State == HIGH ) {
- button1Held = true;
- button1Pressed = false;
- }
- else if (button1State == LOW && prevButton1State == HIGH ) {
- button1Pressed = true;
- button1Held = false;
- buttonPressedTimer = 0;
- }
- else {
- button1Pressed = false;
- button1Held = false;
- }
- if(button2State == HIGH && prevButton2State == HIGH ) {
- button2Held = true;
- button2Pressed = false;
- }
- else if (button2State == LOW && prevButton2State == HIGH ) {
- button2Pressed = true;
- button2Held = false;
- buttonPressedTimer = 0;
- }
- else {
- button2Pressed = false;
- button2Held = false;
- }
- prevButton1State = button1State;
- prevButton2State = button2State;
- // Setting the time?
- if (setTimeMode > 0) {
- setTime();
- }
- // Or setting the alarm?
- else if (setAlarmMode > 0 ) {
- setAlarm();
- }
- // Otherwise just display the time & temperature
- else {
- // Calculate hours / minutes / seconds since Arduino reset
- // Used to calcuate time
- int hours = (millisSinceMidnight/3600000)%24;
- int minutes = (millisSinceMidnight/60000)%60;
- int seconds = (millisSinceMidnight/1000)%60;
- // BUTTON 1 PRESS
- // Change the time
- if ( button1Pressed ) {
- setTimeMode = 1;
- adjustedHour = hours;
- adjustedMinute = minutes;
- }
- // BUTTON 2 PRESS
- if ( button2Pressed ) {
- setAlarmMode = 1;
- adjustedHour = alarmHour;
- adjustedMinute = alarmMinute;
- }
- // DISPLAY THE TIME
- displayTime(hours, minutes, seconds);
- // DISPLAY ALARM ICON (if on)
- if ( alarmOn ) {
- lcd.print(" ");
- lcd.write( byte(0) ); // this is our alarm icon
- }
- else {
- lcd.print(" ");
- }
- // DISPLAY THE TEMPERATURE
- // update the timer, check if threshold reached, if so
- // write the temperature
- tempTimer += interval;
- if (tempTimer > tempFrequency) {
- writeTemp();
- tempTimer = 0;
- }
- // Set off alarms if set on and time
- if ( alarmOn &&
- hours == alarmHour && minutes == alarmMinute ) {
- alarm();
- }
- }
- // Increment millisecond count from midnight
- // rollover if we've reached midnight
- millisSinceMidnight += interval;
- millisSinceMidnight = millisSinceMidnight % 86400000;
- }
- // Displays the time
- void displayTime(int hours, int minutes, int seconds) {
- // is it morning
- bool am = hours < 12;
- // HOURS
- lcd.setCursor(0,0);
- // first handle 24 hour time
- if( hour24 ) {
- if ( hours < 10 ) {
- lcd.print(" ");
- }
- lcd.print(hours);
- }
- // otherwise am/pm
- else {
- hours = am ? hours : hours - 12;
- if ( hours == 0 ) {
- lcd.print("12");
- }
- else if ( hours < 10 ) {
- lcd.print( " " );
- lcd.print(hours);
- }
- else {
- lcd.print(hours);
- }
- }
- // FlASHING COLON
- colonTimer += interval;
- if ( colonTimer > colonFrequency ) {
- colonTimer = 0;
- colonOn = !colonOn;
- }
- if (colonOn) {
- lcd.print(":");
- }
- else {
- lcd.print(" ");
- }
- // MINUTES
- if ( minutes < 10 ) {
- lcd.print("0");
- }
- lcd.print(minutes);
- // AM/PM
- if ( !hour24 ) {
- if ( am ) {
- lcd.print("am");
- }
- else {
- lcd.print("pm");
- }
- }
- else {
- lcd.print (" ");
- }
- }
- // Print a welcome message
- // Two lines, top line first, bottom line scrolling in with top
- // line scrolling out.
- void welcomeMessage() {
- char topMessage[] = " Ruffian Clock";
- // bottom message split so I can put a heart in
- char bottomMessageLeft[] = "I ";
- char bottomMessageRight[] = " Arduino! ";
- // Write top welcome message
- lcd.setCursor(0,0);
- lcd.print(topMessage);
- delay(1000);
- // Write bottom welcome message
- lcd.setCursor(16,1);
- lcd.autoscroll();
- for ( int i = 0 ; bottomMessageLeft[i] != '\0' ; i++ ) {
- lcd.print(bottomMessageLeft[i]);
- delay(500);
- }
- // print the heart
- lcd.write(byte(1));
- delay(500);
- for ( int i = 0 ; bottomMessageRight[i] != '\0' ; i++ ) {
- lcd.print(bottomMessageRight[i]);
- delay(500);
- }
- delay(1000);
- lcd.noAutoscroll();
- lcd.clear();
- }
- void setTime() {
- bool am = adjustedHour < 12;
- // work out whether flashing digit is on or off
- blinkTimer += interval;
- if (blinkOn) {
- if (blinkTimer > blinkOnTime) {
- blinkOn = false;
- blinkTimer = 0;
- }
- }
- else {
- if (blinkTimer > blinkOffTime) {
- blinkOn = true;
- blinkTimer = 0;
- }
- }
- // display the clock
- // flash the digits (HH or MM) being changed
- // display the time
- lcd.setCursor(0,0);
- if( !blinkOn && setTimeMode == 1 && !button2Held && ! button2Pressed) {
- lcd.print("__"); // flash when setting
- }
- else {
- if (hour24) {
- if ( adjustedHour < 10 ) {
- lcd.print(" ");
- }
- lcd.print(adjustedHour);
- }
- else {
- if (!am) {
- if ( adjustedHour == 12 ) {
- lcd.print("12");
- }
- else {
- if ( adjustedHour -12 < 10 ) {
- lcd.print(" ");
- }
- lcd.print(adjustedHour - 12);
- }
- }
- else {
- if ( adjustedHour == 0 ) {
- lcd.print("12");
- }
- else {
- if ( adjustedHour < 10 ) {
- lcd.print(" ");
- }
- lcd.print(adjustedHour);
- }
- }
- }
- }
- lcd.print(":");
- if( !blinkOn && setTimeMode == 2 && !button2Held ) {
- lcd.print("__"); // flash when setting
- }
- else {
- if (adjustedMinute < 10 ) {
- lcd.print("0");
- }
- lcd.print(adjustedMinute);
- }
- // am/pm
- if( !blinkOn && setTimeMode == 3 && !button2Held ) {
- lcd.print("__"); // flash when setting
- }
- else {
- if ( hour24 ) {
- lcd.print(" ");
- }
- else {
- if ( am ) {
- lcd.print("am");
- }
- else {
- lcd.print("pm");
- }
- }
- }
- // Button 2 Pressed
- // this increments the hours/minutes
- if ( button2Held ) {
- blinkOn = true;
- blinkTimer = 0;
- buttonPressedTimer += interval;
- if (buttonPressedTimer < speed1Max) {
- delay(speed1Delay);
- }
- else if (buttonPressedTimer < speed2Max) {
- delay(speed2Delay);
- }
- else {
- delay(speed3Delay);
- }
- if (setTimeMode == 1) {
- adjustedHour = adjustedHour + 1;
- if (adjustedHour == 24) adjustedHour = 0;
- }
- else if (setTimeMode == 2 ){
- adjustedMinute = adjustedMinute + 1;
- if (adjustedMinute == 60) adjustedMinute = 0;
- }
- }
- if ( button2Pressed && setTimeMode == 3 ) {
- blinkOn = true;
- blinkTimer = 0;
- hour24 = !hour24;
- }
- // Button 1 Pressed
- // This cycles through Hours / Minutes / Finished
- if ( button1Pressed ) {
- blinkOn = false;
- blinkTimer = 0;
- setTimeMode = setTimeMode +1;
- if (setTimeMode == 4) {
- setTimeMode = 0;
- millisSinceMidnight =
- adjustedHour * 3600000 + adjustedMinute * 60000;
- lcd.clear();
- writeTemp();
- }
- }
- }
- void setAlarm() {
- bool am = adjustedHour < 12;
- // work out whether flashing digit is on or off
- blinkTimer += interval;
- if (blinkOn) {
- if (blinkTimer > blinkOnTime) {
- blinkOn = false;
- blinkTimer = 0;
- }
- }
- else {
- if (blinkTimer > blinkOffTime) {
- blinkOn = true;
- blinkTimer = 0;
- }
- }
- // display the clock
- // flash the digits (HH or MM) being changed
- // display the time
- lcd.setCursor(0,0);
- if( !blinkOn && setAlarmMode == 1 && !button2Held && ! button2Pressed) {
- lcd.print("__"); // flash when setting
- }
- else {
- if (hour24) {
- if ( adjustedHour < 10 ) {
- lcd.print(" ");
- }
- lcd.print(adjustedHour);
- }
- else {
- if (!am) {
- if ( adjustedHour == 12 ) {
- lcd.print("12");
- }
- else {
- if ( adjustedHour -12 < 10 ) {
- lcd.print(" ");
- }
- lcd.print(adjustedHour - 12);
- }
- }
- else {
- if ( adjustedHour == 0 ) {
- lcd.print("12");
- }
- else {
- if ( adjustedHour < 10 ) {
- lcd.print(" ");
- }
- lcd.print(adjustedHour);
- }
- }
- }
- }
- lcd.print(":");
- if( !blinkOn && setAlarmMode == 2 && !button2Held ) {
- lcd.print("__"); // flash when setting
- }
- else {
- if (adjustedMinute < 10 ) {
- lcd.print("0");
- }
- lcd.print(adjustedMinute);
- }
- // am/pm - not changing here
- if ( hour24 ) {
- lcd.print(" ");
- }
- else {
- if ( am ) {
- lcd.print("am");
- }
- else {
- lcd.print("pm");
- }
- }
- if( !blinkOn && setAlarmMode == 3 && !button2Held ) {
- lcd.print(" ___"); // flash when setting
- }
- else {
- if ( alarmOn ) {
- lcd.print(" on ");
- }
- else {
- lcd.print(" off");
- }
- }
- // Button 2 Pressed
- // this increments the hours/minutes
- if ( button2Held ) {
- blinkOn = true;
- blinkTimer = 0;
- buttonPressedTimer += interval;
- if (buttonPressedTimer < speed1Max) {
- delay(speed1Delay);
- }
- else if (buttonPressedTimer < speed2Max) {
- delay(speed2Delay);
- }
- else {
- delay(speed3Delay);
- }
- if (setAlarmMode == 1) {
- adjustedHour = adjustedHour + 1;
- if (adjustedHour == 24) adjustedHour = 0;
- }
- else if (setAlarmMode == 2 ){
- adjustedMinute = adjustedMinute + 1;
- if ( adjustedMinute == 60 ) adjustedMinute = 0;
- }
- }
- if ( button2Pressed && setAlarmMode == 3 ) {
- blinkOn = true;
- blinkTimer = 0;
- alarmOn = !alarmOn;
- }
- // Button 1 Pressed
- // This cycles through Hours / Minutes / Finished
- if ( button1Pressed ) {
- blinkOn = false;
- blinkTimer = 0;
- setAlarmMode = setAlarmMode + 1;
- if (setAlarmMode == 4) {
- setAlarmMode = 0;
- alarmHour = adjustedHour;
- alarmMinute = adjustedMinute;
- lcd.clear();
- writeTemp();
- }
- }
- }
- // Set off the alarm, combination of:
- // - tone
- // - LED flashing
- // - note icon on LCD
- void alarm() {
- // draw the note icon on the LCD
- lcd.setCursor(9,0);
- lcd.write(byte(2));
- // play the little tune (uses frequencies in notes[])
- // flash the LED at the same time
- for ( int i = 0 ; i < 4 ; i++ ) {
- tone(alarmPin,notes[i],200);
- digitalWrite(alarmLedPin,LOW);
- delay(200);
- tone(alarmPin,notes[i+2],200);
- digitalWrite(alarmLedPin,HIGH);
- delay(200);
- }
- tone(alarmPin,notes[6],600);
- for (int i = 0 ; i < 6 ; i++ ) {
- digitalWrite(alarmLedPin,LOW);
- delay(50);
- digitalWrite(alarmLedPin,HIGH);
- delay(50);
- }
- for(int i = 3 ; i >= 0 ; i-- ) {
- tone(alarmPin,notes[i],200);
- lcd.setCursor(9,0);
- lcd.write(byte(2));
- delay(100);
- // flash the note icon a little
- lcd.setCursor(9,0);
- lcd.write(" ");
- delay(100);
- }
- // turn off alarm, clear LCD, turn off LED
- alarmOn = false;
- digitalWrite(alarmLedPin,LOW);
- lcd.clear();
- // write the temp (because there might be a delay)
- writeTemp();
- }
- // write the temperature on the bottom line of the LCD
- void writeTemp() {
- // get the sensor value
- int tempSensorVal = analogRead(tempPin);
- // convert the sensor reading to voltage
- float voltage = (tempSensorVal/1024.0) * 5.0;
- // convert voltage to temperature
- float temperature = (voltage - 0.5) * 100;
- lcd.setCursor(0,1);
- lcd.print(temperature);
- lcd.setCursor(4,1);
- lcd.print((char)223); // degrees symbol
- lcd.print("C");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement