Advertisement
markruff

Arduino alarm clock with temperature - fixed

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