Advertisement
goebish

Arduino Alarm Clock with TSA1605A micro leds display

Jun 17th, 2013
572
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.93 KB | None | 0 0
  1. // Arduino code for Alarm Clock with TSA1605A 8x14 segments micro leds display
  2. // Goebish 2013 (twitter: @goebish)
  3. //
  4. // This code is  distributed  in the hope that it  will be useful for everyone  but it  is distributed
  5. // without any warranty.  It is provided  "as is" without  warranty of  any kind, either  expressed or
  6. // implied, including, but not limited to, the implied warranties of merchantability and fitness for a
  7. // particular purpose.  The entire risk  as to the  quality and  performance of the  code is with you.
  8. // Should  the code  prove  defective,  you assume  the cost of  all necessary  servicing,  repair  or
  9. // correction.  In no  event will  the author of the  code be liable  to you  for  damages,  including
  10. // any general,  special,  incidental or  consequential  damages arising  out of  the use of the code,
  11. // including  but  not limited to  loss  of life,  money,  the loss  of data or  data  being  rendered
  12. // inaccurate, or  any other losses  sustained by  you or  third parties  or a failure of  the code to
  13. // operate with any other  device(s), even if the author  has been advised of the  possibility of such
  14. // possibilities.
  15. //
  16. // pictures:
  17. // http://imgur.com/10iBfZd
  18. // http://imgur.com/CL1NXCh
  19. //
  20. // parts:
  21. // - atmega168 or atmega328 Arduino or compatible dev board (2009, UNO, nano, mini ...) this has not been tested with the Leonardo and shouldn't work on the MEGA
  22. // - DS1307 RTC + 32.768kHz chrystal + 3V coin battery cell (CR2032) or DS1307 breakout module
  23. // - TSA1605A 8x14 segments micro LEDs display
  24. // - 14x 68 ohms resistors (one for each segments anode, they don't appear in my pictures, but you should really use them ;))
  25. // - 3x 74HC595 shift registers
  26. // - 3x momentary pushbuttons (MODE/SET, PLUS, MINUS) + 3x 0.1µF capacitors
  27. // - 10k ohms resistor (HC595s OE pullup)
  28. // - piezzo buzzer + 100 ohms resistor
  29. // - led + 8k ohms resistor (alarm enabled indicator)
  30. //
  31. // schematics:
  32. // http://imgur.com/2fvOBml
  33. //
  34. // read through the code for usage description :)
  35.  
  36. #include <Wire.h> // I2C for DS1307 RTC
  37. #include <EEPROM.h> // eeprom used to store alarm settings
  38. #include <TimerOne.h>  // get it from http://code.google.com/p/arduino-timerone/
  39. #define NO_PORTC_PINCHANGES
  40. #define NO_PORTD_PINCHANGES
  41. #include <PinChangeInt.h>  // get it from http://code.google.com/p/arduino-pinchangeint/
  42.  
  43. #if (ARDUINO >= 100)
  44.   #define WireWrite Wire.write
  45.   #define WireRead Wire.read()
  46. #else
  47.   #define WireWrite Wire.send
  48.   #define WireRead Wire.receive()
  49. #endif
  50.  
  51. // One side of the pushbuttons is connected to ground. The other sides connect to the Arduino pins.
  52. // Put a 0.1µF cap between pushbuttons legs to provide hard debouncing
  53. const int setButton = 9;
  54. const int minusButton=10;
  55. const int plusButton =11;
  56.  
  57. const int buzzer=2; // buzzer w/ 100ohms resistor
  58. const int alarmLed=13; // led + 8k ohms resistor, use an high enough resistor value so the led isn't brighter than the display
  59.  
  60. // HC595s wiring:
  61. // HC595-1, 2 & 3 pin 8 to GND
  62. // HC595-1, 2 & 3 pin 10 to +5V
  63. // HC595-1, 2 & 3 pin 16 to +5V
  64. // HC595-1 QA to QH outputs --> TSA1605A cathodes 1 to 8 (pins 1, 22, 3, 19, 8, 15, 11, 12)
  65. // HC595-2 QA to QH outputs --> TSA1605A G to N segments (pins 6, 13, 20, 18, 17, 2, 7, 10)
  66. // HC595-3 QA to QF outputs --> TSA1605A A to F segments (pins 14, 16, 5, 4, 9, 21)
  67. // place one 68 ohms resistor between each display segment anodes and it's HC959 output.
  68. // do not modify the following pins assignments ! (direct port access in ISR, no digitalWrite)
  69. const int dataPin1  = 5; // to HC595-1 (pin 14) cathodes driver
  70. const int dataPin2  = 4; // to HC595-2 (pin 14) segments GHIJKLMN anodes driver
  71. const int dataPin3  = 6; // to HC595-3 (pin 14) segments ABCDEF anodes driver
  72. const int latchPin  = 7; // to HC595-1, 2 & 3 (pin 12)
  73. const int clockPin  = 8; // to HC595-1, 2 & 3 (pin 11)
  74. const int oePin = 3; // to HC595-1, 2 & 3 (pin 13) + 10k pull up resistor to +5V
  75.  
  76. #define DISPLAY_ISR_PERIOD 500 // 1/DISPLAY_ISR_PERIOD/1000 = display frequency, lower value produce brighter display. Don't go to low or the main loop won't have enough (if any) CPU cycles for itself.
  77. //#define DISPLAY_ISR_PERIOD 2000 // for use without resistors on display anodes, USE AT YOUR OWN RISK !
  78.  
  79.  
  80. // DS1307 Real Time Clock
  81. // SDA (pin 5) to Arduino A4
  82. // SCL (pin 6) to Arduino A5
  83. #define DS1307_ADDRESS 0x68
  84. typedef struct {
  85.   byte second;
  86.   byte minute;
  87.   byte hour;
  88.   byte weekDay;
  89.   byte monthDay;
  90.   byte month;
  91.   int year;
  92. }
  93. s_dateTime;
  94. volatile s_dateTime curDateTime;
  95.  
  96. typedef struct {
  97.   byte enabled;
  98.   byte hour;
  99.   byte minute;
  100. } s_alarmSettings;
  101. volatile s_alarmSettings alarm = {false,0,0};
  102.  
  103. // states
  104. typedef enum e_states{
  105.   CLOCK,
  106.   DATE,     // return to CLOCK if SET button is not pushed for 5 seconds
  107.   SET_ALARM, // is SET button is pushed while "SET ALARM" is displayed, go directly to "SET_DATE", or wait 2s to enter SET_ALARM_ENABLED
  108.   SET_ALARM_ENABLED, // if OFF is choosen, go to WRITE_ALARM
  109.   SET_ALARM_HOUR,
  110.   SET_ALARM_MINUTE, // go to WRITE_ALARM when done
  111.   SET_DATE, // if SET button is pushed while "SET DATE" is displayed, go directly to "SET TIME", or wait 2s to enter SET_YEAR
  112.   SET_YEAR,
  113.   SET_MONTH,
  114.   SET_DAY, // go to WRITE_DATETIME after setting day
  115.   SET_TIME, // if SET button is pushed while "SET TIME" is displayed, return to CLOCK mode
  116.   SET_HOUR,
  117.   SET_MINUTE,
  118.   WRITE_DATETIME, // returns to CLOCK when done
  119.   WRITE_ALARM // returns to CLOCK when done
  120. };
  121. volatile int currentState = CLOCK;
  122. volatile unsigned long mode_start=0;
  123. volatile unsigned long last_button_push=0;
  124.  
  125. const char* clock_format_no_tick = "%02d %02d %02d";
  126. const char* clock_format_tick = "%02d-%02d-%02d";
  127. const char* clock_format_date = "%02d %s";
  128. const char* set_hour_tick = "   %02d   ";
  129. const char* set_hour_no_tick = "%02d %02d   ";
  130. const char* set_minute_tick = "%02d      ";
  131. const char* set_minute_no_tick = set_hour_no_tick;
  132. const char* set_day_tick = "   %s";
  133. const char* set_month_tick = set_minute_tick;
  134. const char* set_year_tick = "  %04d  ";
  135. const char* month[] = {"JANV ","FEV  ","MARS ","AVRIL","MAI  ","JUIN ","JUIL ","AOUT ","SEPT ","OCT  ","NOV  ","DEC  "}; // french months, change them as you like but keep 5 characters per month
  136. const int daysInMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  137. char displayBuffer[9]= "aaaaaaaa";
  138.  
  139. // credits go to http://huinink.info/8-x-14-segment/ for most of the ascii table font, I only modified a few numbers to take advantage of the 14 segments
  140. const byte ascii[] PROGMEM={
  141.   0x00, 0x00, // space
  142.   0x01, 0x4A, // !
  143.   0x22, 0x00, // "
  144.   0x0E, 0x55, // #
  145.   0x39, 0x55, // euro. for dollar use 0x2D, 0x55
  146.   0x24, 0x88, // %
  147.   0x1D, 0x2B, // &
  148.   0x00, 0x08, // '
  149.   0x39, 0x00, // {
  150.   0x0F, 0x00, // )
  151.   0x00, 0xFF, // *
  152.   0x00, 0x55, // +
  153.   0x00, 0x80, // ,
  154.   0x00, 0x11, //
  155.   0x08, 0x00, // dot?
  156.   0x00, 0x88, // /
  157.   0x3F, 0x00, // 0
  158.   0x06, 0x08, // 1
  159.   0x1B, 0x11, // 2
  160.   0x0F, 0x10, // 3
  161.   0x26, 0x11, // 4
  162.   0x2D, 0x11, // 5
  163.   0x3D, 0x11, // 6
  164.   0x01, 0x88, // 7
  165.   0x3F, 0x11, // 8
  166.   0x2F, 0x11, // 9
  167.   0x01, 0x11, // :
  168.   0x01, 0x80, // ;
  169.   0x00, 0x28, // <
  170.   0x00, 0x82, // >
  171.   0x08, 0x11, // =
  172.   0x03, 0x50, // ?
  173.   0x1F, 0x41, // @
  174.   0x37, 0x11, // A
  175.   0x0F, 0x54, // B
  176.   0x39, 0x00, // C
  177.   0x0F, 0x44, // D
  178.   0x39, 0x01, // E
  179.   0x31, 0x01, // F
  180.   0x3D, 0x10, // G
  181.   0x36, 0x11, // H
  182.   0x09, 0x44, // I
  183.   0x1E, 0x00, // J
  184.   0x30, 0x29, // K
  185.   0x38, 0x00, // L
  186.   0x36, 0x0A, // M
  187.   0x36, 0x22, // N
  188.   0x3F, 0x00, // O
  189.   0x33, 0x11, // P
  190.   0x3F, 0x20, // Q
  191.   0x33, 0x31, // R
  192.   0x2D, 0x11, // S
  193.   0x01, 0x44, // T
  194.   0x3E, 0x00, // U
  195.   0x30, 0x88, // V
  196.   0x36, 0xA0, // W
  197.   0x00, 0xAA, // X
  198.   0x00, 0x4A, // Y
  199.   0x09, 0x88, // Z
  200.   0x39, 0x00, // [
  201.   0x00, 0x88, // /
  202.   0x0F, 0x00, // ]
  203.   0x00, 0xA0, // ^
  204.   0x08, 0x00, // _
  205.   0x00, 0x02, // `
  206.   0x3F, 0xFF  // a --> test character
  207. };
  208.  
  209. void buttonsManager()
  210. {
  211.   if(millis()-last_button_push>150) {
  212.     switch(PCintPort::arduinoPin) {
  213.       case setButton:
  214.         if(currentState == SET_ALARM)
  215.           currentState = SET_DATE;
  216.         else if(currentState == SET_DATE)
  217.           currentState = SET_TIME;
  218.         else if(currentState==SET_TIME)
  219.           currentState = CLOCK;
  220.         else if(currentState==SET_MONTH)
  221.         {
  222.           if( curDateTime.monthDay > daysInMonth[curDateTime.month-1])
  223.             curDateTime.monthDay = daysInMonth[curDateTime.month-1];
  224.           currentState++;  
  225.         }
  226.         else if(currentState == SET_DAY)
  227.           currentState = WRITE_DATETIME;
  228.         else if(currentState == SET_MINUTE)
  229.         {
  230.           curDateTime.second=0;
  231.           currentState = WRITE_DATETIME;  
  232.         }
  233.         else if((currentState==SET_ALARM_ENABLED && alarm.enabled==false) || currentState==SET_ALARM_MINUTE)
  234.           currentState = WRITE_ALARM;
  235.         else
  236.           currentState++;
  237.         mode_start=millis();
  238.         break;
  239.       case minusButton:
  240.         switch(currentState) {
  241.           case SET_HOUR:
  242.             if(curDateTime.hour<=0)
  243.               curDateTime.hour = 23;
  244.             else
  245.               curDateTime.hour--;
  246.             break;
  247.           case SET_MINUTE:
  248.             if(curDateTime.minute<=0)
  249.               curDateTime.minute = 59;
  250.             else
  251.               curDateTime.minute--;
  252.             break;
  253.           case SET_ALARM_ENABLED:
  254.             alarm.enabled = !alarm.enabled;
  255.             digitalWrite(alarmLed, alarm.enabled);
  256.             break;
  257.           case SET_ALARM_HOUR:
  258.             if(alarm.hour<=0)
  259.               alarm.hour = 23;
  260.             else
  261.               alarm.hour--;
  262.             break;
  263.           case SET_ALARM_MINUTE:
  264.             if(alarm.minute<=0)
  265.               alarm.minute = 59;
  266.             else
  267.               alarm.minute--;
  268.             break;
  269.           case SET_MONTH:
  270.             if(curDateTime.month<=1)
  271.               curDateTime.month = 12;
  272.             else
  273.               curDateTime.month--;
  274.             break;
  275.           case SET_DAY:
  276.             if(curDateTime.monthDay <= 1)
  277.               if(isLeapYear(curDateTime.year) && curDateTime.month==2)
  278.                 curDateTime.monthDay = 29;
  279.               else
  280.                 curDateTime.monthDay = daysInMonth[curDateTime.month-1];
  281.             else
  282.               curDateTime.monthDay--;
  283.             break;
  284.           case SET_YEAR:
  285.             if(curDateTime.year<=2000)
  286.               curDateTime.year = 2099;
  287.             else
  288.               curDateTime.year--;
  289.             break;
  290.         }
  291.         break;
  292.       case plusButton:
  293.         switch(currentState) {
  294.           case SET_HOUR:
  295.             if(curDateTime.hour>=23)
  296.               curDateTime.hour = 0;
  297.             else
  298.               curDateTime.hour++;
  299.             break;
  300.           case SET_MINUTE:
  301.             if(curDateTime.minute>=59)
  302.               curDateTime.minute = 0;
  303.             else
  304.               curDateTime.minute++;
  305.             break;
  306.           case SET_ALARM_ENABLED:
  307.             alarm.enabled = !alarm.enabled;
  308.             digitalWrite(alarmLed, alarm.enabled);
  309.             break;
  310.           case SET_ALARM_HOUR:
  311.             if(alarm.hour>=59)
  312.               alarm.hour = 0;
  313.             else
  314.               alarm.hour++;
  315.             break;
  316.           case SET_ALARM_MINUTE:
  317.             if(alarm.minute>=59)
  318.               alarm.minute = 0;
  319.             else
  320.               alarm.minute++;
  321.             break;
  322.           case SET_MONTH:
  323.             if(curDateTime.month>=12)
  324.               curDateTime.month = 1;
  325.             else
  326.               curDateTime.month++;
  327.             break;
  328.           case SET_DAY:
  329.             if(isLeapYear(curDateTime.year) && curDateTime.month==2 && curDateTime.monthDay>=29)
  330.               curDateTime.monthDay = 1;
  331.             else if(curDateTime.monthDay >= daysInMonth[curDateTime.month-1])
  332.               curDateTime.monthDay = 1;
  333.             else
  334.               curDateTime.monthDay++;
  335.             break;
  336.           case SET_YEAR:
  337.             if(curDateTime.year>=2099)
  338.               curDateTime.year = 2000;
  339.             else
  340.               curDateTime.year++;
  341.             break;
  342.         }
  343.         break;
  344.     }
  345.     last_button_push = millis();
  346.   }
  347. }
  348.  
  349. void setup()
  350. {
  351.   digitalWrite(oePin, HIGH); // disable output
  352.   pinMode(oePin, OUTPUT);
  353.   pinMode(dataPin1, OUTPUT);
  354.   pinMode(dataPin2, OUTPUT);
  355.   pinMode(dataPin3, OUTPUT);
  356.   pinMode(latchPin, OUTPUT);
  357.   pinMode(clockPin, OUTPUT);
  358.  
  359.   pinMode(buzzer, OUTPUT);
  360.   digitalWrite(buzzer, LOW);
  361.   pinMode(alarmLed, OUTPUT);
  362.  
  363.   // init buttons interrupt
  364.   pinMode(setButton, INPUT);
  365.   digitalWrite(setButton, HIGH);
  366.   PCintPort::attachInterrupt(setButton, &buttonsManager, FALLING);
  367.   pinMode(minusButton, INPUT);
  368.   digitalWrite(minusButton, HIGH);
  369.   PCintPort::attachInterrupt(minusButton, &buttonsManager, FALLING);
  370.   pinMode(plusButton, INPUT);
  371.   digitalWrite(plusButton, HIGH);
  372.   PCintPort::attachInterrupt(plusButton, &buttonsManager, FALLING);
  373.  
  374.   // init I2C bus for DS1307 RTC
  375.   Wire.begin();
  376.  
  377.   // init display interrupt
  378.   Timer1.initialize(DISPLAY_ISR_PERIOD);
  379.   Timer1.attachInterrupt(displayISR);
  380.  
  381.   getAlarmSettings();
  382.  
  383.   delay(1000);
  384. }
  385.  
  386. bool isLeapYear(const int year) {
  387.   return year%4==0; // ok for 2000-2099 because 2000 is leap
  388. }
  389.  
  390. void printDate() {
  391.   sprintf(displayBuffer,clock_format_date,curDateTime.monthDay, month[curDateTime.month-1]);
  392. }
  393.  
  394. void printTime() {
  395.   sprintf(displayBuffer,curDateTime.second%2?clock_format_tick:clock_format_no_tick,curDateTime.hour,curDateTime.minute,curDateTime.second);
  396. }
  397.  
  398. void buzz() {
  399.   unsigned long alarmStart=millis();
  400.   while(digitalRead(setButton==HIGH) && millis()-alarmStart < 60000) { // one minute should be enough to wake up ;)
  401.     updateCurDateTime();
  402.     printTime();
  403.     for(int j=0; j<4; j++) {
  404.       digitalWrite(buzzer,HIGH);
  405.       delay(90);
  406.       digitalWrite(buzzer,LOW);
  407.       delay(45);
  408.       if(digitalRead(setButton)==LOW) {
  409.         currentState = CLOCK;
  410.         return;
  411.       }
  412.     }
  413.     sprintf(displayBuffer,"  ALARM ");
  414.     delay(400);
  415.   }
  416.   currentState = CLOCK;
  417. }
  418.  
  419. void loop(){
  420.   bool tick=millis()%600<300 && millis()-last_button_push >  400;
  421.   if(millis()-last_button_push>200 && (digitalRead(minusButton)==LOW || digitalRead(plusButton)==LOW)) { // buttons auto-repeat
  422.     buttonsManager();
  423.   }
  424.   updateCurDateTime();
  425.   switch(currentState) {
  426.     case CLOCK:
  427.       printTime();
  428.       if(alarm.enabled && curDateTime.second==0 && curDateTime.hour==alarm.hour && curDateTime.minute==alarm.minute)
  429.         buzz();
  430.       break;
  431.     case DATE:
  432.       printDate();
  433.       if(millis()-mode_start>5000) // return to clock after 5s
  434.         currentState = CLOCK;
  435.       break;
  436.     case SET_ALARM:
  437.       if(millis()%1000<500)
  438.         sprintf(displayBuffer, "SET ALAR");
  439.       else
  440.         sprintf(displayBuffer, "ET ALARM");
  441.         if(millis()-mode_start>2000) // wait 2s to set alarm
  442.           currentState++;
  443.       break;
  444.     case SET_ALARM_ENABLED:
  445.       if(alarm.enabled)
  446.         sprintf(displayBuffer,"   ON   ");
  447.       else
  448.         sprintf(displayBuffer,"   OFF  ");
  449.       break;
  450.     case SET_ALARM_HOUR:
  451.       if(tick)
  452.         sprintf(displayBuffer, set_hour_tick, alarm.minute);
  453.       else
  454.         sprintf(displayBuffer, set_hour_no_tick, alarm.hour, alarm.minute);
  455.       break;
  456.     case SET_ALARM_MINUTE:
  457.       if(tick)
  458.         sprintf(displayBuffer, set_minute_tick, alarm.hour);
  459.       else
  460.         sprintf(displayBuffer, set_minute_no_tick, alarm.hour, alarm.minute);
  461.       break;
  462.     case SET_TIME:
  463.       sprintf(displayBuffer,"SET TIME");
  464.       if(millis()-mode_start>2000) // wait 2s to set time
  465.         currentState++;
  466.       break;  
  467.     case SET_HOUR:
  468.       if(tick)
  469.         sprintf(displayBuffer, set_hour_tick, curDateTime.minute);
  470.       else
  471.         sprintf(displayBuffer, set_hour_no_tick, curDateTime.hour, curDateTime.minute);
  472.       break;
  473.     case SET_MINUTE:
  474.       if(tick)
  475.         sprintf(displayBuffer, set_minute_tick, curDateTime.hour);
  476.       else
  477.         sprintf(displayBuffer, set_minute_no_tick, curDateTime.hour, curDateTime.minute);
  478.       break;
  479.     case SET_DATE:
  480.       sprintf(displayBuffer,"SET DATE");
  481.       if(millis()-mode_start>2000) // wait 2s to set date
  482.         currentState++;
  483.       break;
  484.     case SET_MONTH:
  485.       if(tick)
  486.         sprintf(displayBuffer, set_month_tick, curDateTime.monthDay);
  487.       else
  488.         printDate();
  489.       break;
  490.     case SET_DAY:
  491.       if(tick)
  492.         sprintf(displayBuffer, set_day_tick, month[curDateTime.month-1]);
  493.       else
  494.         printDate();
  495.       break;
  496.     case SET_YEAR:
  497.       if(tick)
  498.         sprintf(displayBuffer, "        ");
  499.       else
  500.         sprintf(displayBuffer, set_year_tick, curDateTime.year);
  501.       break;
  502.     case WRITE_DATETIME:
  503.       setDateTime();
  504.       currentState=CLOCK;
  505.       break;
  506.     case WRITE_ALARM:
  507.       setAlarmSettings();
  508.       currentState=CLOCK;
  509.       break;
  510.   }
  511. }
  512.  
  513. void shiftBits (byte cathodes, byte segments1,  byte segments2){
  514.   PORTD |= B10000000; // HC595s latch high
  515.   for (int k=0; k < 8; k++){
  516.     PORTB &= ~1; // HC595s clock low
  517.     if ( cathodes & (0b10000000 >> k) )
  518.       PORTD |= 0b100000; // HC595-1 data high
  519.     else
  520.       PORTD &= ~0b100000; // HC595-1 data low
  521.     if ( segments2 & (0b10000000 >> k) )
  522.       PORTD |= 0b10000; // HC595-2 data high
  523.     else
  524.       PORTD &= ~0b10000; // HC595-2 data low
  525.     if ( segments1 & (0b10000000 >> k) )
  526.       PORTD |= 0b1000000; // HC595-3 data high
  527.     else
  528.       PORTD &= ~0b1000000; // HC595-3 data low
  529.     PORTB |= 1; // HC595s clock high
  530.   }
  531.   PORTD &= ~0b10000000; // HC595s latch low
  532. }
  533.  
  534. void displayISR(){  
  535.   PORTD &= ~B1000; // HC595s output enabled
  536.   for (int cathode = 0; cathode <8; cathode++){
  537.     shiftBits(0xFF-(1<<cathode),pgm_read_byte(&ascii[(2*(displayBuffer[cathode]-0x20))]), pgm_read_byte(&ascii[(1+2*(displayBuffer[cathode]-0x20))]));
  538.   }
  539.   PORTD |= B1000; // HC595s output disabled
  540. }
  541.  
  542. byte bcdToDec(byte val) {
  543.   return ((val/16*10)+(val%16));
  544. }
  545.  
  546. byte decToBcd(byte val){
  547.   return ((val/10*16)+(val%10));
  548. }
  549.  
  550. void updateCurDateTime() {
  551.   static unsigned long last_update = -200;
  552.   if((currentState<SET_HOUR || currentState>SET_MINUTE) && currentState != WRITE_DATETIME) {
  553.     if(millis()-last_update>100) {
  554.       Timer1.detachInterrupt(); // disable display ISR while using i2c bus
  555.       Wire.beginTransmission(DS1307_ADDRESS);
  556.       WireWrite(0);
  557.       Wire.endTransmission();
  558.       Wire.requestFrom(DS1307_ADDRESS, 7);
  559.       curDateTime.second = bcdToDec(WireRead);
  560.       curDateTime.minute = bcdToDec(WireRead);
  561.       curDateTime.hour = bcdToDec(WireRead & 0b111111);
  562.       curDateTime.weekDay = bcdToDec(WireRead);
  563.       if(currentState>SET_DAY || currentState<SET_YEAR) {
  564.         curDateTime.monthDay = bcdToDec(WireRead);
  565.         curDateTime.month = bcdToDec(WireRead);
  566.         curDateTime.year = bcdToDec(WireRead)+2000;
  567.       }
  568.       if(curDateTime.second & 0b1000000) {
  569.         curDateTime.second = 0; // disable Clock Halt bit on fresh ds1307 chip
  570.         setDateTime();
  571.       }
  572.       Timer1.attachInterrupt(displayISR);
  573.     }
  574.   }
  575. }
  576.  
  577. void setDateTime() {
  578.   Timer1.detachInterrupt();
  579.   Wire.beginTransmission(DS1307_ADDRESS);
  580.   WireWrite(0);
  581.   WireWrite(decToBcd(curDateTime.second));
  582.   WireWrite(decToBcd(curDateTime.minute));
  583.   WireWrite(decToBcd(curDateTime.hour));
  584.   WireWrite(decToBcd(curDateTime.weekDay));
  585.   WireWrite(decToBcd(curDateTime.monthDay));
  586.   WireWrite(decToBcd(curDateTime.month));
  587.   WireWrite(decToBcd(curDateTime.year-2000));
  588.   WireWrite(0);
  589.   Wire.endTransmission();
  590.   Timer1.attachInterrupt(displayISR);
  591. }
  592.  
  593. void getAlarmSettings()
  594. {
  595.   if(EEPROM.read(0)==0x13 && EEPROM.read(1)==0x37) // check signature
  596.   {
  597.     alarm.enabled = EEPROM.read(2);
  598.     alarm.hour = EEPROM.read(3);
  599.     alarm.minute = EEPROM.read(4);
  600.   }
  601.   digitalWrite(alarmLed, alarm.enabled);
  602. }
  603.  
  604. void setAlarmSettings()
  605. {
  606.   EEPROM.write(0, 0x13);
  607.   EEPROM.write(1, 0x37);
  608.   EEPROM.write(2, alarm.enabled);
  609.   EEPROM.write(3, alarm.hour);
  610.   EEPROM.write(4, alarm.minute);
  611. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement