Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //CLACK, by Gabriel Maria
- //You Only Live Forever
- #include <DS1307RTC.h>
- #include <Time.h>
- #include <Wire.h>
- #include <EEPROM.h>
- //-------------------------------------------PINS---------------------------------------------------------------------------------------------------------
- //only pins A0,A6, 0&1,13 are not used.
- int latchPin = A2;//ST_CP of 74HC595
- int clockPin = A3;//SH_CP of 74HC595
- int dataPin = A1;//DS of 74HC595
- int ONE = 8; //Numeric indicator parallel inputs v
- int TWO = 10;
- int FOUR = 11;
- int EIGHT = 9;
- int DP = 12;
- int UPpin = 2; //buttons v
- int DOWNpin = 5;
- int LEFTpin = 3;
- int RIGHTpin = 6;
- int ENTERpin = 4;
- int SQWpin = 7; //DS3231 1hz square coming in
- int PWMpin = 13; //Piezo speaker
- //--------------------------------------------arrays--------------------------------------------------------------------------------------------------------
- /////////////0,1,2,3,4,5,6,7,8,9 t,_,_,-,_,_
- boolean o[]={0,1,0,1,0,1,0,1,0,1, 0,1,0,1,0,1}; //one
- boolean t[]={0,0,1,1,0,0,1,1,0,0, 1,1,0,0,1,1}; //two
- boolean f[]={0,0,0,0,1,1,1,1,0,0, 0,0,1,1,1,1}; //four
- boolean e[]={0,0,0,0,0,0,0,0,1,1, 1,1,1,1,1,1}; //eight
- //////////////////--0--,--1--,--2--,--3--,--4--,--5--,--6--,--7--, --8--,--9--,--10-,--11-,--12-,--13-,--14-,--15-
- 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
- //------------------- Y, M, D, H, m, S
- int fullTime[6] = { 2008, 1, 1, 0, 0, 0};
- 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} };
- int compiledTime[6];
- //---------------------- Y,Y,Y,Y,M,M,D,D,H,H,m,m,S,S,s,s
- byte dispTime[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
- 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 } } ;
- //--------------------0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
- byte places[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11 };
- byte Decimals[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 };
- byte timeDecimals[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 };
- byte noDecimals[16]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
- byte error[16] = { 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 };
- byte success[16] = { 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 };
- boolean buttons[5] = {1,1,1,1,1}; //buttons are pulled up, so 1=off
- int Year; int Month; int Day; int Hour; int Minute; int Second;
- //------------------------------------------other----------------------------------------------------------------------------------------------------------
- int UPcount = 0; int DOWNcount = 0; int LEFTcount = 0; int RIGHTcount = 0; int ENTERcount = 0;
- boolean CENTRUN = true;
- int cents = 0;
- boolean SQW = 1;
- boolean SQWLast = 0;
- boolean alarmSound = 0;
- boolean buzzToggle = 0;
- byte MODE = 0;
- byte PART = 0;
- byte PLACE = 9;
- tmElements_t tm; //with this DS3231 library, the values are placed into an object which are accessed like "tm.Hour"
- void setup() {
- Serial.begin(9600);
- pinMode(UPpin, INPUT_PULLUP);
- pinMode(DOWNpin, INPUT_PULLUP);
- pinMode(LEFTpin, INPUT_PULLUP);
- pinMode(RIGHTpin, INPUT_PULLUP);
- pinMode(ENTERpin, INPUT_PULLUP);
- pinMode(SQWpin, INPUT_PULLUP);
- pinMode(latchPin, OUTPUT);
- pinMode(clockPin, OUTPUT);
- pinMode(dataPin, OUTPUT);
- pinMode(ONE, OUTPUT);
- pinMode(TWO, OUTPUT);
- pinMode(FOUR, OUTPUT);
- pinMode(EIGHT, OUTPUT);
- pinMode(DP, OUTPUT);
- //----------set control register to output a square wave to pin 2 at 1Hz
- Wire.begin();
- //setup square wave choice of 0=1Hz/8=1024Hz/16=4096Hz/24=8192Hz
- Wire.beginTransmission(104);
- //select control register
- Wire.write(0x0e);//one of the scaler registers on the DS3231
- Wire.write(0);//set square wave @ 1 Hz
- Wire.endTransmission();
- blankall();
- MainTime();
- delay(200);
- MODE = 0;
- }
- void loop() {
- Buttons();
- Alarm();
- Control();
- if(MODE == 0){CLACK();}
- if(MODE == 1){SETCLACK();}
- if(MODE == 2){SHOWALARM(0);}
- if(MODE == 3){SHOWALARM(1);}
- if(MODE == 4){SHOWALARM(2);}
- if(MODE == 5){SHOWALARM(3);}
- if(MODE == 6){SETALARM(0);}
- if(MODE == 7){SETALARM(1);}
- if(MODE == 8){SETALARM(2);}
- if(MODE == 9){SETALARM(3);}
- }
- void Buttons(){
- buttons[0] = digitalRead(UPpin);
- buttons[1] = digitalRead(DOWNpin);
- buttons[2] = digitalRead(LEFTpin);
- buttons[3] = digitalRead(RIGHTpin);
- buttons[4] = digitalRead(ENTERpin);
- if(buttons[0] == 0){UPcount++;} else{UPcount = 0;}
- if(buttons[1] == 0){DOWNcount++;} else{DOWNcount = 0;}
- if(buttons[2] == 0){LEFTcount++;} else{LEFTcount = 0;}
- if(buttons[3] == 0){RIGHTcount++;} else{RIGHTcount = 0;}
- if(buttons[4] == 0){ENTERcount++;} else{ENTERcount = 0;}
- }
- void Alarm(){
- boolean alarmCheck[4] = {1,1,1,1}; //all alarms are triggered until proven not
- byte address = 0;
- //the trial
- for(int a = 0; a <= 4; a++){
- if(a == 0){address = 0;}
- if(a == 1){address = 16;}
- if(a == 2){address = 32;}
- if(a == 3){address = 48;}
- for(int b = 0; b <= 13; b++){
- if( (EEPROM.read(address + b)) == 13 ){} //don't flag if "-"
- else if((EEPROM.read(address + b)) != dispTime[b]){alarmCheck[a] = false; break;} //flag alarm "a", if anything misses, were done here, break
- }
- }
- if(alarmCheck[0] || alarmCheck[1] || alarmCheck[2] || alarmCheck[3]){alarmSound = true;} //if any alarms make it though, alarm.
- if(alarmSound && SQW) {tone(PWMpin,2000);} else {noTone(PWMpin);}
- }
- void Control(){//-------------dealing with buttons based on MODE---------
- if((ENTERcount == 10)&&(alarmSound)){alarmSound = 0;}//turn off alarm if enter is pressed
- if(MODE == 0){
- if(ENTERcount > 400){
- MODE = 1; PART = 1;
- }
- else if(UPcount > 10) {MODE = 2;}
- else if(DOWNcount > 10) {MODE = 4;}
- else if(LEFTcount > 10) {MODE = 5;}
- else if(RIGHTcount > 10){MODE = 3;}
- else {MODE = 0; PART = 1;}
- }
- else if(MODE == 1){
- if(LEFTcount == 5){movePLACE(1);}
- if(RIGHTcount == 5){movePLACE(0);}
- if(UPcount == 5){incPLACEtime(1);}
- if(DOWNcount == 5){incPLACEtime(0);}
- if(ENTERcount == 5){PART = 3;}
- }
- else if(MODE == 2){
- if(ENTERcount > 100){MODE = 6; PART = 1;}
- if(UPcount == 0){MODE = 0;}
- }
- else if(MODE == 3){
- if(ENTERcount > 100){MODE = 7; PART = 1;}
- if(RIGHTcount == 0){MODE = 0;}
- }
- else if(MODE == 4){
- if(ENTERcount > 100){MODE = 8; PART = 1;}
- if(DOWNcount == 0){MODE = 0;}
- }
- else if(MODE == 5){
- if(ENTERcount > 100){MODE = 9; PART = 1;}
- if(LEFTcount == 0){MODE = 0;}
- }
- else if(MODE == 6){
- if(LEFTcount == 5){movePLACE(1);}
- if(RIGHTcount == 5){movePLACE(0);}
- if(UPcount == 5){incPLACEalarm(1);}
- if(DOWNcount == 5){incPLACEalarm(0);}
- if(ENTERcount == 5){PART = 3;}
- }
- else if(MODE == 7){
- if(LEFTcount == 5){movePLACE(1);}
- if(RIGHTcount == 5){movePLACE(0);}
- if(UPcount == 5){incPLACEalarm(1);}
- if(DOWNcount == 5){incPLACEalarm(0);}
- if(ENTERcount == 5){PART = 3;}
- }
- else if(MODE == 8){
- if(LEFTcount == 5){movePLACE(1);}
- if(RIGHTcount == 5){movePLACE(0);}
- if(UPcount == 5){incPLACEalarm(1);}
- if(DOWNcount == 5){incPLACEalarm(0);}
- if(ENTERcount == 5){PART = 3;}
- }
- else if(MODE == 9){
- if(LEFTcount == 5){movePLACE(1);}
- if(RIGHTcount == 5){movePLACE(0);}
- if(UPcount == 5){incPLACEalarm(1);}
- if(DOWNcount == 5){incPLACEalarm(0);}
- if(ENTERcount == 5){PART = 3;}
- }
- else{}
- }
- //------Methods for the MODES---------------------------------------------------------------------
- void CLACK(){
- if(CENTRUN){
- cents++;
- writeNumber(cents%10, Decimals[15], 15);
- writeNumber((cents/10)%10, Decimals[14], 14);
- if(cents == 99){CENTRUN = false;}
- delayMicroseconds(9500);
- }
- SQW = digitalRead(SQWpin);
- if((SQW == 1) && (SQWLast == 0)){
- digitalWrite(PWMpin,HIGH);
- digitalWrite(PWMpin,LOW);
- MainTime();
- CENTRUN = true;
- cents = 0;
- }
- SQWLast = SQW;
- }
- void MainTime(){
- if (RTC.read(tm)) { //the RTC is polled and its values placed into tm, also it returns true if it works
- fullTime[0] = (tmYearToCalendar(tm.Year));
- fullTime[1] = tm.Month;
- fullTime[2] = tm.Day;
- fullTime[3] = tm.Hour;
- fullTime[4] = tm.Minute;
- fullTime[5] = tm.Second;
- }
- displayTime();
- }
- void SETCLACK(){
- switch (PART){
- case 1:
- for(byte y = 0; y <= 13; y++){places[y] = dispTime[y];}
- setPLACE(9);
- PART = 2;
- break;
- case 2:
- displayIt(0, 15, places, Decimals);
- break;
- case 3:
- if(compile(places)){
- for(byte z = 0; z <= 6; z++){fullTime[z] = compiledTime[z];}
- uploadTIME(fullTime[0],fullTime[1],fullTime[2],fullTime[3],fullTime[4],fullTime[5]);
- displayIt(0, 15, success, noDecimals);
- delay(500);
- MODE = 0; PART = 0;
- break;
- }else{
- displayIt(0, 15, error, noDecimals);
- delay(1000);
- MODE = 0; PART = 0;
- break;
- }
- }
- }
- void SHOWALARM(byte a){
- byte address = 0;
- if(a == 0){address = 0;}
- if(a == 1){address = 16;}
- if(a == 2){address = 32;}
- if(a == 3){address = 48;}
- byte tempArray[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11};
- for(byte y = 0; y <= 13; y++){tempArray[y] = (EEPROM.read(address + y));}
- displayIt(0,15,tempArray,noDecimals);
- }
- void SETALARM(byte a){
- byte address = 0;
- if(a == 0){address = 0;}
- if(a == 1){address = 16;}
- if(a == 2){address = 32;}
- if(a == 3){address = 48;}
- switch (PART){
- case 1:
- for(byte y = 0; y <= 13; y++){places[y] = (EEPROM.read(address + y));}
- setPLACE(9);
- PART = 2;
- break;
- case 2:
- displayIt(0, 15, places, Decimals);
- break;
- case 3:
- displayIt(0, 15, success, noDecimals);
- for(byte w = 0; w <= 13; w++){EEPROM.write((address + w), places[w]);}
- MODE = 0; PART = 0;
- break;
- }
- }
- //-----------Methods for encoding and decoding--------------------------------------------------
- void displayTime(){
- Year = fullTime[0];
- dispTime[3] = (Year % 10);
- Year = (Year / 10);
- dispTime[2] = (Year % 10);
- Year = (Year / 10);
- dispTime[1] = (Year % 10);
- Year = (Year / 10);
- dispTime[0] = (Year % 10);
- Month = fullTime[1];
- dispTime[5] = (Month % 10);
- Month = (Month / 10);
- dispTime[4] = (Month % 10);
- Day = fullTime[2];
- dispTime[7] = (Day % 10);
- Day = (Day / 10);
- dispTime[6] = (Day % 10);
- Hour = fullTime[3];
- dispTime[9] = (Hour % 10);
- Hour = (Hour / 10);
- dispTime[8] = (Hour % 10);
- Minute = fullTime[4];
- dispTime[11] = (Minute % 10);
- Minute = (Minute / 10);
- dispTime[10] = (Minute % 10);
- Second = fullTime[5];
- dispTime[13] = (Second % 10);
- Second = (Second / 10);
- dispTime[12] = (Second % 10);
- //print the array from display 0-13, 14 & 15 are used by the centiseconds and are not apart of the main time display
- displayIt(0,13,dispTime,timeDecimals);
- }
- boolean compile(byte g[]){
- boolean compileSUC = true;
- int tempYear = ( (g[0] * 1000) + (g[1] * 100) + (g[2] * 10) + (g[3]) );
- if(tempYear > 2100){compileSUC = false;}
- else{compiledTime[0] = tempYear;}
- int tempMonth = ( (g[4] * 10) + (g[5]) );
- if(tempMonth > 12){compileSUC = false;}
- else{compiledTime[1] = tempMonth;}
- int tempDay = ( (g[6] * 10) + (g[7]) );
- if(tempDay > 31){compileSUC = false;}
- else{compiledTime[2] = tempDay;}
- int tempHour = ( (g[8] * 10) + (g[9]) );
- if(tempHour > 24){compileSUC = false;}
- else{compiledTime[3] = tempHour;}
- int tempMinute = ( (g[10] * 10) + (g[11]) );
- if(tempMinute > 59){compileSUC = false;}
- else{compiledTime[4] = tempMinute;}
- int tempSecond = ( (g[12] * 10) + (g[13]) );
- if(tempSecond > 59){compileSUC = false;}
- else{compiledTime[5] = tempSecond;}
- return compileSUC;
- }
- void uploadTIME(int YEAR, int MONTH, int DAY, int HOUR, int MINUTE, int SECOND){
- //set a time into the "tmElements_t tm" object
- tm.Year = (YEAR - 1970); //tm.Year is stored in years since 1970
- tm.Month = MONTH;
- tm.Day = DAY;
- tm.Hour = HOUR;
- tm.Minute = MINUTE;
- tm.Second = SECOND;
- RTC.write(tm);//to DS3231
- }
- //------------Methods for moving the cursor around and changing the numbers---------------
- void setPLACE(byte a){
- for(int h=0;h<=13;h++){Decimals[h] = 0;}
- Decimals[a] = 1;
- PLACE = a;
- }
- void movePLACE(boolean P){
- if(P){ // 1 = LEFT
- if(PLACE == 0){
- setPLACE(13);
- }else{
- setPLACE((PLACE)-1);
- }
- }else{ // 0 = RIGHT
- if(PLACE == 13){
- setPLACE(0);
- }else{
- setPLACE((PLACE)+1);
- }
- }
- }
- void incPLACEalarm(boolean I){
- if(I){ // 1 = UP
- if(places[PLACE] == 9){
- places[PLACE] = 13;
- }else if(places[PLACE] == 13){
- places[PLACE] = 0;
- }else{
- places[PLACE] = ((places[PLACE]) + 1);
- }
- }else{ // 0 = DOWN
- if(places[PLACE] == 0){
- places[PLACE] = 13;
- }else if(places[PLACE] == 13){
- places[PLACE] = 9;
- }else{
- places[PLACE] = ((places[PLACE]) - 1);
- }
- }
- }
- void incPLACEtime(boolean I){
- if(I){ // 1 = UP
- if(places[PLACE] == 9){
- places[PLACE] = 0;
- }else{
- places[PLACE] = ((places[PLACE]) + 1);
- }
- }else{ // 0 = DOWN
- if(places[PLACE] == 0){
- places[PLACE] = 9;
- }else{
- places[PLACE] = ((places[PLACE]) - 1);
- }
- }
- }
- //-------Methods for controlling the displays though shift registers----------------------
- void displayIt(byte a, byte b,byte p[],byte D[]){
- for(int m = a; m <= b; m++){ writeNumber(p[m], D[m], m); }
- }
- void blankall(){
- digitalWrite(ONE, o[11]);
- digitalWrite(TWO, t[11]);
- digitalWrite(FOUR, f[11]);
- digitalWrite(EIGHT, e[11]);
- Shift(0);//all displays enabled for blanking
- }
- void blank(int a){
- digitalWrite(ONE, o[11]);
- digitalWrite(TWO, t[11]);
- digitalWrite(FOUR, f[11]);
- digitalWrite(EIGHT, e[11]);
- Shift(Displays[a]);
- }
- void writeNumber(int a, int dp,int disp){
- selectAndShift(disp);
- if(dp == 1){digitalWrite(DP, LOW);}
- else if(dp == 0){digitalWrite(DP, HIGH);}
- digitalWrite(ONE, o[a]);
- digitalWrite(TWO, t[a]);
- digitalWrite(FOUR, f[a]);
- digitalWrite(EIGHT, e[a]);
- }
- void selectAndShift(int displayNum){
- digitalWrite(latchPin, LOW);
- shiftOut(dataPin, clockPin, MSBFIRST, highByte(Displays[displayNum]));
- shiftOut(dataPin, clockPin, MSBFIRST, lowByte(Displays[displayNum]));
- digitalWrite(latchPin, HIGH);
- digitalWrite(latchPin, LOW);
- }
- void Shift(int Num){
- digitalWrite(latchPin, LOW);
- shiftOut(dataPin, clockPin, MSBFIRST, highByte(Num));
- shiftOut(dataPin, clockPin, MSBFIRST, lowByte(Num));
- digitalWrite(latchPin, HIGH);
- digitalWrite(latchPin, LOW);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement