Advertisement
Guest User

Untitled

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