Advertisement
markruff

Arduino alarm clock with temperature

Jan 18th, 2016
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.38 KB | None | 0 0
  1.  /*
  2.  * LCD Alarm Clock with Temperature
  3.  *
  4.  * Arduino powered alarm clock that shows the time and temperature
  5.  * Alarm can be set. Alarm creates tone at piezo and flashes LED
  6.  *
  7.  * Settings controlled with two buttons:
  8.  *  - button 1: set time
  9.  *     - button 1: cycle hr/min/24hr
  10.  *     - button 2: increment
  11.  *  - button 2: set alarm
  12.  *     - button 1: cycle hr/min/on-off
  13.  *     - button 2: increment
  14.  *    
  15.  * pin configuration outlined in comments below
  16.  *
  17.  * To do: adjust to handle millis() rollover
  18.  *  ... I've got about 50 days
  19.  *  
  20.  * Mark Ruff, Jan 2015
  21.  */
  22.  
  23. #include <LiquidCrystal.h>
  24.  
  25. // GLOBALS
  26.  
  27. // ARDUINO PINS
  28. const int button1 = 6; // push buttons
  29. const int button2 = 7;
  30. const int tempPin = A0; // temperature monitor
  31. const int alarmPin = 8; // piezo
  32. const int alarmLedPin = 13; // LED
  33.  
  34. // LCD
  35. // moved pin 11->10 and 3->9 to avoid interference from tone()
  36. LiquidCrystal lcd(12,10,5,4,9,2);
  37.  
  38. // Byte blocks for additional icons to display in lcd
  39. // loading in setup()
  40. byte alarmIcon[8] = {
  41.   B00100,
  42.   B01110,
  43.   B01110,
  44.   B01110,
  45.   B11111,
  46.   B00100,
  47.   B00000,
  48. };
  49.  
  50. byte heartIcon[8] = {
  51.   B00000,
  52.   B01010,
  53.   B11111,
  54.   B11111,
  55.   B11111,
  56.   B01110,
  57.   B00100,
  58. };
  59.  
  60. byte noteIcon[8] = {
  61.   B00100,
  62.   B00110,
  63.   B00101,
  64.   B00101,
  65.   B00100,
  66.   B11100,
  67.   B11100,
  68. };
  69.  
  70. // TIME SETTINGS
  71. // Set time - adjustment relative to millis()
  72. unsigned long int setMillis = 0; // (60 * hours + minutes)*60000
  73. int hour24 = false;  // 24 hour time
  74.  
  75. // For setting the time
  76. // - 0 = not settingm time
  77. // - 1 = setting Hours
  78. // - 2 = setting Minutes
  79. // - 3 = setting am/pm
  80. int setTimeMode;
  81. int adjustedHour;
  82. int adjustedMinute;
  83.  
  84. // ALARM SETTINGS
  85. bool alarmOn = false;
  86. int alarmHour = 0;
  87. int alarmMinute = 0;
  88.  
  89. // For setting the alarm (mode similar to setTime Mode
  90. int setAlarmMode;
  91.  
  92. // frequencies (notes) used by the alarm
  93. int notes[] = {261, 294, 329, 349, 392, 440, 493, 523};
  94.  
  95. // BUTTON SETTINGS
  96. // Held button: current state HIGH and prev state HIGH
  97. // Pressed button: current state LOW and prev state HIGH
  98. //  - Pressed is really released button
  99. // Pressed time is used to vary the speed when incrementing
  100. // the time or alarm
  101. int button1State = LOW;
  102. int button2State = LOW;
  103. int prevButton1State = LOW;
  104. int prevButton2State = LOW;
  105. bool button1Pressed = false;
  106. bool button1Held = false;
  107. bool button2Pressed = false;
  108. bool button2Held = false;
  109. int button1PressedTime = 0;
  110. int button2PressedTime = 0;
  111.  
  112. void setup() {
  113.  
  114.   // pins
  115.   pinMode(button1, INPUT);
  116.   pinMode(button2, INPUT);
  117.   pinMode(tempPin, INPUT);
  118.   pinMode(alarmPin, OUTPUT);
  119.   pinMode(alarmLedPin, OUTPUT);
  120.   digitalWrite(alarmLedPin, LOW);
  121.  
  122.   // lcd
  123.   lcd.begin(16,2 );
  124.  
  125.   // three characters (defined above)
  126.   lcd.createChar(0, alarmIcon);
  127.   lcd.createChar(1, heartIcon);
  128.   lcd.createChar(2, noteIcon);
  129.  
  130.   // print the welcome message
  131.   welcomeMessage();
  132.    
  133.   // write the temperature, because we don't do it every loop
  134.   writeTemp();
  135. }
  136.  
  137. void loop() {
  138.  
  139.   // capture button presses
  140.   // HELD = while button depressed
  141.   // PRESSED = after release (reading falling edge)
  142.   button1State = digitalRead(button1);
  143.   button2State = digitalRead(button2);
  144.   if(button1State == HIGH && prevButton1State == HIGH ) {
  145.     button1Held = true;
  146.     button1Pressed = false;
  147.     if (button1PressedTime == 0) {
  148.       button1PressedTime = millis();
  149.     }
  150.   }
  151.   else if (button1State == LOW && prevButton1State == HIGH ) {
  152.     button1Pressed = true;
  153.     button1Held = false;
  154.     button1PressedTime = 0;
  155.   }
  156.   else {
  157.     button1Pressed = false;
  158.     button1Held = false;
  159.   }
  160.  
  161.   if(button2State == HIGH && prevButton2State == HIGH ) {
  162.     button2Held = true;
  163.     button2Pressed = false;
  164.     if ( button2PressedTime == 0 ) {
  165.       button2PressedTime = millis();
  166.     }
  167.   }
  168.   else if (button2State == LOW && prevButton2State == HIGH ) {
  169.     button2Pressed = true;
  170.     button2Held = false;
  171.     button2PressedTime = 0;
  172.   }
  173.   else {
  174.     button2Pressed = false;
  175.     button2Held = false;
  176.   }
  177.   prevButton1State = button1State;
  178.   prevButton2State = button2State;
  179.  
  180.   // Setting the time?
  181.   if (setTimeMode > 0) {
  182.     setTime();
  183.   }
  184.   // Or setting the alarm?
  185.   else if (setAlarmMode > 0 ) {
  186.     setAlarm();
  187.   }
  188.   // Otherwise just display the time & temperature
  189.   else {
  190.     int hours = getHour();
  191.     int minutes = getMinute();
  192.     int seconds =  getSeconds();
  193.          
  194.     // BUTTON 1 PRESS
  195.     // Change the time
  196.     if ( button1Pressed ) {
  197.       setTimeMode = 1;
  198.       adjustedHour = hours;
  199.       adjustedMinute = minutes;
  200.     }
  201.  
  202.     // BUTTON 2 PRESS
  203.     if ( button2Pressed ) {
  204.       setAlarmMode = 1;
  205.       adjustedHour = alarmHour;
  206.       adjustedMinute = alarmMinute;
  207.     }
  208.  
  209.     // DISPLAY THE TIME
  210.     displayTime(hours, minutes, seconds);    
  211.  
  212.     // DISPLAY ALARM ICON (if on)
  213.     if ( alarmOn ) {
  214.       lcd.print(" ");
  215.       lcd.write( byte(0) ); // this is our alarm icon
  216.     }
  217.     else {
  218.       lcd.print("  ");    
  219.     }
  220.    
  221.     // DISPLAY THE TEMPERATURE
  222.     // only refresh every 10s
  223.     if ( millis() % 10000 < 200 ) {
  224.       writeTemp();
  225.     }
  226.  
  227.     // Set off alarms if set on and time
  228.     if ( alarmOn &&
  229.          hours == alarmHour && minutes == alarmMinute ) {
  230.       alarm();
  231.     }
  232.   }
  233. }
  234.  
  235. // Calculate hours / minutes / seconds since Arduino reset
  236. // Used to calcuate time
  237. int getHour() {
  238.   return ((millis()+setMillis)/3600000)%24;
  239. }
  240.  
  241. int getMinute() {
  242.   return ((millis()+setMillis)/60000)%60;
  243.  
  244. }
  245.  
  246. int getSeconds() {
  247.   return (millis()/1000)%60;
  248. }
  249.  
  250. // Displays the time
  251. void displayTime(int hours, int minutes, int seconds) {
  252.  
  253.   // is it morning
  254.   bool am = hours < 12;
  255.  
  256.   // HOURS
  257.   lcd.setCursor(0,0);
  258.  
  259.   // first handle 24 hour time
  260.   if( hour24 ) {
  261.     if ( hours < 10 ) {
  262.       lcd.print(" ");
  263.     }
  264.     lcd.print(hours);
  265.   }
  266.   // otherwise am/pm
  267.   else {
  268.     hours = am ? hours : hours - 12;
  269.     if ( hours == 0 ) {
  270.       lcd.print("12");
  271.     }
  272.     else if ( hours < 10 ) {
  273.       lcd.print( " " );
  274.       lcd.print(hours);
  275.     }
  276.     else {
  277.       lcd.print(hours);
  278.     }
  279.   }
  280.  
  281.   // FlASHING COLON
  282.   if ( seconds % 2 == 0 ) {
  283.     lcd.print(":");
  284.   }
  285.   else {
  286.     lcd.print(" ");
  287.   }
  288.  
  289.   // MINUTES
  290.   if ( minutes < 10 ) {
  291.     lcd.print("0");
  292.   }
  293.   lcd.print(minutes);
  294.  
  295.   // AM/PM
  296.   if ( !hour24 ) {
  297.     if ( am ) {
  298.       lcd.print("am");
  299.     }
  300.     else {
  301.       lcd.print("pm");
  302.     }
  303.   }
  304.   else {
  305.     lcd.print ("  ");
  306.   }
  307. }
  308.  
  309. // Print a welcome message
  310. // Two lines, top line first, bottom line scrolling in with top
  311. // line scrolling out.
  312. void welcomeMessage() {
  313.   char topMessage[] = " Ruffian Clock";
  314.  
  315.   // bottom message split so I can put a heart in
  316.   char bottomMessageLeft[] = "I ";
  317.   char bottomMessageRight[] = " Arduino!";
  318.  
  319.   // Write top welcome message
  320.   lcd.setCursor(0,0);
  321.   lcd.print(topMessage);
  322.   delay(2500);
  323.  
  324.   // Write bottom welcome message
  325.   lcd.setCursor(16,1);
  326.   lcd.autoscroll();
  327.  
  328.   for ( int i = 0 ; bottomMessageLeft[i] != '\0' ; i++ ) {
  329.     lcd.print(bottomMessageLeft[i]);
  330.     delay(500);    
  331.   }
  332.  
  333.   // print the heart
  334.   lcd.write(byte(1));
  335.   delay(500);
  336.  
  337.   for ( int i = 0 ; bottomMessageRight[i] != '\0' ; i++ ) {
  338.     lcd.print(bottomMessageRight[i]);
  339.     delay(500);    
  340.   }
  341.  
  342.   lcd.noAutoscroll();
  343.   lcd.clear();
  344. }
  345.  
  346. void setTime() {
  347.  
  348.   bool am = adjustedHour < 12;
  349.  
  350.   bool flash = (millis() % 1500 ) < 250;
  351.  
  352.   // display the clock
  353.   // flash the digits (HH or MM) being changed
  354.   // display the time
  355.   lcd.setCursor(0,0);
  356.   if( flash && setTimeMode == 1 && !button2Held && ! button2Pressed) {
  357.     lcd.print((char)95);
  358.     lcd.print((char)95); // flash when setting
  359.   }
  360.   else {
  361.     if (hour24) {
  362.       if ( adjustedHour < 10 ) {
  363.         lcd.print(" ");
  364.       }
  365.       lcd.print(adjustedHour);
  366.     }
  367.     else {
  368.       if (!am) {
  369.         if ( adjustedHour == 12 ) {
  370.           lcd.print("12");
  371.         }
  372.         else {
  373.           if ( adjustedHour -12 < 10 ) {
  374.             lcd.print(" ");
  375.           }      
  376.           lcd.print(adjustedHour - 12);
  377.         }
  378.       }
  379.       else {
  380.         if ( adjustedHour == 0 ) {
  381.           lcd.print("12");
  382.         }
  383.         else {
  384.           if ( adjustedHour < 10 ) {
  385.             lcd.print(" ");
  386.           }
  387.           lcd.print(adjustedHour);        
  388.         }
  389.       }
  390.     }
  391.   }
  392.   lcd.print(":");
  393.   if( flash && setTimeMode == 2 && !button2Held ) {
  394.     lcd.print((char)95);
  395.     lcd.print((char)95); // flash when setting
  396.   }
  397.   else {
  398.     if (adjustedMinute < 10 ) {
  399.       lcd.print("0");
  400.     }
  401.     lcd.print(adjustedMinute);
  402.   }
  403.  
  404.   // am/pm - don't flash
  405.   if( flash && setTimeMode == 3 && !button2Held ) {
  406.     lcd.print((char)95);
  407.     lcd.print((char)95); // flash when setting
  408.   }
  409.   else {
  410.  
  411.     if ( hour24 ) {
  412.       lcd.print("  ");
  413.     }
  414.     else {
  415.       if ( am ) {
  416.         lcd.print("am");
  417.       }
  418.       else {
  419.         lcd.print("pm");
  420.       }
  421.     }  
  422.   }
  423.  
  424.   // Button 2 Pressed
  425.   // this increments the hours/minutes
  426.   if ( button2Held ) {
  427.     int delayFactor = millis() - button2PressedTime;
  428.     if ( delayFactor < 2000 ) {
  429.       delay(200);
  430.     }
  431.     if (delayFactor < 4000) {
  432.       delay(100);
  433.     }
  434.     delay(50);
  435.     if (setTimeMode == 1) {
  436.       adjustedHour = ( adjustedHour + 1 ) % 24;
  437.     }
  438.  
  439.     else if (setTimeMode == 2 ){
  440.       adjustedMinute = ( adjustedMinute + 1 ) % 60;
  441.     }
  442.   }
  443.   if ( button2Pressed && setTimeMode == 3 ) {
  444.       hour24 = !hour24;
  445.   }
  446.  
  447.   // Button 1 Pressed
  448.   // This cycles through Hours / Minutes / Finished
  449.   if ( button1Pressed ) {
  450.     setTimeMode = (setTimeMode +1 ) % 4;
  451.     if (setTimeMode == 0) {
  452.       setMillis = (((adjustedHour * 60 + adjustedMinute )
  453.                 * 60000) - millis()) % 86400000;
  454.       lcd.clear();
  455.       writeTemp();
  456.     }
  457.   }
  458. }
  459.  
  460. void setAlarm() {
  461.  
  462.   bool am = adjustedHour < 12;
  463.  
  464.   bool flash = (millis() % 1500 ) < 300;
  465.  
  466.   // display the clock
  467.   // flash the digits (HH or MM) being changed
  468.   // display the time
  469.   lcd.setCursor(0,0);
  470.   if( flash && setAlarmMode == 1 && !button2Held && ! button2Pressed) {
  471.     lcd.print((char)95);
  472.     lcd.print((char)95); // flash when setting
  473.   }
  474.   else {
  475.     if (hour24) {
  476.       if ( adjustedHour < 10 ) {
  477.         lcd.print(" ");
  478.       }
  479.       lcd.print(adjustedHour);
  480.     }
  481.     else {
  482.       if (!am) {
  483.         if ( adjustedHour == 12 ) {
  484.           lcd.print("12");
  485.         }
  486.         else {
  487.           if ( adjustedHour -12 < 10 ) {
  488.             lcd.print(" ");
  489.           }      
  490.           lcd.print(adjustedHour - 12);
  491.         }
  492.       }
  493.       else {
  494.         if ( adjustedHour == 0 ) {
  495.           lcd.print("12");
  496.         }
  497.         else {
  498.           if ( adjustedHour < 10 ) {
  499.             lcd.print(" ");
  500.           }
  501.           lcd.print(adjustedHour);        
  502.         }
  503.       }
  504.     }
  505.   }
  506.   lcd.print(":");
  507.   if( flash && setAlarmMode == 2 && !button2Held ) {
  508.     lcd.print((char)95);
  509.     lcd.print((char)95); // flash when setting
  510.   }
  511.   else {
  512.     if (adjustedMinute < 10 ) {
  513.       lcd.print("0");
  514.     }
  515.     lcd.print(adjustedMinute);
  516.   }
  517.  
  518.   // am/pm - not changing here
  519.   if ( hour24 ) {
  520.     lcd.print("  ");
  521.   }
  522.   else {
  523.     if ( am ) {
  524.       lcd.print("am");
  525.     }
  526.     else {
  527.       lcd.print("pm");
  528.     }
  529.   }  
  530.  
  531.   if( flash && setAlarmMode == 3 && !button2Held ) {
  532.     lcd.print(" ");
  533.     lcd.print((char)95);
  534.     lcd.print((char)95);
  535.     lcd.print((char)95); // flash when setting
  536.   }
  537.   else {
  538.     if ( alarmOn ) {
  539.       lcd.print(" on ");
  540.     }
  541.     else {
  542.       lcd.print(" off");
  543.     }
  544.   }
  545.    
  546.   // Button 2 Pressed
  547.   // this increments the hours/minutes
  548.   if ( button2Held ) {
  549.     int delayFactor = millis() - button2PressedTime;
  550.     if ( delayFactor < 2000 ) {
  551.       delay(200);
  552.     }
  553.     if (delayFactor < 4000) {
  554.       delay(100);
  555.     }
  556.     delay(50);
  557.    
  558.     if (setTimeMode == 1) {
  559.       adjustedHour = ( adjustedHour + 1 ) % 24;
  560.     }
  561.  
  562.     if (setAlarmMode == 1) {
  563.       adjustedHour = ( adjustedHour + 1 ) % 24;
  564.     }
  565.  
  566.     else if (setAlarmMode == 2 ){
  567.       adjustedMinute = ( adjustedMinute + 1 ) % 60;
  568.     }
  569.   }
  570.   if ( button2Pressed && setAlarmMode == 3 ) {
  571.       alarmOn = !alarmOn;
  572.   }
  573.  
  574.   // Button 1 Pressed
  575.   // This cycles through Hours / Minutes / Finished
  576.   if ( button1Pressed ) {
  577.     setAlarmMode = (setAlarmMode +1 ) % 4;
  578.     if (setAlarmMode == 0) {
  579.       alarmHour = adjustedHour;
  580.       alarmMinute = adjustedMinute;
  581.       lcd.clear();
  582.       writeTemp();
  583.     }
  584.   }
  585.   delay(100);
  586. }
  587.  
  588. // Set off the alarm, combination of:
  589. //  - tone
  590. //  - LED flashing
  591. //  - note icon on LCD
  592. void alarm() {
  593.  
  594.   // draw the note icon on the LCD
  595.   lcd.setCursor(9,0);
  596.   lcd.write(byte(2));
  597.  
  598.   // play the little tune (uses frequencies in notes[])
  599.   // flash the LED at the same time
  600.   for ( int i = 0 ; i < 4 ; i++ ) {
  601.     tone(alarmPin,notes[i],200);
  602.     digitalWrite(alarmLedPin,LOW);
  603.     delay(200);
  604.     tone(alarmPin,notes[i+2],200);
  605.     digitalWrite(alarmLedPin,HIGH);
  606.     delay(200);    
  607.   }
  608.   tone(alarmPin,notes[6],600);
  609.   for (int i = 0 ; i < 6 ; i++ ) {
  610.     digitalWrite(alarmLedPin,LOW);
  611.     delay(50);
  612.     digitalWrite(alarmLedPin,HIGH);
  613.     delay(50);        
  614.   }
  615.   for(int i = 3 ; i >= 0 ; i-- ) {
  616.     tone(alarmPin,notes[i],200);
  617.     lcd.setCursor(9,0);
  618.     lcd.write(byte(2));
  619.     delay(100);  
  620.  
  621.     // flash the note icon a little
  622.     lcd.setCursor(9,0);
  623.     lcd.write(" ");
  624.     delay(100);  
  625.   }
  626.  
  627.   // turn off alarm, clear LCD, turn off LED
  628.   alarmOn = false;
  629.   digitalWrite(alarmLedPin,LOW);
  630.   lcd.clear();
  631.  
  632.   // write the temp (because there might be a delay)
  633.   writeTemp();
  634. }
  635.  
  636. // write the temperature on the bottom line of the LCD
  637. void writeTemp() {
  638.   // get the sensor value
  639.   int tempSensorVal = analogRead(tempPin);
  640.  
  641.   // convert the sensor reading to voltage
  642.   float voltage = (tempSensorVal/1024.0) * 5.0;
  643.  
  644.   // convert voltage to temperature
  645.   float temperature = (voltage - 0.5) * 100;
  646.  
  647.   lcd.setCursor(0,1);
  648.   lcd.print(temperature);
  649.   lcd.setCursor(4,1);
  650.   lcd.print((char)223); // degrees symbol
  651.   lcd.print("C");
  652. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement