SHARE
TWEET

Untitled

a guest Feb 21st, 2019 72 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <avr/interrupt.h>
  2. #include <avr/io.h>
  3. #include <stdlib.h>
  4. #include <\\puffball.labs.eait.uq.edu.au\s4264101\Documents\i2cmaster.h>
  5. //#include <C:\Users\battlemage\Downloads\twimaster.c>
  6. //#include <C:\Users\battlemage\Downloads\i2cmaster.h>
  7.  
  8. #define DS1307 0b11010000
  9. #define ENABLE 32
  10. #define TIME_BTN 77
  11. #define SETTING_BTN 83
  12. #define ENTER_BTN 81
  13. #define DATE_BTN 69
  14. #define ALARM_BTN 85
  15. #define NEXT_BTN 67
  16. #define PREV_BTN 75
  17. #define WEATHER_SET 3
  18. #define WEATHER_BTN 73
  19.  
  20. void update_time(void); //Updates Time Variables from RTC
  21. void set_rtc_time(void); //Sends time to RTC
  22. char dec2bcd(char); //Converts numbers from Decimal to Binary-coded Decimal
  23. char bcd2dec(char); //Converts numbers from Binary-coded Decimal to Decimal
  24. void configure_display(void); //Chooses what to show on the display
  25. void update_display(int); //Adds a given integer into the display array
  26. void add_display(int); //Adds a specific led into the display array
  27. void cycle_leds(void); //Cycles through the display array
  28. void add_current_alarm(void); //Adds the last alarm recieved to alarm array
  29. void check_for_alarm(); //Checks the alarm array for alarms at current time
  30. void clear_leds(void); //Clears the ledsOn array
  31. void update_time_variables(void); //Updates time global variables
  32. void reset_clock(void); //Resets the global time variables
  33. char get_command(void); //Calculates the decimal value of the last infrared command recieved
  34. void deal_with_command(void); //Directs the program after recieving an IR command
  35. void enter_button_pressed(void); //Directs the program after recieving a "Set" IR command
  36. void prev_button_pressed(void); //Updates the display when "Previous" button is pressed
  37. void next_button_pressed(void); //Updates the display when "Next" button is pressed
  38. void set_time(void); //Controls IR time setting
  39. void set_date(void); //Controls IR date setting
  40. void set_alarm(void); //Controls IR alarm setting
  41. void setting_mode(void); //Controls IR setting mode
  42. void check_clock(void); //Checks to see if Optical "clock" has changed
  43. void read_data(void); //Reads data off the Optical "data" pin
  44. char get_adc(void); //Calculates decimal value of last optical command
  45. void deal_with_adc(void); //Directs program after recieving an optical command
  46. void clear_adc(void); //Clears the optical command array
  47. void adc_setting_mode(void); //Controls Optical Setting mode
  48. void adc_set(void); //Directs program while in Optical setting
  49. void adc_weather_set(void); //Controlls Optical weather Setting
  50. void adc_set_time(void); //Controls Optical time setting
  51. void adc_set_alarm(void); //Controls Optical alarm setting
  52. void adc_set_date(void); //Controls Optical date setting
  53.  
  54.  
  55.  
  56. int ledDemux[17] = {12, 24, 28, 0, 2, 4, 6, 16, 20, 18, 22, 14, 10, 8, 26, 30, 12}; //Demux values for LEDs
  57.  
  58. volatile int ledsOn[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; //Current Leds on Display
  59. volatile int irArray[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; //IR commands recieved
  60. volatile int adcArray[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; //Optical commands recieved
  61. volatile int oldSeconds = 0; //Previously checked seconds
  62. volatile int prevOldSeconds = 0;  //Prviously checked seconds
  63. volatile int lastCycle = 0; //Last LED turned on
  64. volatile int irCount = 0; //Number of bits in current IR signal recieved
  65. volatile int change = 0; //DONT THINK WE NEED -------------------------------------------------------------
  66. volatile int display = 0; //Display enabled -- 0 == enabled
  67. volatile int newSignal = 0; //Ready for new signal -- 0 == ready
  68. volatile int wavesMissed = 0; //Number of IR reads missed to avoid repetition of commands
  69. volatile int displayMode = 0; //Current Display -- 0 = time, 1 = date, 2 = weather
  70. volatile int dateDisplayChange = 0; //Time when display was changed to date
  71. volatile int weatherDisplayChange = 0; //Time when display was changed to weather
  72. volatile int weatherType = 0; //Current weather -- 1 = fine, 2 = rain, 3 = cloud
  73. volatile int oldADC = 0; //Previous Optical clock
  74. volatile int currentADC = 0; //Current Optical clock
  75. volatile int adcCount = 0; //Number of bits in current Optical command
  76. volatile int adcDelay = -1; //Pause between optical reads
  77.  
  78. //Time Variables
  79. volatile int seconds = 0; //Number of seconds in current minute
  80. volatile int minutes = 0; //Number of minutes in current hour
  81. volatile int hours = 0; //Number of hours in current day
  82. volatile int day = 1; //Number of days in current month
  83. volatile int month = 1; //Number of months in current year
  84. volatile int year = 2012; //Current year
  85. volatile int ampm = 0; //Current am/pm
  86. volatile int changeSeconds = -1; //Number of seconds in current minute
  87. volatile int changeMinutes = -1; //Number of minutes in current hour
  88. volatile int changeHours = -1; //Number of hours in current day
  89. volatile int changeDay = -1; //Number of days in current month
  90. volatile int changeMonth = -1; //Number of months in current year
  91. volatile int changeYear = -1; //Current year
  92. volatile int changeAmpm = -1; //Current am/pm
  93.  
  94. //Alarm Variables
  95. int alarmNow = 0; //Alarm needs to trigger
  96. int buzzPrev = 0; //Last Buzzer Check
  97. int buzzCount = 0; //Number of seconds remaining on buzzer
  98. int adcNum = 0; //Second last Optical command
  99. int settingMode = 0; //In IR setting mode
  100. int adcSettingMode = 0; //In Optical Setting mode
  101. int currentLedIndex = 0; //Current Led turned on in setting mode
  102. int specificSet = 0;  //If a specific setting mode has been selected (time, alarm etc.)
  103.  
  104. int alarms[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; //Alarms Set
  105. int alarmMeridians[10] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}; //Corresponding am/pm for alarms
  106.  
  107. // Time Setting
  108. int timeSetting = 0;
  109. int minutesSet = 0;
  110. int hoursSet = 0;
  111. int tempMeridian = 0;
  112. //Optical temp variables
  113. int adcHours = 0;  
  114. int adcMinutes = 0;        
  115. int adcAmpm = 0;           
  116. int adcCommandStart = -1; //Time when optical command begins to be recieved
  117. int adcSettingStart = -1; //Time when optical setting mode is enabled
  118.  
  119. int weatherSetting = 0; // Weather Setting
  120.  
  121. // Alarm Setting
  122. int dateSetting = 0;
  123. int minuteResoSet = 0;
  124. int alarmSetting = 0;
  125. int tempMinutes = 0;
  126. int tempHours = 0;
  127. int tempAmPm = 0;
  128.  
  129. // Date Setting
  130. int tempLeap = 0;
  131. int yearSet = 0;
  132. int yearResoSet = 0;
  133. int monthSet = 0;
  134. int daySet = 0;
  135. int dayResoSet = 0;
  136. int adcYear = 0;
  137. int adcMonth = 0;
  138. int adcDay = 0;
  139.  
  140.  
  141. /* Main loop for clock processing*/
  142. int main(void) {
  143.     DDRB = 0xFF; //Basic I/O Setup
  144.     PORTB = 0x00;
  145.     DDRB = 0x3F;   
  146.  
  147.     DDRC = 0xFF;
  148.     PORTC = 0x00;
  149.     DDRC = 0x32;
  150.  
  151.     DDRD = 0xFF;
  152.     PORTD = 0x00;
  153.     DDRD = 0xC0;
  154.    
  155.     sei(); //Global Interrupts on
  156.  
  157.     EICRA |= (1 << ISC00);    // set INT0 to trigger on ANY logic change
  158.     EIMSK |= (1 << INT0);     // Turns on INT0
  159.  
  160.     TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt
  161.     TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
  162.     OCR1A   = 840; // Trigger every 0.84ms
  163.  
  164.     TIMSK0 |= (1 << OCIE0A); // Enable CTC interrupt
  165.     TCCR0A |= (1 << WGM01); // Configure timer 1 for CTC mode
  166.     OCR0A  = 80;
  167.     TCCR0B |= ((1 << CS01));
  168.  
  169.     ADMUX = 0x40; //ADC Setup for ADC0
  170.     ADCSRA = 0x86; //Configure ADC to run on demand
  171.     ADCSRB = 0x00;
  172.     ADCSRA |= 0x40; //Run initial ADC check
  173.     while ((ADCSRA & 0x40) != 0x00); //Wait for check to finish
  174.     check_clock(); //Check initial ADC
  175.     for (int i = 0; i < 8; i++) { //Clear array resulting from check
  176.         adcArray[i] = -1;
  177.     }
  178.     i2c_init(); //Initialise I2C communication for RTC
  179.     changeSeconds = 0;
  180.     changeMinutes = 0;
  181.     changeHours = 0;changeAmpm = 0;
  182.     set_rtc_time();
  183.  
  184.    
  185.     while(1) {
  186.        
  187.         /* Setting mode while loop if in setting mode */
  188.         if(settingMode) {
  189.             PORTD &= 0xBF;
  190.             setting_mode(); //Setting mode while loop
  191.         }
  192.         //Optical taken too long to receive a command
  193.         if ((adcCommandStart != -1) && (seconds == ((adcCommandStart + 5) % 60))) {
  194.             clear_adc();
  195.             adcCommandStart = -1;
  196.         }
  197.         //Check the Optical Sensors
  198.         if (((ADCSRA & 0x40) == 0) && (adcDelay == -1)) { //NEW
  199.             ADCSRA |= 0x40;
  200.             while ((ADCSRA & 0x40) != 0x00); //Wait for conversion to finish
  201.             check_clock();
  202.         }
  203.         /* Setting mode for ADC, GUI data transfer */
  204.         if(adcSettingMode) {
  205.             adc_setting_mode();
  206.         }
  207.  
  208.         //ALARM CHECK
  209.         check_for_alarm();
  210.         //If alarm is found
  211.         if(alarmNow) {
  212.             PORTC |= 0b00000010;    //Turn on buzzer
  213.             if(buzzPrev != seconds) {   //Decrement the buzzer timer (buzzCount)
  214.                 buzzPrev = seconds;
  215.                 buzzCount--;
  216.             }
  217.             if(buzzCount == 0) {    //If the buzzer doesn't need to be sounded anymore, turn it off
  218.                 PORTC &= 0b11111101;
  219.                 alarmNow = 0;
  220.                 buzzCount = 0;
  221.                 buzzPrev = 0;
  222.             }
  223.         }
  224.        
  225.                                
  226.         //DISPLAY
  227.         update_time(); //Update time from RTC
  228.         configure_display(); //configure what is displayed
  229.         update_time_variables(); //Update global time variables
  230.  
  231.     }
  232. }
  233.  
  234. //Used for IR communication. Started after IR command begins
  235. ISR(TIMER1_COMPA_vect) {
  236.     /* Read in IR value */
  237.     if (newSignal == 1) {
  238.         if(!display) { //Not in displaymode
  239.             if((PIND & 0x04) == 0x04) { //Read data
  240.                 irArray[irCount] = 1;
  241.             } else {
  242.                 irArray[irCount] = 0;
  243.             }
  244.             irCount++; //Another bit read
  245.             OCR1A = 1680; //Read in a full waves time
  246.             if (irCount == 8) { //If full IR signal recieved
  247.                 change = 0;
  248.                 irCount = 0; //reset IR counter
  249.                 display = 1; //enable display again
  250.                 if(settingMode) { //If already in settingmode
  251.                     deal_with_command(); //Act on command
  252.                 } else if (get_command() == SETTING_BTN) { //Otherwise if command was set
  253.                     if(!adcSettingMode) { //If its not already setting Optical
  254.                         settingMode = 1; //Enter IR setting mode
  255.                     }                  
  256.                 } else if (get_command() == DATE_BTN) { //If command is date
  257.                     dateDisplayChange = seconds; //Start the date display
  258.                     displayMode = 1;
  259.                 } else if (get_command() == WEATHER_BTN) { //If command is weather
  260.                     weatherDisplayChange = seconds; //Start weather display
  261.                     displayMode = 2;
  262.                 }
  263.                 EIMSK |= (1 << INT0);     // Turns on INT0
  264.  
  265.             }
  266.         } else { //Otherwise skip IR reads to avoid second signal
  267.             wavesMissed++; //Increment waves missed
  268.             if (wavesMissed == 65) { //If enough waves missed
  269.                 TCCR1B |= (0 << CS10); //Able to recieve new command
  270.                 TIMSK1 = 0;
  271.                 wavesMissed = 0;
  272.                 newSignal = 0;
  273.                 display = 0;
  274.             }
  275.         }
  276.     }
  277. }
  278.  
  279. //Timer for cycling display and tracking ADC delays
  280. ISR(TIMER0_COMPA_vect) {
  281.     if((settingMode == 0) && (adcSettingMode == 0)) { //If not setting
  282.         cycle_leds(); //Cycle through LED array
  283.     }
  284.     if (adcDelay != -1) { //If waiting for next Optical read
  285.         adcDelay++; //Increment delay to 700
  286.         if (adcDelay == 700) {
  287.             adcDelay = -1;
  288.         }
  289.     }
  290. }
  291.  
  292. //Infrared reciever pin change
  293. ISR(INT0_vect) {
  294.     if (newSignal == 0) { //Ready to get new signal
  295.         EIMSK |= (0 << INT0);     // Turns off INT0_vect
  296.         change = 1;
  297.         TCNT1 = 0; //clears timer register
  298.         OCR1A = 840; //Sets timer to read HALF an ir wave from now!! IMPORTANT
  299.         TCCR1B |= ((1 << CS10)); // Start timer at Fcpu/1
  300.         TIMSK1 |= (1 << OCIE1A);
  301.         newSignal = 1;
  302.     }
  303. }  
  304.  
  305. //Gets the current seconds value form RTC
  306. void update_time(void) {
  307.     i2c_start_wait(DS1307+I2C_WRITE);     // set device address and write mode
  308.     i2c_write(0x00);                        // write address = =0
  309.     i2c_rep_start(DS1307+I2C_READ);       // set device address and read mode
  310.     seconds = i2c_readAck();                    // read one byte
  311.     seconds = bcd2dec(seconds); //Convert from Binary Coded Decimal
  312.     minutes = i2c_readAck();
  313.     minutes = bcd2dec(minutes);
  314.     hours = i2c_readNak();
  315.     hours = bcd2dec(hours);
  316.     if (hours >= 12) {
  317.         hours -= 12;
  318.         ampm = 1;
  319.     } else {
  320.         ampm = 0;
  321.     }
  322.     i2c_stop();
  323. }
  324.  
  325. void set_rtc_time(void) {
  326.     i2c_start_wait(DS1307+I2C_WRITE);
  327.     i2c_write(0x00);
  328.     if (changeSeconds != -1) {
  329.         i2c_write(dec2bcd(changeSeconds));
  330.     } else {
  331.         i2c_write(dec2bcd(seconds));
  332.     }
  333.     if (changeMinutes != -1) {
  334.         i2c_write(dec2bcd(changeMinutes));
  335.     } else {
  336.         i2c_write(dec2bcd(minutes));
  337.     }
  338.     if (changeHours != -1) {
  339.         if (changeAmpm == 1) {
  340.             i2c_write(dec2bcd(changeHours + 12));
  341.         } else {
  342.             i2c_write(dec2bcd(changeHours));
  343.         }
  344.     } else {
  345.         if (ampm == 1) {
  346.             i2c_write(dec2bcd(hours + 12));
  347.         } else {
  348.             i2c_write(dec2bcd(hours));
  349.         }
  350.     }
  351.     i2c_stop();
  352.     changeSeconds = -1;
  353.     changeMinutes = -1;
  354.     changeHours = -1;
  355.     changeAmpm = -1;
  356. }
  357.  
  358. //Add the minutes to the display correctly
  359. void update_display(int time) {
  360.     int outer = time / 5;
  361.     int inner = time % 5;
  362.     for (int i = 0; i < 8; i++) {
  363.         ledsOn[i] = -1;
  364.     }
  365.     ledsOn[0] = ledDemux[outer];
  366.     if (inner != 0) {
  367.         for (int i = 0; i < inner; i++) {
  368.             ledsOn[i+1] = ledDemux[i+12];
  369.         }
  370.     }
  371. }
  372.  
  373. //Runs the display.
  374. //displayMode 0 is time
  375. //displayMode 1 is date
  376. //displayMode 2 is weather
  377. void configure_display(void) {
  378.     if (displayMode == 0) {
  379.         if ((seconds % 2) == 0) { //flash the hours in time mode
  380.             update_display(minutes);
  381.             add_display(hours);
  382.         } else {
  383.             update_display(minutes);
  384.         }
  385.         if (ampm == 1) { //turn on am/pm light if its pm
  386.             PORTD |= 0x40;
  387.         } else {
  388.             PORTD &= 0xBF;
  389.         }
  390.     } else if (displayMode == 1) { //date
  391.         if (seconds < ((dateDisplayChange + 3) % 60)) {
  392.             update_display(day); //Show the day
  393.             PORTB |= 0x01;
  394.             PORTD &= 0x3F;
  395.         } else if (seconds < ((dateDisplayChange + 6) % 60)) {
  396.             if (month != 12) { //Show the month
  397.                 update_display(month*5);
  398.             } else {
  399.                 update_display(0);
  400.             }
  401.             PORTB &= 0xFE;
  402.             PORTD &= 0x3F;
  403.             PORTD |= 0x80;
  404.         } else if (seconds < ((dateDisplayChange + 9) % 60)) {
  405.             update_display(year - 2000); //Show the year
  406.             PORTD &= 0x3F;
  407.             PORTD |= 0x40;
  408.         } else {
  409.             dateDisplayChange = 0;
  410.             PORTD &= 0x3F;
  411.             displayMode = 0;
  412.         }
  413.     } else if (displayMode == 2) { //Weather
  414.         if (weatherType == 0) { //Fine
  415.             if (seconds < ((weatherDisplayChange + 1) % 60)) {
  416.                 clear_leds();
  417.                 add_display(6);
  418.             } else if (seconds < ((weatherDisplayChange + 2) % 60)) {
  419.                 clear_leds();
  420.                 add_display(7);
  421.                 add_display(5);
  422.             } else if (seconds < ((weatherDisplayChange + 3) % 60)) {
  423.                 clear_leds();
  424.                 add_display(8);
  425.                 add_display(4);
  426.             } else if (seconds < ((weatherDisplayChange + 4) % 60)) {
  427.                 clear_leds();
  428.                 add_display(9);
  429.                 add_display(3);
  430.             } else if (seconds < ((weatherDisplayChange + 5) % 60)) {
  431.                 clear_leds();
  432.                 add_display(6);
  433.             } else if (seconds < ((weatherDisplayChange + 6) % 60)) {
  434.                 clear_leds();
  435.                 add_display(7);
  436.                 add_display(5);
  437.             } else if (seconds < ((weatherDisplayChange + 7) % 60)) {
  438.                 clear_leds();
  439.                 add_display(8);
  440.                 add_display(4);
  441.             } else if (seconds < ((weatherDisplayChange + 8) % 60)) {
  442.                 clear_leds();
  443.                 add_display(9);
  444.                 add_display(3);
  445.             } else {
  446.                 weatherDisplayChange = 0;
  447.                 displayMode = 0;
  448.             }
  449.         } else if (weatherType == 1) { //Rainy
  450.             if (seconds < ((weatherDisplayChange + 1) % 60)) {
  451.                 clear_leds();
  452.                 add_display(0);
  453.             } else if (seconds < ((weatherDisplayChange + 2) % 60)) {
  454.                 clear_leds();
  455.                 add_display(1);
  456.                 add_display(11);
  457.             } else if (seconds < ((weatherDisplayChange + 3) % 60)) {
  458.                 clear_leds();
  459.                 add_display(2);
  460.                 add_display(10);
  461.             } else if (seconds < ((weatherDisplayChange + 4) % 60)) {
  462.                 clear_leds();
  463.                 add_display(9);
  464.                 add_display(3);
  465.             } else if (seconds < ((weatherDisplayChange + 5) % 60)) {
  466.                 clear_leds();
  467.                 add_display(0);
  468.             } else if (seconds < ((weatherDisplayChange + 6) % 60)) {
  469.                 clear_leds();
  470.                 add_display(1);
  471.                 add_display(11);
  472.             } else if (seconds < ((weatherDisplayChange + 7) % 60)) {
  473.                 clear_leds();
  474.                 add_display(2);
  475.                 add_display(10);
  476.             } else if (seconds < ((weatherDisplayChange + 8) % 60)) {
  477.                 clear_leds();
  478.                 add_display(9);
  479.                 add_display(3);
  480.             } else {
  481.                 weatherDisplayChange = 0;
  482.                 displayMode = 0;
  483.             }
  484.         } else if (weatherType == 2) { //Cloudy
  485.             if (seconds < ((weatherDisplayChange + 1) % 60)) {
  486.                 clear_leds();
  487.                 add_display(3);
  488.                 add_display(9);
  489.             } else if (seconds < ((weatherDisplayChange + 2) % 60)) {
  490.                 clear_leds();
  491.                 add_display(8);
  492.                 add_display(2);
  493.             } else if (seconds < ((weatherDisplayChange + 3) % 60)) {
  494.                 clear_leds();
  495.                 add_display(7);
  496.                 add_display(1);
  497.             } else if (seconds < ((weatherDisplayChange + 4) % 60)) {
  498.                 clear_leds();
  499.                 add_display(6);
  500.                 add_display(0);
  501.             } else if (seconds < ((weatherDisplayChange + 5) % 60)) {
  502.                 clear_leds();
  503.                 add_display(11);
  504.                 add_display(5);
  505.             } else if (seconds < ((weatherDisplayChange + 6) % 60)) {
  506.                 clear_leds();
  507.                 add_display(10);
  508.                 add_display(4);
  509.             } else if (seconds < ((weatherDisplayChange + 7) % 60)) {
  510.                 clear_leds();
  511.                 add_display(9);
  512.                 add_display(3);
  513.             } else {
  514.                 weatherDisplayChange = 0;
  515.                 displayMode = 0;
  516.             }
  517.         }
  518.     }
  519. }
  520.  
  521. //Add an individual LED to the outer ring on display
  522. void add_display(int hours) {
  523.     int num = 0;
  524.     while (num < 8) { //Search for next unused spot in array
  525.         if (ledsOn[num] == -1) {
  526.             break;
  527.         }
  528.         num++;
  529.     }
  530.     ledsOn[num] = ledDemux[hours]; //Add to array
  531. }
  532.  
  533. //Cycles through the LEDs that should be turned on
  534. void cycle_leds(void) {
  535.     int numIter = 0;
  536.     if (ledsOn[0] != -1) { //If == -1
  537.         while (numIter < 8) { //search through 8 slots
  538.             if (ledsOn[lastCycle] != -1) {
  539.                 //PORTB to be the array, turning on setting mode light if in setting mode,
  540.                 //ENABLE is to enable the demux
  541.                 PORTB = ledsOn[lastCycle] + ENABLE;
  542.                 lastCycle++;
  543.                 if (lastCycle == 8) { //reset lastCycle
  544.                     lastCycle = 0;
  545.                 }
  546.                 break;
  547.             } else {
  548.                 lastCycle = 0;
  549.             }
  550.             numIter++;
  551.         }
  552.     }
  553. }
  554.  
  555. //Deal with current command in IR Array
  556. void deal_with_command(void) { 
  557.     //If command is set
  558.     if(get_command() == SETTING_BTN) {
  559.         enter_button_pressed();
  560.     }      
  561.  
  562.     //Specific Setting Modes (TIME, ALARM, DATE)
  563.     //set spececificSet
  564.     if(!specificSet) {
  565.         if(get_command() == TIME_BTN) {
  566.             timeSetting = 1;
  567.             specificSet = 1;   
  568.         } else if (get_command() == ALARM_BTN) {
  569.             alarmSetting = 1;
  570.             specificSet = 1;
  571.         } else if (get_command() == DATE_BTN) {
  572.             dateSetting = 1;
  573.             specificSet = 1;
  574.         }
  575.        
  576.     }
  577.  
  578.     //PREVIOUS or NEXT
  579.     //Only works if specifically set
  580.     if((get_command() == NEXT_BTN) && specificSet) {
  581.         next_button_pressed();
  582.     } else if((get_command() == PREV_BTN) && specificSet) {
  583.         prev_button_pressed();
  584.     }  
  585.     PORTB = ledDemux[currentLedIndex] + settingMode + ENABLE;  
  586. }
  587.  
  588.  
  589. //If previous button is pressed while in IR setting mode
  590. void prev_button_pressed(void) {
  591.     int min = 0;    //Lower bound of valid LED range (corresponds to LEDs on clock face)
  592.     int max = 11;   //Outer bound
  593.     int skip = -1;  //Used to limit range of inner 4 LEDs  (e.g. 28 days - only 3 middle LEDs allowed)
  594.    
  595.     if(timeSetting) {
  596.         //Time Setting
  597.         if(!minutesSet) { //Setting minutes
  598.             min = 0;
  599.             max = 11;
  600.         } else if((minutesSet) && !minuteResoSet) { //Setting minute resolution
  601.             min = 12;
  602.             max = 16;
  603.         } else if (minuteResoSet) { //Setting AM/PM
  604.             min = 0;
  605.             max = 0;
  606.             currentLedIndex = 0;
  607.             //Meridian setting
  608.             PORTD ^= 0b01000000;    //Toggle AM/PM LED
  609.         }
  610.     }          
  611.  
  612.     //Alarm Setting
  613.     if(alarmSetting) {
  614.         if(!hoursSet && !minutesSet) {  //Set Hours or Minutes
  615.             min = 0;
  616.             max = 11;
  617.         } else if((minutesSet) && !minuteResoSet) {
  618.             //Setting minute reso
  619.             min = 12;
  620.             max = 16;
  621.         } else if (minuteResoSet) { //Setting AM/PM
  622.             min = 0;
  623.             max = 0;
  624.             currentLedIndex = 0;
  625.             //Meridian setting
  626.             PORTD ^= 0b01000000;    //Toggle AM/PM LED
  627.         }
  628.     }
  629.  
  630.     //DATE SETTING
  631.     if(dateSetting) {
  632.         if(!yearSet) {  //Setting year
  633.             min = 0;
  634.             max = 11;
  635.         } else if(!yearResoSet) { //Setting year resolution
  636.             min = 12;
  637.             max = 16;
  638.         } else if (!monthSet) { //Setting of month         
  639.             min = 0;
  640.             max = 11;
  641.         } else if(!daySet) { //Setting of Day
  642.             if(month != 2) {    //Not February
  643.                 min = 0;
  644.                 max = 6;
  645.             } else {    //February - Allow setting of up to 25 days
  646.                 min = 0;
  647.                 max = 5;        //CHANGED
  648.             }
  649.         } else if(!dayResoSet) {    //Setting Day Resolution
  650.             if (month == 1 || month == 3 || month == 5 || month == 7 ||
  651.             month == 8 || month == 10 || month == 12) {
  652.                 //MONTHS with 31 days
  653.                 if(day == 30) { //Limit to first LED
  654.                     //31 Days
  655.                     min = 12;
  656.                     max = 16;
  657.                     skip = 13;  //Skip to this LED if at 16
  658.                 } else  { //All 4 middle LEDs accessible
  659.                     min = 12;
  660.                     max = 16;
  661.                 }
  662.             } else if (month == 4 || month == 6 || month == 9 || month == 11) {
  663.                 //MONTHS with 30 days
  664.                 if(day == 30) {
  665.                     currentLedIndex = 0;    //Don't allow any setting of resolution
  666.                     return;
  667.                 } if (day < 30) {   //Allow 4 LEDs accessible
  668.                     min = 12;
  669.                     max = 16;  
  670.                 }      
  671.             //FEBRUARY         
  672.             } else if (tempLeap) {  //Leap Year - February
  673.                     min = 12;
  674.                     max = 16;
  675.             } else {    //Not Leap Year - February
  676.                 if(day == 25) {
  677.                     //For 28 days
  678.                     min = 12;
  679.                     max = 16;
  680.                     skip = 15;  //Skip to if at max
  681.                 } else {
  682.                     //Allow 4 LEDs accessible (day <= 20)
  683.                     min = 12;
  684.                     max = 16;
  685.                 }
  686.             }
  687.         }
  688.     }
  689.  
  690.     //Check boundaries, else decrement
  691.     if (currentLedIndex == min) {
  692.         currentLedIndex = max;
  693.     } else {
  694.         //Decrement LED index
  695.         currentLedIndex--;
  696.         while ((skip != -1) && (currentLedIndex >= skip)) { //Skip to 'skip' value
  697.             currentLedIndex--;
  698.         }
  699.     }
  700. }
  701.  
  702. //If next button is pressed while in IR setting mode
  703. void next_button_pressed(void) {
  704.     int min = 0;
  705.     int max = 11;
  706.     int skip = -1;
  707.  
  708.     //If setting minutes resolution, 12 - 16 LED indexes
  709.     if(timeSetting) {
  710.         if(!minutesSet) {
  711.             min = 0;
  712.             max = 11;
  713.         } else if((minutesSet) && !minuteResoSet) {
  714.             //Setting minute reso
  715.             min = 12;
  716.             max = 16;
  717.         } else if (minuteResoSet) {
  718.             min = 0;
  719.             max = 0;
  720.             currentLedIndex = 0;
  721.             //Meridian setting
  722.             PORTD ^= 0b01000000;
  723.         }
  724.     }
  725.     //Alarm setting
  726.     if(alarmSetting) {
  727.         if(!hoursSet && !minutesSet) { //Setting hours or minutes
  728.             min = 0;
  729.             max = 11;
  730.         } else if(!minuteResoSet) { //Setting Minute resolution
  731.             min = 12;
  732.             max = 16;
  733.         } else if (minuteResoSet) { //Setting AM/PM
  734.             min = 0;
  735.             max = 0;
  736.             currentLedIndex = 0;
  737.             //Meridian setting
  738.             PORTD ^= 0b01000000;
  739.         }
  740.     }
  741.  
  742.     //Date setting mode
  743.     if(dateSetting) {
  744.         if(!yearSet) {  //Setting year
  745.             min = 0;
  746.             max = 11;
  747.         } else if(!yearResoSet) { //Setting year resolution
  748.             min = 12;
  749.             max = 16;
  750.         } else if (!monthSet) { //Setting months
  751.             min = 0;
  752.             max = 11;
  753.         }else if(!daySet) {
  754.             if(month != 2) {
  755.                 min = 0;
  756.                 max = 6;
  757.             } else {
  758.                 //February
  759.                 min = 0;
  760.                 max = 5;    //CHANGED  
  761.             }
  762.         } else if(!dayResoSet) {
  763.             if (month == 1 || month == 3 || month == 5 || month == 7 ||
  764.             month == 8 || month == 10 || month == 12) {
  765.                 if(day == 30) {
  766.                     //31 Days - only allow first 1 of 4 middle LEDs to select
  767.                     min = 12;
  768.                     max = 16;
  769.                     skip = 13;
  770.                 } else {
  771.                     //Allow all middle LEDs to be accessible
  772.                     min = 12;
  773.                     max = 16;
  774.                 }
  775.             } else if (month == 4 || month == 6 || month == 9 || month == 11) {
  776.                 if(day == 30) { //CHANGED
  777.                     //Don't allow setting of day resolution
  778.                     currentLedIndex = 0;
  779.                     return;
  780.                 } else if (day < 30) {
  781.                     //Allow access of all middle LEDs
  782.                     min = 12;
  783.                     max = 16;
  784.                 }
  785.             } else if (tempLeap) {
  786.                     //Leap year, 29 days (allow all 4 LEDs to be accessed)
  787.                     min = 12;
  788.                     max = 16;
  789.             } else {
  790.                 if(day == 25) {
  791.                     //For 28 days - allow 3 out of 4 LEDs to be accessed
  792.                     min = 12;
  793.                     max = 16;
  794.                     skip = 15;
  795.                 } else {
  796.                     //Allow all LEDs to be accessed ( <= 20 days)
  797.                     min = 12;
  798.                     max = 16;
  799.                 }          
  800.             }
  801.         }  
  802.     }
  803.  
  804.     //Check boundaries, else increment
  805.     if (currentLedIndex == max) { //If at maximum, put LED at start of bounds (min)
  806.         currentLedIndex = min;
  807.     } else {
  808.         //Increment ledIndex
  809.         currentLedIndex++;
  810.         if (currentLedIndex == skip) {  //If need to skip LEDs
  811.             currentLedIndex = max;
  812.         }
  813.     }
  814. }
  815.  
  816. //Setting mode for IR (when SET is sent for the first time)
  817. void setting_mode(void) {
  818.     currentLedIndex = 0;    //Display top middle LED
  819.     PORTB |= 0b00000001; //turn setting LED on
  820.     PORTD &= 0xBF;
  821.     clear_leds();   //Clear display LEDs
  822.     while(1) {
  823.         /* Turn off alarms */
  824.         PORTC &= 0b11111101;
  825.         alarmNow = 0;
  826.         buzzCount = 0;
  827.         buzzPrev = 0;
  828.  
  829.         PORTB = ledDemux[currentLedIndex] + settingMode + ENABLE; //Update PORTB (enable, setting LED and selected LED
  830.         if(!timeSetting) {
  831.             update_time();  //Still update the time if we're not setting the time
  832.             update_time_variables();    //Update time variables (seconds, minutes, hours etc.)
  833.         }
  834.         //Setting mode finished
  835.         if(!settingMode) {
  836.             PORTB &= 0b11111110; //turn setting LED off
  837.             specificSet = 0;
  838.             break;
  839.         }
  840.     }
  841. }
  842.  
  843.  
  844. //SET button pressed via infrared remote, while in IR setting mode (settingMode == 1)
  845. void enter_button_pressed(void) {
  846.     //The SET button is pressed to 'enter' or 'select' a value
  847.     if (timeSetting) {
  848.         set_time();
  849.     }  
  850.    
  851.     if (alarmSetting) {
  852.         set_alarm();
  853.     }
  854.  
  855.     if (dateSetting) {
  856.         set_date();
  857.     }
  858.    
  859. }
  860.  
  861. //DATE setting for Infrared Remote
  862. void set_date(void) {
  863.     if(!yearSet) {
  864.         year = 2000 + currentLedIndex * 5;  //Increment 2000  by value of selected LED and set year
  865.         yearSet = 1;
  866.         currentLedIndex = 16;
  867.     } else if (!yearResoSet) {
  868.         //If year resolution is not 0, increment minutes accordingly
  869.         if (currentLedIndex != 0  && currentLedIndex != 16) {
  870.             year += (currentLedIndex - 11); //Increment year by value of selected LED
  871.         }
  872.         if ((year % 4) == 0) {  //Leap year ?
  873.             tempLeap = 1;
  874.         }
  875.         yearResoSet = 1;
  876.         currentLedIndex = 1;
  877.     } else if (!monthSet) { //Setting months
  878.         if(currentLedIndex) { //If not on topMiddle LED (12th month)
  879.             month = currentLedIndex;
  880.         } else {
  881.             month = 12;
  882.         }      
  883.         monthSet = 1;
  884.         currentLedIndex = 0;
  885.     } else if (!daySet) {   //Setting days
  886.         day = 5 * currentLedIndex; //Set day to value of selected LED
  887.         daySet = 1;
  888.         currentLedIndex = 16;
  889.     } else {
  890.         if (currentLedIndex != 0  && currentLedIndex != 16) {   //If not LED value of '0'
  891.             day += (currentLedIndex - 11); //Increment days by value of selected LED
  892.         }
  893.         currentLedIndex = 0;
  894.         tempLeap = 0;
  895.         daySet = 0;
  896.         yearSet = 0;
  897.         monthSet = 0;
  898.         yearResoSet = 0;
  899.         specificSet = 0;
  900.         dateSetting = 0;
  901.         settingMode = 0;
  902.     }      
  903. }
  904.  
  905. //TIME setting for Infrared remote
  906. void set_time(void) {
  907.     if(!hoursSet) { //Set hours
  908.         changeHours = currentLedIndex;  //Set hours to selected LED value
  909.         hoursSet = 1;
  910.         currentLedIndex = 0;
  911.     } else if(!minutesSet) { //Set Minutes
  912.         if(currentLedIndex > 0) {
  913.             changeMinutes = 5 * currentLedIndex;    //Set minutes to selected LED value
  914.         } else if (currentLedIndex == 0) {
  915.             //On 12 location
  916.             changeMinutes = 0;
  917.         }
  918.         minutesSet = 1;
  919.         currentLedIndex = 16;
  920.     } else if(!minuteResoSet){  //Setting minute resolution
  921.         //If minute resolution is not 0, increment minutes accordingly
  922.         if (currentLedIndex != 0  && currentLedIndex != 16) { //If not LED value of '0'
  923.             changeMinutes += (currentLedIndex - 11);    //Increment minutes by resolution (20 + 1 (reso) = 21 minutes)
  924.         }
  925.         minuteResoSet = 1;
  926.         currentLedIndex = 0;
  927.     } else {
  928.         //Set ampm
  929.         if((PORTD & 0b01000000) == 0b01000000) {    //Take AM/PM value based whether AM/PM LED on
  930.             changeAmpm = 1; //pm
  931.         } else {
  932.             changeAmpm = 0; //am
  933.         }
  934.         //Reset all varaibles
  935.         changeSeconds = 0;  
  936.         tempLeap = 0;
  937.         settingMode = 0;
  938.         hoursSet = 0;
  939.         minutesSet = 0;
  940.         minuteResoSet = 0;
  941.         specificSet = 0;
  942.         currentLedIndex = 0;
  943.         timeSetting = 0;
  944.         set_rtc_time();
  945.     }  
  946.    
  947.        
  948. }
  949.  
  950. /* SETTING ALARMS for Infrared Remote
  951.  (NOTE, only temporary variables are set, not time variables (hours, minutes etc.)
  952.  add_current_alarm(void) then takes these values and adds the actual alarm
  953. */
  954. void set_alarm(void) {
  955.     if(!hoursSet) { //Setting hours
  956.         tempHours = currentLedIndex;    //Set tempHours to value of selected LED
  957.         hoursSet = 1;
  958.         currentLedIndex = 0;
  959.     } else if(!minutesSet) { //Set Minutes
  960.         if(currentLedIndex > 0) {
  961.             tempMinutes = 5 * currentLedIndex ; //Set tempMnutes to value of selected LED
  962.         } else if (currentLedIndex == 0) {
  963.             //On 12 location
  964.             tempMinutes = 0;
  965.         }
  966.         minutesSet = 1;
  967.         currentLedIndex = 16;
  968.     } else if(!minuteResoSet){  //Setting minute resolution
  969.         //If minute resolution is not 0, increment minutes accordingly
  970.         if (currentLedIndex != 0  && currentLedIndex != 16) { //If not LED value of '0'
  971.             tempMinutes += (currentLedIndex - 11);  //Increment tempMinutes by value of selected LED
  972.         }
  973.         minuteResoSet = 1;
  974.         currentLedIndex = 0;
  975.     } else {
  976.         //Set ampm
  977.         if((PORTD & 0b01000000) == 0b01000000) {    //AM/PM depending on whether AM/PM light on
  978.             tempMeridian = 1;
  979.         } else {
  980.             tempMeridian = 0;
  981.         }
  982.         add_current_alarm();    //Add alarms with 'temp' variable values
  983.         tempHours = 0;
  984.         tempMinutes = 0;
  985.         tempMeridian = 0;
  986.         settingMode = 0;
  987.         hoursSet = 0;
  988.         minutesSet = 0;
  989.         minuteResoSet = 0;
  990.         specificSet = 0;
  991.         currentLedIndex = 0;
  992.         alarmSetting = 0;
  993.     }  
  994. }
  995.  
  996. //Checks to see if there is an alarm that needs to be triggered
  997. void check_for_alarm(void) {
  998.     int alarmValue = (minutes*60) + (hours * 60 * 60); //Alarms stored as seconds
  999.     int found = 0; //Whether an alarm has been found
  1000.    
  1001.     //Iterate through the alarm array
  1002.     for(int i = 0; i < 10; i++ ) {
  1003.         //if alarm is now
  1004.         if((alarms[i] == alarmValue) && (alarmMeridians[i] == ampm)) {
  1005.             found = 1;
  1006.             alarms[i] = -1; //reset that alarm
  1007.             alarmMeridians[i] = -1;
  1008.             alarmNow = 1;   //Is there an alarm that should be on now
  1009.             buzzPrev = seconds;
  1010.             buzzCount = 3; //turn on buzzer for 3 seconds
  1011.             break;
  1012.         }
  1013.     }
  1014.     //Remove any other alarms at the same time
  1015.     if(found) {
  1016.         for(int i = 0; i < 10; i++ ) {
  1017.             if((alarms[i] == alarmValue) && (alarmMeridians[i] == ampm)) {
  1018.                 alarms[i] = -1;
  1019.                 alarmMeridians[i] = -1;
  1020.             }
  1021.         }
  1022.     }
  1023. }
  1024.  
  1025. //Adds the alarm currently stored in global variables
  1026. void add_current_alarm(void) {
  1027.     int alarmValue = (tempMinutes*60) + (tempHours* 60 * 60); //Alarm in seconds
  1028.     for(int i = 0; i < 10; i++) {
  1029.         //Find first free alarm slot and store alarm
  1030.         if(alarms[i] == -1) {
  1031.             alarms[i] = alarmValue;
  1032.             alarmMeridians[i] = tempMeridian;
  1033.             break;
  1034.         }
  1035.     }
  1036. }
  1037.  
  1038. //Clear the ledsOn array
  1039. void clear_leds(void) {
  1040.     for(int i = 0; i < 8; i++) {
  1041.         ledsOn[i] = -1;
  1042.     }
  1043. }
  1044.  
  1045. //Get the command currently stored in irArray and return as a 8bit char
  1046. char get_command(void) {
  1047.     char temp = 0;
  1048.     for (int i = 0; i < 8; i++) {
  1049.         temp |= (irArray[i] << (7-i));
  1050.     }
  1051.     return temp;
  1052. }
  1053.  
  1054. //Checks to see if the Optical clock pin has changed since the last read
  1055. void check_clock(void) {
  1056.     //If clock has been in optical setting mode for more than 25 seconds, reset clock
  1057.     if ((adcSettingStart != -1) && (seconds == ((adcSettingStart + 29) % 60))) {
  1058.         reset_clock();
  1059.         adcSettingMode = 0;
  1060.         specificSet = 0;
  1061.         weatherSetting = 0;
  1062.         timeSetting = 0;
  1063.         dateSetting = 0;
  1064.         alarmSetting = 0;
  1065.         adcSettingStart = -1;
  1066.     }
  1067.     //If value in ADC register is >675 it is a logical 0, else 1
  1068.     if (ADC > 675) {
  1069.         currentADC = 0;
  1070.     } else {
  1071.         currentADC = 1;
  1072.     }
  1073.     //If changed since last read
  1074.     if (currentADC != oldADC) {  
  1075.         oldADC = currentADC; //Update varaible
  1076.         adcDelay = 0; //Start delay until next read
  1077.         if (adcCount == 0) {
  1078.             adcCommandStart = seconds;
  1079.         }
  1080.         read_data();
  1081.     }  
  1082. }
  1083.  
  1084. //Reads data off Optical data pin
  1085. void read_data(void) {
  1086.     //Change ADC multiplexer register
  1087.     ADMUX = 0x42;
  1088.     //Complete previous read
  1089.     while ((ADCSRA & 0x40) != 0x00);
  1090.     //Start read with new multiplexer value
  1091.     ADCSRA |= 0x40;
  1092.     //Wait for that read to complete
  1093.     while ((ADCSRA & 0x40) != 0x00);
  1094.     if (ADC > 675) { //Store result in adcArray
  1095.         adcArray[adcCount] = 0;
  1096.     } else {
  1097.         adcArray[adcCount] = 1;
  1098.     }
  1099.     if (adcCount < 8) {
  1100.         adcCount++;
  1101.     }
  1102.     //If full command recieved
  1103.     if (adcCount == 8) {
  1104.         //If set command while not in setting mode
  1105.         if(!adcSettingMode && (get_adc() == SETTING_BTN)) {        
  1106.             //If not in IR setting mode
  1107.             if(!settingMode) {
  1108.                 adcSettingMode = 1; //Optical Setting
  1109.                 adcSettingStart = seconds; //Start counting the 25 seconds
  1110.             }          
  1111.         } else if (adcSettingMode) {
  1112.             deal_with_adc(); //Process command
  1113.         }
  1114.         adcCount = 0; //Reset the array
  1115.         clear_adc();
  1116.         adcCommandStart = -1; //Clear timeout counter
  1117.     }
  1118.     while ((ADCSRA & 0x40) != 0x00); //Complete current Read
  1119.     ADMUX = 0x40; //Change register back
  1120.     ADCSRA |= 0x40;
  1121.     while ((ADCSRA & 0x40) != 0x00); //Wait for another read
  1122. }
  1123.  
  1124. //Clears AdcArray
  1125. void clear_adc(void) {
  1126.     for (int i = 0; i < 8; i++) {
  1127.         adcArray[i] = -1;
  1128.     }
  1129.     adcCount = 0;
  1130. }
  1131.  
  1132. // Setting mode for the GUI data transfer, (when first SET signal is received)
  1133. void adc_setting_mode(void) {
  1134.     //TODO: Turn on Setting LED
  1135.     while(1) {
  1136.         /* Turn off alarms */
  1137.         PORTC &= 0b11111101;
  1138.         alarmNow = 0;
  1139.         buzzCount = 0;
  1140.         buzzPrev = 0;
  1141.  
  1142.         PORTB = ledDemux[0] + ENABLE;   //Put top middle LED on whilst setting ADC
  1143.         PORTB |= 0x01;
  1144.         PORTD &= 0xBF;
  1145.  
  1146.         if (((ADCSRA & 0x40) == 0) && (adcDelay == -1)) { //Whilst still converting ADC
  1147.             ADCSRA |= 0x40;
  1148.             while ((ADCSRA & 0x40) != 0x00);
  1149.             check_clock();  //Check if the clock has changed
  1150.         }
  1151.         //Still update time whilst in setting mode
  1152.         update_time();
  1153.         update_time_variables();       
  1154.  
  1155.         if(!adcSettingMode) {
  1156.             break;
  1157.         }
  1158.     }
  1159. }
  1160.  
  1161. //When a signal is received whilst in GUI data transfer setting mode (adcSetting == 1)
  1162. void deal_with_adc(void) {
  1163.     //Deal with current command in IR Array
  1164.     if(get_adc() == SETTING_BTN) {
  1165.         adc_set();      //NOTE: This uses the value of the PREVIOUS signal for adcNum
  1166.     }
  1167.  
  1168.     //Determine the signal received from GUI
  1169.     int adc1 = 128 - get_adc();
  1170.     int adc2 = 64 - get_adc();
  1171.     if ((adc1 > 0) && (adc1 < 33)) {
  1172.         adcNum = adc1;
  1173.     } else if ((adc2 > 30) && (adc2 < 61)) {
  1174.         if (adc2 == 60) {
  1175.             adcNum = 0;
  1176.         } else {
  1177.             adcNum = adc2;
  1178.         }
  1179.     } else if ((get_adc() > -1) && (get_adc() < 3)) {
  1180.         adcNum = get_adc();
  1181.     }
  1182.  
  1183.  
  1184.     //Specific Setting Modes (TIME, ALARM, DATE, WEATHER)
  1185.     if(!specificSet) {
  1186.         if(get_adc() == TIME_BTN) {
  1187.             timeSetting = 1;
  1188.             specificSet = 1;
  1189.         } else if (get_adc() == ALARM_BTN) {
  1190.             alarmSetting = 1;
  1191.             specificSet = 1;
  1192.         } else if(get_adc() == DATE_BTN) {
  1193.             dateSetting = 1;
  1194.             specificSet = 1;
  1195.         } else if(get_adc() == WEATHER_SET) {
  1196.             weatherSetting = 1;
  1197.             specificSet = 1;
  1198.         }
  1199.        
  1200.     }
  1201.     clear_adc();
  1202.     adcCommandStart = -1;
  1203. }
  1204.  
  1205. //SET signal received from GUI, while in adcSetting mode
  1206. void adc_set(void) {
  1207.     //The SET signal is received from GUI (via adc) whilst in setting mode
  1208.     if(timeSetting) {
  1209.         adc_set_time();
  1210.     }
  1211.  
  1212.     if(alarmSetting) {
  1213.         adc_set_alarm();
  1214.     }
  1215.    
  1216.     if(dateSetting) {
  1217.         adc_set_date();
  1218.     }
  1219.  
  1220.     if(weatherSetting) {
  1221.         adc_weather_set();
  1222.     }
  1223. }
  1224.  
  1225.  
  1226. //GUI Data Transfer - WEATHER SETTING
  1227. void adc_weather_set(void) {
  1228.     if(adcNum == 2) {
  1229.         //FINE
  1230.         weatherType = 0;
  1231.     } else if (adcNum == 1) {
  1232.         //CLOUDY
  1233.         weatherType = 2;
  1234.     } else if (adcNum == 0) {
  1235.         //RAINY
  1236.         weatherType = 1;
  1237.     }
  1238.     //Finish setting mode since only one signal needed
  1239.     weatherSetting = 0;
  1240.     weatherDisplayChange = seconds;
  1241.     displayMode = 2;
  1242.     adcSettingMode = 0;
  1243.     specificSet = 0;
  1244.     adcSettingStart = -1;
  1245.  
  1246. }
  1247.  
  1248.  
  1249. //GUI Data Transfer - DATE SETTING
  1250. void adc_set_date(void) {
  1251.     if(!yearSet) {  //Set years
  1252.         adcYear = 2000 + adcNum; //Set year to that of the read value from GUI
  1253.         yearSet = 1;
  1254.     } else if (!monthSet) { //Set month to that of the read value from GUI
  1255.         adcMonth = adcNum;
  1256.         monthSet = 1;
  1257.     } else { //Set day and finished setting mode
  1258.         day = adcNum;
  1259.         year = adcYear;
  1260.         month = adcMonth;
  1261.         yearSet = 0;
  1262.         monthSet = 0;
  1263.         specificSet = 0;
  1264.         adcSettingMode = 0;
  1265.         dateSetting = 0;
  1266.         adcSettingStart = -1;
  1267.     }
  1268. }
  1269.  
  1270. //GUI Data Transfer - TIME SETTING
  1271. void adc_set_time(void) {
  1272.     //NOTE: adcNum is the value of the previous signal (before SET was sent)
  1273.     if(!hoursSet) { //Set hours in 24 hours
  1274.         if((adcNum - 12) >= 0) { //In 24 hour time - meaning greater than 12 is PM
  1275.             //PM
  1276.             adcHours = adcNum - 12;
  1277.             adcAmpm = 1;   
  1278.         } else {
  1279.             //AM
  1280.             adcHours = adcNum;
  1281.             adcAmpm = 0;
  1282.         }          
  1283.         hoursSet = 1;
  1284.     } else { //Set minutes and finish setting mode
  1285.         adcMinutes = adcNum;
  1286.         changeHours = adcHours;
  1287.         adcHours = 0;
  1288.         hoursSet = 0;
  1289.        
  1290.         changeMinutes = adcMinutes;
  1291.         adcMinutes = 0;
  1292.        
  1293.         changeAmpm = adcAmpm;
  1294.         adcAmpm = 0;
  1295.        
  1296.         changeSeconds = 0;
  1297.  
  1298.         timeSetting = 0;
  1299.         specificSet = 0;
  1300.         adcSettingMode = 0;
  1301.         adcSettingStart = -1;
  1302.         set_rtc_time();
  1303.     }
  1304.        
  1305. }
  1306.  
  1307. //ALARM setting for GUI data transfer
  1308. void adc_set_alarm(void) {
  1309.     //NOTE: adcNum is the value of the previous signal (before SET was sent)
  1310.     if(!hoursSet) { //Setting hours
  1311.         if((adcNum - 12) >= 0) { //Since in 24-hour time, if greater than 12, PM
  1312.             //PM
  1313.             tempMeridian = 1;
  1314.             tempHours = adcNum - 12;
  1315.         } else {
  1316.             //AM
  1317.             tempMeridian = 0;
  1318.             tempHours = adcNum;
  1319.         }
  1320.         hoursSet = 1;
  1321.     } else { //Set minutes and finish setting mode
  1322.         tempMinutes = adcNum;
  1323.  
  1324.         add_current_alarm(); //Add alarm via use of 'temp' variables
  1325.        
  1326.         tempMinutes = 0;
  1327.         tempHours = 0;
  1328.         tempMeridian = 0;
  1329.         adcSettingMode = 0;
  1330.         hoursSet = 0;
  1331.         specificSet = 0;
  1332.         alarmSetting = 0;
  1333.         adcSettingStart = -1;  
  1334.     }  
  1335. }
  1336.  
  1337. //Returns an 8bit char representation of the array currently stored in adcArray
  1338. char get_adc(void) {
  1339.     char temp = 0;
  1340.     for (int i = 0; i < 8; i++) {
  1341.         temp |= (adcArray[i] << (7-i));
  1342.     }
  1343.     return temp;
  1344. }
  1345.  
  1346. //Updates time global variables
  1347. void update_time_variables(void) {
  1348.     //If seconds have changed from the last time
  1349.     if(seconds != oldSeconds) {
  1350.         //update vars
  1351.         oldSeconds = seconds;
  1352.         if ((seconds == 0) && (minutes == 0) && (hours == 0) && (ampm == 0)) { //update ampm and days
  1353.             day++;
  1354.         } //Update month
  1355.         if (month == 1 || month == 3 || month == 5 || month == 7 ||
  1356.         month == 8 || month == 10 || month == 12) {
  1357.             if (day == 32) {
  1358.                 month++;
  1359.                 day = 0;
  1360.             }
  1361.         } else if (month == 4 || month == 6 || month == 9 || month == 11) {
  1362.             if (day == 31) {
  1363.                 month++;
  1364.                 day = 0;
  1365.             }
  1366.         } else if ((year % 4) == 0) {
  1367.             if (day == 30) {
  1368.                 month++;
  1369.                 day = 0;
  1370.             }
  1371.         } else {
  1372.             if (day == 29) {
  1373.                 month++;
  1374.                 day = 0;
  1375.             }
  1376.         } //update year
  1377.         if (month == 13) {
  1378.             year++;
  1379.             month = 0;
  1380.         }
  1381.     }
  1382. }
  1383. //Resets the time variables in the event of an Optical timeout.
  1384. void reset_clock(void) {
  1385.     seconds = 0;
  1386.     minutes = 0;
  1387.     hours = 0;
  1388.     day = 1;
  1389.     month = 1;
  1390.     year = 2012;
  1391.     ampm = 0;
  1392. }
  1393.  
  1394.  
  1395.  
  1396. // Convert Decimal to Binary Coded Decimal (BCD)
  1397. char dec2bcd(char num) {
  1398.     return ((num/10 * 16) + (num % 10));
  1399. }
  1400.  
  1401. // Convert Binary Coded Decimal (BCD) to Decimal
  1402. char bcd2dec(char num) {
  1403.     return ((num/16 * 10) + (num % 16));
  1404. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top