// LED er nummrert fra 0 til 23 (0 er kl 12) // Første bit i MAP kl 12 #include "Wire.h" #define INTERRUPT_PIN 18 #define DS3231_I2C_ADDRESS 0x68 #define debug false #define FIRST_ANALOG_PIN 2 #define FIRST_DIGITAL_PIN 23 #define FIRST_INPUT_PIN 47 #define DS3231_SQW_FREQ_1 0b00000000 // 1Hz #define DS3231_SQW_FREQ_1024 0b00001000 // 1024Hz #define DS3231_SQW_FREQ_4096 0b00010000 // 4096Hz #define DS3231_SQW_FREQ_8192 0b00011000 // 8192Hz #define FRAME_GLOW 2 #define SECOND_BLINK_FRACTION 8 #define MINUTE_BLINK_FRACTION 1 volatile bool secondBlink=false; volatile bool minuteBlink=false; volatile byte lastHourLED=100; volatile byte lastMinuteLED=100; volatile byte lastSecondLED=100; volatile bool minuteON=false; volatile bool SecondON=false; volatile bool doneCircleFlash=false; volatile int count =0; volatile bool B1pressed=false; // NOT IN USE volatile bool B2pressed=false; volatile bool B3pressed=false; volatile bool B4pressed=false; volatile bool B5pressed=false; String linje=""; volatile bool showTime=true; //------------------------------------------- void SQWFrequency(uint8_t freq) { Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0x0E); Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 1); // control register uint8_t creg = Wire.read(); creg &= ~0b00011000; // Set to 0 creg |= freq; // Set freq bits Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0x0E); Wire.write(creg); Wire.endTransmission(); } // -------------------- INTERUPT --------------- void InterruptHandler(void) { static int iSecond=0; static int iMinute=0; iSecond+=1; iMinute+=1; count+=1; if (iSecond>1024/SECOND_BLINK_FRACTION) { // Half Second secondBlink = true; iSecond=0; } if (iMinute>1024/MINUTE_BLINK_FRACTION) { // 1 Second minuteBlink = true; iMinute=0; } } //************************************ SETUP ************************** void setup() { Serial.begin(9600); setup_pins(); set_glow(); Wire.begin(); // set the initial time here: // DS3231 seconds, minutes, hours, day, date, month, year // setDS3231time(00,05,11,1,20,12,15); SQWFrequency(DS3231_SQW_FREQ_1024); // register interrupt function to line pinMode(INTERRUPT_PIN, INPUT); digitalWrite(INTERRUPT_PIN, HIGH); attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), InterruptHandler, FALLING); } //************************************ MAIN LOOP ************************** void loop() { byte newSecond, newMinute, newHour; byte nLED; char c; // --------------- LES serial -------------- if(Serial.available()) { while(Serial.available()) { c = Serial.read(); linje+=c; if(c=='\r') { Serial.println(linje); if(linje.indexOf("?")>-1) { Serial.println("Commands:"); Serial.println("test"); Serial.println("allon"); Serial.println("alloff"); Serial.println("show"); Serial.println("setHH:MM"); } if(linje.indexOf("test")>-1) { testAlle(); circle(); circle(); circle(); flash(); delay(1000); flash(); delay(1000); flash(); delay(1000); } if(linje.indexOf("show")>-1) { showTime=true; } if(linje.indexOf("allon")>-1) { alleOn(); } if(linje.indexOf("alloff")>-1) { alleOff(); } if(linje.indexOf("set")>-1) { newHour=linje.substring(3,6).toInt(); newMinute=linje.substring(6,8).toInt(); newSecond=0; settKlokka(newSecond,newMinute,newHour); } linje=""; } } } // Read Time Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); // set DS3231 register pointer to 00h Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 3); // request 3 bytes of data from DS3231 starting from register 00h newSecond = bcdToDec(Wire.read() & 0x7f); newMinute = bcdToDec(Wire.read()); newHour = bcdToDec(Wire.read() & 0x3f); // -------------------- BRYTERE ------ // if (digitalRead(FIRST_DIGITAL_PIN+1)) { // if (B1pressed==false) { // skrivTid(newSecond,newMinute,newHour); // B1pressed=true; // } // } else B1pressed=false; if (!digitalRead(FIRST_INPUT_PIN)) { if (B2pressed==false) { if (debug) Serial.println("Bryter 1 trykket"); settKlokka(newSecond,newMinute,newHour+1); B2pressed=true; } } else B2pressed=false; if (!digitalRead(FIRST_INPUT_PIN+2)) { if (B3pressed==false) { if (debug) Serial.println("Bryter 2 trykket"); settKlokka(newSecond,newMinute,newHour-1); B3pressed=true; } } else B3pressed=false; if (!digitalRead(FIRST_INPUT_PIN+4)) { if (B4pressed==false) { if (debug) Serial.println("Bryter 3 trykket"); settKlokka(newSecond,newMinute+1,newHour); B4pressed=true; } } else B4pressed=false; if (!digitalRead(FIRST_INPUT_PIN+6)) { if (B5pressed==false) { if (debug) Serial.println("Bryter 4 trykket"); settKlokka(newSecond,newMinute-1,newHour); B5pressed=true; } } else B5pressed=false; //Serial.println(newHour); // -------------------- HOUR ------ if (newHour > 11) { newHour = newHour-12; } nLED=hour2Led(newHour, newMinute); if (nLED != lastHourLED) { turnOFF(lastHourLED); turnON(nLED); lastHourLED=nLED; } // ---------------------- Flash ------------------ if (newMinute==0 || newMinute==30) { if (! doneCircleFlash) { circle(); delay(100); flash(); doneCircleFlash=true; } } else { doneCircleFlash=false; } //------------------ MINUTE --- nLED=time2Led(newMinute); if (nLED != lastMinuteLED) { turnOFFMiniteSecond(lastMinuteLED); turnON(nLED); minuteON=true; lastMinuteLED=nLED; } if (minuteBlink) { if (showTime) skrivTid(newSecond,newMinute,newHour); if (minuteON==true) { turnOFFMiniteSecond(lastMinuteLED); minuteON=false; } else { turnON(lastMinuteLED); minuteON=true; } minuteBlink=false; } //------------------ SECOND --- if (lastMinuteLED == lastHourLED) { nLED=time2Led(newSecond); if (nLED != lastSecondLED) { turnOFFMiniteSecond(lastSecondLED); turnON(nLED); SecondON=true; lastSecondLED=nLED; } if (secondBlink) { if (SecondON==true) { turnOFFMiniteSecond(lastSecondLED); SecondON=false; } else { turnON(lastSecondLED); SecondON=true; } secondBlink=false; } } else { if (SecondON==true) { turnOFFMiniteSecond(lastSecondLED); // turn off at end SecondON=false; } } delay(1); } /// ***************************** END MAIN ***************************** void settKlokka(byte newSecond, byte newMinute, byte newHour) { if (newHour > 23) { newHour = 0; } if (newMinute > 59) { newMinute = 0; } // Read Time Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); // set DS3231 register pointer to 00h Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request 7 bytes of data from DS3231 starting from register 00h byte xSecond = bcdToDec(Wire.read() & 0x7f); byte xMinute = bcdToDec(Wire.read()); byte xHour = bcdToDec(Wire.read() & 0x3f); byte xdayOfWeek = bcdToDec(Wire.read()); byte xdayOfMonth = bcdToDec(Wire.read()); byte xmonth = bcdToDec(Wire.read()); byte xyear = bcdToDec(Wire.read()); // DS3231 seconds, minutes, hours, day, date, month, year setDS3231time(newSecond,newMinute,newHour,xdayOfWeek,xdayOfMonth,xmonth,xyear); skrivTid(newSecond,newMinute,newHour); } void skrivTid(byte newSecond, byte newMinute, byte newHour) { Serial.print(newHour); Serial.print(":"); Serial.print(newMinute); Serial.print(":"); Serial.println(newSecond); } void circle() { for (int i=0; i<24;i++) { turnON(i); delay(15); } for (int i=0; i<24;i++) { turnOFFMiniteSecond(i); } delay(300); } void testAlle() { for (int i=0; i<24;i++) { turnON(i); delay(500); } for (int i=0; i<24;i++) { turnOFF(i); } delay(500); } void alleOn() { for (int i=0; i<24;i++) { turnON(i); } } void alleOff() { for (int i=0; i<24;i++) { turnOFF(i); } } void flash() { for (int i=0; i<24;i++) { turnON(i); } delay(150); for (int i=0; i<24;i++) { turnOFFMiniteSecond(i); } } void turnOFFMiniteSecond(byte nLed) { if (nLed != lastHourLED) { turnOFF(nLed); } } void turnON(byte nLed) { //Serial.print("Turn ON LED="); //Serial.println(nLed); if (nLed % 2) { digitalWrite(nLed-1+FIRST_DIGITAL_PIN,HIGH); } else { analogWrite(nLed/2+FIRST_ANALOG_PIN,255); } } void turnOFF(byte nLed) { //Serial.print("Turn OFF LED="); //Serial.println(nLed); if (nLed % 2) { digitalWrite(nLed-1+FIRST_DIGITAL_PIN,LOW); } else { analogWrite(nLed/2+FIRST_ANALOG_PIN,FRAME_GLOW); } } byte hour2Led(byte nHour, byte nMinute) { byte hourLed; hourLed = nHour * 2; if (nMinute > 39) { hourLed+=2; } else if (nMinute > 19) { hourLed+=1; } if (hourLed==24) hourLed=0; return hourLed; } byte time2Led(byte nTime) { switch (nTime) { case 59: case 0: case 1: return 0; break; case 2: case 3: return 1; break; case 4: case 5: case 6: return 2; break; case 7: case 8: return 3; break; case 9: case 10: case 11: return 4; break; case 12: case 13: return 5; break; case 14: case 15: case 16: return 6; break; case 17: case 18: return 7; break; case 19: case 20: case 21: return 8; break; case 22: case 23: return 9; break; case 24: case 25: case 26: return 10; break; case 27: case 28: return 11; break; case 29: case 30: case 31: return 12; break; case 32: case 33: return 13; break; case 34: case 35: case 36: return 14; break; case 37: case 38: return 15; break; case 39: case 40: case 41: return 16; break; case 42: case 43: return 17; break; case 44: case 45: case 46: return 18; break; case 47: case 48: return 19; break; case 49: case 50: case 51: return 20; break; case 52: case 53: return 21; break; case 54: case 55: case 56: return 22; break; case 57: case 58: return 23; break; } } // ------------------------ Time --------------------------- void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) { // sets time and date data to DS3231 Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); // set next input to start at the seconds register Wire.write(decToBcd(second)); // set seconds Wire.write(decToBcd(minute)); // set minutes Wire.write(decToBcd(hour)); // set hours Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday) Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31) Wire.write(decToBcd(month)); // set month Wire.write(decToBcd(year)); // set year (0 to 99) Wire.endTransmission(); } // Convert normal decimal numbers to binary coded decimal byte decToBcd(byte val) { return( (val/10*16) + (val%10) ); } // Convert binary coded decimal to normal decimal numbers byte bcdToDec(byte val) { return( (val/16*10) + (val%16) ); } void setup_pins() { pinMode(FIRST_ANALOG_PIN, OUTPUT); pinMode(FIRST_ANALOG_PIN+1, OUTPUT); pinMode(FIRST_ANALOG_PIN+2, OUTPUT); pinMode(FIRST_ANALOG_PIN+3, OUTPUT); pinMode(FIRST_ANALOG_PIN+4, OUTPUT); pinMode(FIRST_ANALOG_PIN+5, OUTPUT); pinMode(FIRST_ANALOG_PIN+6, OUTPUT); pinMode(FIRST_ANALOG_PIN+7, OUTPUT); pinMode(FIRST_ANALOG_PIN+8, OUTPUT); pinMode(FIRST_ANALOG_PIN+9, OUTPUT); pinMode(FIRST_ANALOG_PIN+10, OUTPUT); pinMode(FIRST_ANALOG_PIN+11, OUTPUT); pinMode(FIRST_DIGITAL_PIN, OUTPUT); pinMode(FIRST_DIGITAL_PIN+2, OUTPUT); pinMode(FIRST_DIGITAL_PIN+4, OUTPUT); pinMode(FIRST_DIGITAL_PIN+6, OUTPUT); pinMode(FIRST_DIGITAL_PIN+8, OUTPUT); pinMode(FIRST_DIGITAL_PIN+10, OUTPUT); pinMode(FIRST_DIGITAL_PIN+12, OUTPUT); pinMode(FIRST_DIGITAL_PIN+14, OUTPUT); pinMode(FIRST_DIGITAL_PIN+16, OUTPUT); pinMode(FIRST_DIGITAL_PIN+18, OUTPUT); pinMode(FIRST_DIGITAL_PIN+20, OUTPUT); pinMode(FIRST_DIGITAL_PIN+22, OUTPUT); pinMode(FIRST_INPUT_PIN, INPUT); pinMode(FIRST_INPUT_PIN+2, INPUT); pinMode(FIRST_INPUT_PIN+4, INPUT); pinMode(FIRST_INPUT_PIN+6, OUTPUT); digitalWrite(FIRST_INPUT_PIN, HIGH); //Pull up digitalWrite(FIRST_INPUT_PIN+2, HIGH); digitalWrite(FIRST_INPUT_PIN+4, HIGH); digitalWrite(FIRST_INPUT_PIN+6, HIGH); } void set_glow() { analogWrite(FIRST_ANALOG_PIN, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+1, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+2, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+3, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+4, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+5, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+6, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+7, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+8, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+9, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+10, FRAME_GLOW); analogWrite(FIRST_ANALOG_PIN+11, FRAME_GLOW); }