Advertisement
markruff

Arduino alarm clock and temp - final

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