Guest User

CLACK Program Final

a guest
Sep 27th, 2014
432
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //CLACK, by Gabriel Maria
  2. //You Only Live Forever
  3.  
  4. #include <DS1307RTC.h>
  5. #include <Time.h>
  6. #include <Wire.h>
  7. #include <EEPROM.h>
  8.  
  9. //-------------------------------------------PINS---------------------------------------------------------------------------------------------------------
  10. //only pins A0,A6, 0&1,13 are not used.
  11. int latchPin = A2;//ST_CP of 74HC595
  12. int clockPin = A3;//SH_CP of 74HC595
  13. int dataPin  = A1;//DS of 74HC595
  14. int ONE      = 8;   //Numeric indicator parallel inputs  v
  15. int TWO      = 10;
  16. int FOUR     = 11;
  17. int EIGHT    = 9;
  18. int DP       = 12;
  19. int UPpin    = 2;  //buttons  v
  20. int DOWNpin  = 5;
  21. int LEFTpin  = 3;
  22. int RIGHTpin = 6;
  23. int ENTERpin = 4;
  24. int SQWpin   = 7; //DS3231 1hz square coming in
  25. int PWMpin   = 13; //Piezo speaker
  26. //--------------------------------------------arrays--------------------------------------------------------------------------------------------------------
  27. /////////////0,1,2,3,4,5,6,7,8,9   t,_,_,-,_,_
  28. boolean o[]={0,1,0,1,0,1,0,1,0,1,  0,1,0,1,0,1}; //one
  29. boolean t[]={0,0,1,1,0,0,1,1,0,0,  1,1,0,0,1,1}; //two
  30. boolean f[]={0,0,0,0,1,1,1,1,0,0,  0,0,1,1,1,1}; //four
  31. boolean e[]={0,0,0,0,0,0,0,0,1,1,  1,1,1,1,1,1}; //eight
  32. //////////////////--0--,--1--,--2--,--3--,--4--,--5--,--6--,--7--,   --8--,--9--,--10-,--11-,--12-,--13-,--14-,--15-
  33. int Displays[] = {65407,65471,65503,65519,65527,65531,65533,65534,   32767,49151,57343,61439,63487,64511,65023,65279}; //the numbers that give a 16bit binary number with only one LOW bit
  34. //-------------------    Y,    M,   D,   H,   m,   S
  35. int  fullTime[6]  = { 2008,    1,   1,   0,   0,   0};
  36. int  alarm[4][6]  = {  { 2000,    1,   1,   0,   0,   0}, { 2000,    1,   1,   0,   0,   0}, { 2000,    1,   1,   0,   0,   0}, { 2000,    1,   1,   0,   0,   0}  };
  37. int  compiledTime[6];
  38. //---------------------- Y,Y,Y,Y,M,M,D,D,H,H,m,m,S,S,s,s
  39. byte   dispTime[14]    = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  40. byte dispAlarm[4][16]  = { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } ;
  41. //--------------------0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  42. byte  places[16]   = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11 };
  43. byte Decimals[16]  = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 };
  44. byte timeDecimals[16]  = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 };
  45. byte noDecimals[16]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  46. byte  error[16]    = { 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 };
  47. byte  success[16]  = { 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 };      
  48. boolean buttons[5] = {1,1,1,1,1}; //buttons are pulled up, so 1=off
  49. int Year; int Month; int Day; int Hour; int Minute; int Second;
  50.  
  51. //------------------------------------------other----------------------------------------------------------------------------------------------------------
  52. int UPcount = 0; int DOWNcount = 0; int LEFTcount = 0; int RIGHTcount = 0; int ENTERcount = 0;
  53. boolean CENTRUN = true;
  54. int cents = 0;
  55. boolean SQW = 1;
  56. boolean SQWLast = 0;
  57. boolean alarmSound = 0;
  58. boolean buzzToggle = 0;
  59.  
  60. byte MODE = 0;
  61. byte PART = 0;
  62. byte PLACE = 9;
  63.  
  64. tmElements_t tm; //with this DS3231 library, the values are placed into an object which are accessed like "tm.Hour"
  65.  
  66. void setup() {
  67.   Serial.begin(9600);
  68.  
  69.   pinMode(UPpin, INPUT_PULLUP);
  70.   pinMode(DOWNpin, INPUT_PULLUP);
  71.   pinMode(LEFTpin, INPUT_PULLUP);
  72.   pinMode(RIGHTpin, INPUT_PULLUP);
  73.   pinMode(ENTERpin, INPUT_PULLUP);
  74.   pinMode(SQWpin, INPUT_PULLUP);
  75.   pinMode(latchPin, OUTPUT);
  76.   pinMode(clockPin, OUTPUT);
  77.   pinMode(dataPin, OUTPUT);
  78.   pinMode(ONE, OUTPUT);
  79.   pinMode(TWO, OUTPUT);
  80.   pinMode(FOUR, OUTPUT);
  81.   pinMode(EIGHT, OUTPUT);
  82.   pinMode(DP, OUTPUT);
  83.  
  84.   //----------set control register to output a square wave to pin 2 at 1Hz
  85.   Wire.begin();
  86.   //setup square wave choice of 0=1Hz/8=1024Hz/16=4096Hz/24=8192Hz
  87.   Wire.beginTransmission(104);
  88.   //select control register
  89.   Wire.write(0x0e);//one of the scaler registers on the DS3231
  90.   Wire.write(0);//set square wave @ 1 Hz
  91.   Wire.endTransmission();
  92.  
  93.   blankall();
  94.   MainTime();
  95.   delay(200);
  96.  
  97.   MODE = 0;
  98.  
  99.   }
  100.  
  101.  
  102. void loop() {
  103.   Buttons();
  104.   Alarm();
  105.   Control();
  106.   if(MODE == 0){CLACK();}
  107.   if(MODE == 1){SETCLACK();}
  108.   if(MODE == 2){SHOWALARM(0);}
  109.   if(MODE == 3){SHOWALARM(1);}
  110.   if(MODE == 4){SHOWALARM(2);}
  111.   if(MODE == 5){SHOWALARM(3);}
  112.   if(MODE == 6){SETALARM(0);}
  113.   if(MODE == 7){SETALARM(1);}
  114.   if(MODE == 8){SETALARM(2);}
  115.   if(MODE == 9){SETALARM(3);}    
  116. }
  117.  
  118.  
  119. void Buttons(){
  120.   buttons[0] = digitalRead(UPpin);
  121.   buttons[1] = digitalRead(DOWNpin);
  122.   buttons[2] = digitalRead(LEFTpin);
  123.   buttons[3] = digitalRead(RIGHTpin);
  124.   buttons[4] = digitalRead(ENTERpin);
  125.  
  126.   if(buttons[0] == 0){UPcount++;}    else{UPcount = 0;}
  127.   if(buttons[1] == 0){DOWNcount++;}  else{DOWNcount = 0;}
  128.   if(buttons[2] == 0){LEFTcount++;}  else{LEFTcount = 0;}
  129.   if(buttons[3] == 0){RIGHTcount++;} else{RIGHTcount = 0;}
  130.   if(buttons[4] == 0){ENTERcount++;} else{ENTERcount = 0;}
  131. }
  132. void Alarm(){
  133.     boolean alarmCheck[4] = {1,1,1,1}; //all alarms are triggered until proven not
  134.     byte address = 0;
  135.    
  136.     //the trial
  137.     for(int a = 0; a <= 4; a++){
  138.        
  139.         if(a == 0){address = 0;}
  140.         if(a == 1){address = 16;}
  141.         if(a == 2){address = 32;}
  142.         if(a == 3){address = 48;}
  143.            
  144.         for(int b = 0; b <= 13; b++){
  145.             if( (EEPROM.read(address + b)) == 13 ){} //don't flag if "-"
  146.             else if((EEPROM.read(address + b)) != dispTime[b]){alarmCheck[a] = false; break;} //flag alarm "a", if anything misses, were done here, break
  147.         }
  148.     }      
  149.     if(alarmCheck[0] || alarmCheck[1] || alarmCheck[2] || alarmCheck[3]){alarmSound = true;} //if any alarms make it though, alarm.
  150.     if(alarmSound && SQW) {tone(PWMpin,2000);} else {noTone(PWMpin);}
  151.        
  152.  
  153. }
  154. void Control(){//-------------dealing with buttons based on MODE---------
  155.    
  156.   if((ENTERcount == 10)&&(alarmSound)){alarmSound = 0;}//turn off alarm if enter is pressed
  157.  
  158.   if(MODE == 0){
  159.     if(ENTERcount > 400){
  160.         MODE = 1; PART = 1;
  161.     }
  162.     else if(UPcount > 10)   {MODE = 2;}
  163.     else if(DOWNcount > 10) {MODE = 4;}
  164.     else if(LEFTcount > 10) {MODE = 5;}
  165.     else if(RIGHTcount > 10){MODE = 3;}
  166.     else                    {MODE = 0; PART = 1;}
  167.    
  168.   }
  169.   else if(MODE == 1){
  170.         if(LEFTcount == 5){movePLACE(1);}
  171.         if(RIGHTcount == 5){movePLACE(0);}
  172.         if(UPcount == 5){incPLACEtime(1);}
  173.         if(DOWNcount == 5){incPLACEtime(0);}
  174.         if(ENTERcount == 5){PART = 3;}
  175.   }
  176.   else if(MODE == 2){
  177.         if(ENTERcount > 100){MODE = 6; PART = 1;}
  178.         if(UPcount == 0){MODE = 0;}
  179.   }
  180.   else if(MODE == 3){
  181.         if(ENTERcount > 100){MODE = 7; PART = 1;}
  182.         if(RIGHTcount == 0){MODE = 0;}
  183.   }
  184.   else if(MODE == 4){
  185.         if(ENTERcount > 100){MODE = 8; PART = 1;}
  186.         if(DOWNcount == 0){MODE = 0;}
  187.   }
  188.   else if(MODE == 5){
  189.         if(ENTERcount > 100){MODE = 9; PART = 1;}
  190.         if(LEFTcount == 0){MODE = 0;}
  191.   }
  192.   else if(MODE == 6){
  193.         if(LEFTcount == 5){movePLACE(1);}
  194.         if(RIGHTcount == 5){movePLACE(0);}
  195.         if(UPcount == 5){incPLACEalarm(1);}
  196.         if(DOWNcount == 5){incPLACEalarm(0);}
  197.         if(ENTERcount == 5){PART = 3;}    
  198.   }
  199.   else if(MODE == 7){
  200.         if(LEFTcount == 5){movePLACE(1);}
  201.         if(RIGHTcount == 5){movePLACE(0);}
  202.         if(UPcount == 5){incPLACEalarm(1);}
  203.         if(DOWNcount == 5){incPLACEalarm(0);}
  204.         if(ENTERcount == 5){PART = 3;}
  205.   }
  206.   else if(MODE == 8){
  207.         if(LEFTcount == 5){movePLACE(1);}
  208.         if(RIGHTcount == 5){movePLACE(0);}
  209.         if(UPcount == 5){incPLACEalarm(1);}
  210.         if(DOWNcount == 5){incPLACEalarm(0);}
  211.         if(ENTERcount == 5){PART = 3;}
  212.   }
  213.   else if(MODE == 9){
  214.         if(LEFTcount == 5){movePLACE(1);}
  215.         if(RIGHTcount == 5){movePLACE(0);}
  216.         if(UPcount == 5){incPLACEalarm(1);}
  217.         if(DOWNcount == 5){incPLACEalarm(0);}
  218.         if(ENTERcount == 5){PART = 3;}
  219.   }
  220.   else{}
  221.  
  222. }
  223.  
  224. //------Methods for the MODES---------------------------------------------------------------------
  225.  
  226. void CLACK(){
  227.    
  228.     if(CENTRUN){
  229.         cents++;
  230.         writeNumber(cents%10, Decimals[15], 15);
  231.         writeNumber((cents/10)%10, Decimals[14], 14);
  232.         if(cents == 99){CENTRUN = false;}
  233.         delayMicroseconds(9500);
  234.     }
  235.    
  236.     SQW = digitalRead(SQWpin);
  237.  
  238.     if((SQW == 1) && (SQWLast == 0)){      
  239.         digitalWrite(PWMpin,HIGH);
  240.         digitalWrite(PWMpin,LOW);
  241.         MainTime();
  242.         CENTRUN = true;
  243.         cents = 0;
  244.     }
  245.    
  246.     SQWLast = SQW;
  247. }
  248.  
  249. void MainTime(){
  250.     if (RTC.read(tm)) {   //the RTC is polled and its values placed into tm, also it returns true if it works
  251.         fullTime[0] = (tmYearToCalendar(tm.Year));
  252.         fullTime[1] = tm.Month;
  253.         fullTime[2] = tm.Day;
  254.         fullTime[3] = tm.Hour;
  255.         fullTime[4] = tm.Minute;
  256.         fullTime[5] = tm.Second;
  257.     }
  258.     displayTime();
  259.  
  260. }
  261.  
  262. void SETCLACK(){
  263.   switch (PART){
  264.     case 1:
  265.         for(byte y = 0; y <= 13; y++){places[y] = dispTime[y];}
  266.         setPLACE(9);
  267.         PART = 2;
  268.         break;
  269.     case 2:
  270.         displayIt(0, 15, places, Decimals);
  271.         break;
  272.     case 3:
  273.         if(compile(places)){
  274.             for(byte z = 0; z <= 6; z++){fullTime[z] = compiledTime[z];}
  275.             uploadTIME(fullTime[0],fullTime[1],fullTime[2],fullTime[3],fullTime[4],fullTime[5]);
  276.             displayIt(0, 15, success, noDecimals);
  277.             delay(500);
  278.             MODE = 0; PART = 0;
  279.             break;
  280.         }else{
  281.             displayIt(0, 15, error, noDecimals);
  282.             delay(1000);
  283.             MODE = 0; PART = 0;
  284.             break;
  285.         }
  286.   }  
  287. }
  288. void SHOWALARM(byte a){
  289.     byte address = 0;
  290.     if(a == 0){address = 0;}
  291.     if(a == 1){address = 16;}
  292.     if(a == 2){address = 32;}
  293.     if(a == 3){address = 48;}
  294.     byte tempArray[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11};
  295.     for(byte y = 0; y <= 13; y++){tempArray[y] = (EEPROM.read(address + y));}  
  296.     displayIt(0,15,tempArray,noDecimals);
  297. }
  298. void SETALARM(byte a){
  299.     byte address = 0;
  300.     if(a == 0){address = 0;}
  301.     if(a == 1){address = 16;}
  302.     if(a == 2){address = 32;}
  303.     if(a == 3){address = 48;}
  304.        
  305.     switch (PART){
  306.        
  307.         case 1:
  308.         for(byte y = 0; y <= 13; y++){places[y] = (EEPROM.read(address + y));}
  309.         setPLACE(9);
  310.         PART = 2;
  311.         break;
  312.        
  313.          
  314.         case 2:
  315.         displayIt(0, 15, places, Decimals);
  316.         break;
  317.        
  318.          
  319.         case 3:
  320.         displayIt(0, 15, success, noDecimals);
  321.         for(byte w = 0; w <= 13; w++){EEPROM.write((address + w), places[w]);}
  322.         MODE = 0; PART = 0;
  323.         break;
  324.        
  325.     }
  326.  
  327. }
  328.  
  329.  
  330.  
  331.  
  332. //-----------Methods for encoding and decoding--------------------------------------------------
  333.  
  334. void displayTime(){
  335.     Year = fullTime[0];
  336.     dispTime[3] = (Year % 10);
  337.     Year = (Year / 10);
  338.     dispTime[2] = (Year % 10);
  339.     Year = (Year / 10);
  340.     dispTime[1] = (Year % 10);
  341.     Year = (Year / 10);
  342.     dispTime[0] = (Year % 10);
  343.    
  344.     Month = fullTime[1];
  345.     dispTime[5] = (Month % 10);
  346.     Month = (Month / 10);
  347.     dispTime[4] = (Month % 10);
  348.    
  349.     Day = fullTime[2];
  350.     dispTime[7] = (Day % 10);
  351.     Day = (Day / 10);
  352.     dispTime[6] = (Day % 10);
  353.    
  354.     Hour = fullTime[3];
  355.     dispTime[9] = (Hour % 10);
  356.     Hour = (Hour / 10);
  357.     dispTime[8] = (Hour % 10);
  358.    
  359.     Minute = fullTime[4];
  360.     dispTime[11] = (Minute % 10);
  361.     Minute = (Minute / 10);
  362.     dispTime[10] = (Minute % 10);
  363.    
  364.     Second = fullTime[5];
  365.     dispTime[13] = (Second % 10);
  366.     Second = (Second / 10);
  367.     dispTime[12] = (Second % 10);
  368.    
  369.     //print the array from display 0-13, 14 & 15 are used by the centiseconds and are not apart of the main time display
  370.     displayIt(0,13,dispTime,timeDecimals);
  371. }
  372.  
  373. boolean compile(byte g[]){
  374.     boolean compileSUC = true;
  375.    
  376.     int tempYear = ( (g[0] * 1000) + (g[1] * 100) + (g[2] * 10) + (g[3])   );
  377.         if(tempYear > 2100){compileSUC = false;}
  378.         else{compiledTime[0] = tempYear;}
  379.     int tempMonth = ( (g[4] * 10)  + (g[5])  );
  380.         if(tempMonth > 12){compileSUC = false;}
  381.         else{compiledTime[1] = tempMonth;}
  382.     int tempDay = ( (g[6] * 10)  + (g[7])  );
  383.         if(tempDay > 31){compileSUC = false;}
  384.         else{compiledTime[2] = tempDay;}
  385.    int tempHour = ( (g[8] * 10)  + (g[9])  );
  386.         if(tempHour > 24){compileSUC = false;}
  387.         else{compiledTime[3] = tempHour;}
  388.    int tempMinute  = ( (g[10] * 10) + (g[11]) );
  389.          if(tempMinute > 59){compileSUC = false;}
  390.          else{compiledTime[4] = tempMinute;}
  391.    int tempSecond = ( (g[12] * 10) + (g[13]) );
  392.          if(tempSecond > 59){compileSUC = false;}
  393.          else{compiledTime[5] = tempSecond;}
  394.              
  395.              return compileSUC;
  396. }
  397. void uploadTIME(int YEAR, int MONTH, int DAY, int HOUR, int MINUTE, int SECOND){
  398.     //set a time into the "tmElements_t tm" object
  399.     tm.Year = (YEAR - 1970); //tm.Year is stored in years since 1970
  400.     tm.Month = MONTH;
  401.     tm.Day = DAY;
  402.     tm.Hour = HOUR;
  403.     tm.Minute = MINUTE;
  404.     tm.Second = SECOND;
  405.     RTC.write(tm);//to DS3231  
  406. }
  407.  
  408. //------------Methods for moving the cursor around and changing the numbers---------------
  409.  
  410. void setPLACE(byte a){
  411.   for(int h=0;h<=13;h++){Decimals[h] = 0;}
  412.   Decimals[a] = 1;
  413.   PLACE = a;
  414. }
  415. void movePLACE(boolean P){
  416.   if(P){                       // 1 = LEFT
  417.    
  418.     if(PLACE == 0){
  419.       setPLACE(13);
  420.     }else{
  421.       setPLACE((PLACE)-1);
  422.     }
  423.  
  424.     }else{                       // 0 = RIGHT
  425.    
  426.         if(PLACE == 13){
  427.             setPLACE(0);
  428.         }else{
  429.             setPLACE((PLACE)+1);
  430.         }
  431.    
  432.     }
  433. }
  434. void incPLACEalarm(boolean I){
  435.   if(I){                              // 1 = UP  
  436.                                        
  437.       if(places[PLACE] == 9){
  438.         places[PLACE] = 13;
  439.       }else if(places[PLACE] == 13){
  440.         places[PLACE] = 0;
  441.       }else{
  442.         places[PLACE] = ((places[PLACE]) + 1);
  443.       }  
  444.        
  445.   }else{                             // 0 = DOWN
  446.                                    
  447.       if(places[PLACE] == 0){
  448.         places[PLACE] = 13;
  449.       }else if(places[PLACE] == 13){
  450.         places[PLACE] = 9;
  451.       }else{  
  452.       places[PLACE] = ((places[PLACE]) - 1);
  453.       }
  454.      
  455.   }
  456. }
  457. void incPLACEtime(boolean I){
  458.   if(I){                              // 1 = UP  
  459.                                        
  460.       if(places[PLACE] == 9){
  461.         places[PLACE] = 0;
  462.       }else{
  463.         places[PLACE] = ((places[PLACE]) + 1);
  464.       }  
  465.        
  466.   }else{                             // 0 = DOWN
  467.                                    
  468.       if(places[PLACE] == 0){
  469.         places[PLACE] = 9;
  470.       }else{  
  471.       places[PLACE] = ((places[PLACE]) - 1);
  472.       }
  473.      
  474.   }
  475. }
  476.  
  477.  
  478.  
  479.  
  480. //-------Methods for controlling the displays though shift registers----------------------
  481.  
  482. void displayIt(byte a, byte b,byte p[],byte D[]){
  483.   for(int m = a; m <= b; m++){ writeNumber(p[m], D[m], m); }
  484. }
  485. void blankall(){
  486.  digitalWrite(ONE, o[11]);
  487.  digitalWrite(TWO, t[11]);
  488.  digitalWrite(FOUR, f[11]);
  489.  digitalWrite(EIGHT, e[11]);
  490.  Shift(0);//all displays enabled for blanking
  491. }
  492. void blank(int a){
  493.  digitalWrite(ONE, o[11]);
  494.  digitalWrite(TWO, t[11]);
  495.  digitalWrite(FOUR, f[11]);
  496.  digitalWrite(EIGHT, e[11]);
  497.   Shift(Displays[a]);
  498. }
  499. void writeNumber(int a, int dp,int disp){
  500.  selectAndShift(disp);
  501.  if(dp == 1){digitalWrite(DP, LOW);}
  502.  else if(dp == 0){digitalWrite(DP, HIGH);}
  503.  digitalWrite(ONE, o[a]);
  504.  digitalWrite(TWO, t[a]);
  505.  digitalWrite(FOUR, f[a]);
  506.  digitalWrite(EIGHT, e[a]);
  507. }
  508. void selectAndShift(int displayNum){
  509.   digitalWrite(latchPin, LOW);
  510.   shiftOut(dataPin, clockPin, MSBFIRST, highByte(Displays[displayNum]));
  511.   shiftOut(dataPin, clockPin, MSBFIRST, lowByte(Displays[displayNum]));
  512.   digitalWrite(latchPin, HIGH);
  513.   digitalWrite(latchPin, LOW);
  514. }
  515. void Shift(int Num){
  516.   digitalWrite(latchPin, LOW);
  517.   shiftOut(dataPin, clockPin, MSBFIRST, highByte(Num));
  518.   shiftOut(dataPin, clockPin, MSBFIRST, lowByte(Num));
  519.   digitalWrite(latchPin, HIGH);
  520.   digitalWrite(latchPin, LOW);
  521. }
RAW Paste Data