/* Based on: http://www.instructables.com/id/World-Clock-in-German-using-Arduino/?ALLSTEPS Compiled with Arduino-IDE 1.06 __________________________________ Changes: Different front-layout. Added 4 single Led's for displaying +1minute, +2minutes, +3minutes, +4minutes Added LDR for brightness-control. Using RTC DS3231 instead of DS1307 - DS3231 is temperature-compensated */ #include //#include #include #include int debug =0; // serial print for debugging only ! choices: 0/1 #define Minute_4 10 // digital 10(PWM) to 4-Minute corner-LED #define Minute_3 9 // digital 9 (PWM) to 3-Minute corner-LED #define Minute_2 6 // digital 6 (PWM) to 2-Minute corner-LED #define Minute_1 5 // digital 5 (PWM) to 1-Minute corner-LED #define BUTTON_HOUR 8 // digital 8 to hour-button #define BUTTON_MINUTE 7 // digital 7 to hour-button #define DATA 2 // digital 2 to pin 14 on the 74HC595 #define LATCH 3 // digital 3 to pin 12 on the 74HC595 #define CLOCK 4 // digital 4 to pin 11 on the 74HC595 // LDR for adjusting brightness const int sensorPin = A0; // analog 0 to LDR const int oePin = 11; // digital 11 (PWM) to pin 13 (OE) on the 74HC595 ICs int sensorValue = 0; // the LDR value int invSensorValue = 255; // inverted LDR value int brightnessLEDs = 50; // brightness of corner LEDs // variables for setting-buttons: int buttonStateHOUR = 0; // current state of the button int buttonStateMINUTE = 0; // current state of the button int lastButtonStateHOUR = 0; // previous state of the button int lastButtonStateMINUTE = 0; // previous state of the button // notice: read bytes from right to left: byte registerByte1 = 0; // 0 ES IST | 1 FUNF | 2 ZEHN | 3 ZWANZIG | 4 DREI | 5 VIERTEL | 6 VOR | 7 NACH byte registerByte2 = 0; // 0 HALB | 1 FUNF | 2 EIN | 3 S | 4 ELF | 5 ZWEI | 6 DREI | 7 VIER byte registerByte3 = 0; // 0 SECHS | 1 ACHT | 2 SIEBEN | 3 ZWOLF | 4 ZEH | 5 N | 6 EUN | 7 UHR tmElements_t tm; void setup(){ analogWrite(oePin, 255); // turn LED-Stripes off // corner-LEDs pinMode(Minute_1, OUTPUT); pinMode(Minute_2, OUTPUT); pinMode(Minute_3, OUTPUT); pinMode(Minute_4, OUTPUT); // LDR pinMode(sensorPin, INPUT); pinMode(oePin, OUTPUT); // Buttons pinMode(BUTTON_HOUR, INPUT); pinMode(BUTTON_MINUTE, INPUT); // Shift Register pinMode(LATCH, OUTPUT); pinMode(CLOCK, OUTPUT); pinMode(DATA, OUTPUT); intro(); // intro-sequence, just for fun if(debug ==1){ Serial.begin(9600); while (!Serial) ; // wait for serial Serial.println("DS1307/DS3231 RTC Read Test"); Serial.println("-------------------"); } } // end of setup void loop(){ sensorValue = analogRead(sensorPin); // read LDR-values sensorValue = map(sensorValue, 0, 1023, 3, 255); // map LDR-values (1 = minimum brightness of LED-Stripes, 0 = off) // why mapping from 3 and not from 0 ?: // because then maximum of variable invSensorValue = 255-3 = 252 // so the LED-Stripes don't completely turn off, when it's dark invSensorValue = 255 - sensorValue; // invert sensorValue for dimming LED-Stripes down, if surrounding light is low // set brightness of all LED-Stripes if(sensorValue >200 ){invSensorValue = 0;} // 0 = maximum brightness LED-Stripes analogWrite(oePin, invSensorValue); // write to OE-Pin's of 74HC595 to control brightness of LED-Stipes // set min/max brightness of minute/corner LEDs brightnessLEDs = sensorValue/5; // max-divisor (5) depends on your type of LEDs and surrounding light - just try if(brightnessLEDs >50){brightnessLEDs = 50;} // 50 = defined maximum brightness of corner LEDs if(brightnessLEDs <1) {brightnessLEDs = 1; } // 1 = defined minimum brightness of corner LEDs, so don't completely turn off // read the pushbutton input pin: buttonStateHOUR = digitalRead(BUTTON_HOUR); buttonStateMINUTE = digitalRead(BUTTON_MINUTE); // Detect HOUR Button if (buttonStateHOUR != lastButtonStateHOUR) { if (buttonStateHOUR == HIGH) { addTime(1,0); } lastButtonStateHOUR = buttonStateHOUR; } // Detect MINUTE Button if (buttonStateMINUTE != lastButtonStateMINUTE) { if (buttonStateMINUTE == HIGH) { addTime(0,1); } lastButtonStateMINUTE = buttonStateMINUTE; } // Generate time and shiftOut timeToBytes(); updateShiftRegisters(); if(debug ==1){ printTime(); } } // end of loop void timeToBytes(){ if (RTC.read(tm)) { // Check minute-/corner-LEDS if((tm.Minute-(tm.Minute/5)*5)==1) {analogWrite(Minute_1,brightnessLEDs); analogWrite(Minute_2,0); analogWrite(Minute_3,0); analogWrite(Minute_4,0); } else if((tm.Minute-(tm.Minute/5)*5)==2) {analogWrite(Minute_1,brightnessLEDs); analogWrite(Minute_2,brightnessLEDs); analogWrite(Minute_3,0); analogWrite(Minute_4,0); } else if((tm.Minute-(tm.Minute/5)*5)==3) {analogWrite(Minute_1,brightnessLEDs); analogWrite(Minute_2,brightnessLEDs); analogWrite(Minute_3,brightnessLEDs); analogWrite(Minute_4,0); } else if((tm.Minute-(tm.Minute/5)*5)==4) {analogWrite(Minute_1,brightnessLEDs); analogWrite(Minute_2,brightnessLEDs); analogWrite(Minute_3,brightnessLEDs); analogWrite(Minute_4,brightnessLEDs); } else { analogWrite(Minute_1,0); analogWrite(Minute_2,0); analogWrite(Minute_3,0); analogWrite(Minute_4,0); } int deutschHour = shortHour(tm.Hour); int halb = 0; registerByte1 = 0; registerByte2 = 0; registerByte3 = 0; //registerByte1: 0 ES IST | 1 FUNF | 2 ZEHN | 3 ZWANZIG | 4 DREI | 5 VIERTEL | 6 VOR | 7 NACH //registerByte2: 0 HALB | 1 FUNF | 2 EIN | 3 S | 4 ELF | 5 ZWEI | 6 DREI | 7 VIER //registerByte3: 0 SECHS | 1 ACHT | 2 SIEBEN | 3 ZWOLF | 4 ZEH | 5 N | 6 EUN | 7 UHR bitSet(registerByte1,0); // "ES IST" - is always on if (tm.Minute >= 5 && tm.Minute <= 9){ bitSet(registerByte1,1); // "FUNF" bitSet(registerByte1,7); // "NACH" } else if (tm.Minute >= 10 && tm.Minute <= 14){ bitSet(registerByte1,2); // "ZEHN" bitSet(registerByte1,7); // "NACH" } else if (tm.Minute >= 15 && tm.Minute <= 19){ bitSet(registerByte1,5); // "VIERTEL" bitSet(registerByte1,7); // "NACH" } else if (tm.Minute >= 20 && tm.Minute <= 24){ bitSet(registerByte1,2); // "ZEHN" bitSet(registerByte1,6); // "VOR" bitSet(registerByte2,0); // "HALB" halb = 1; } else if (tm.Minute >= 25 && tm.Minute <= 29){ bitSet(registerByte1,1); // "FUNF" bitSet(registerByte1,6); // "VOR" bitSet(registerByte2,0); // "HALB" halb = 1; } else if (tm.Minute >= 30 && tm.Minute <= 34){ bitSet(registerByte2,0); // "HALB" halb = 1; } else if (tm.Minute >= 35 && tm.Minute <= 39){ bitSet(registerByte1,1); // "FUNF" bitSet(registerByte1,7); // "NACH" bitSet(registerByte2,0); // "HALB" halb = 1; } else if (tm.Minute >= 40 && tm.Minute <= 44){ bitSet(registerByte1,2); // "ZEHN" bitSet(registerByte1,7); // "NACH" bitSet(registerByte2,0); // "HALB" halb = 1; } else if (tm.Minute >= 45 && tm.Minute <= 49){ bitSet(registerByte1,4); // "DREI" bitSet(registerByte1,5); // "VIERTEL" halb = 1; } else if (tm.Minute >= 50 && tm.Minute <= 54){ bitSet(registerByte1,2); // "ZEHN" bitSet(registerByte1,6); // "VOR" halb = 1; } else if (tm.Minute >= 55 && tm.Minute <= 59){ bitSet(registerByte1,1); // "FUNF" bitSet(registerByte1,6); // "VOR" halb = 1; } deutschHour = shortHour( deutschHour + halb); if ( deutschHour == 1 ) { bitSet(registerByte2,2); // "EIN" if (tm.Minute >= 5 && tm.Minute <= 59){ // if minute between 5-59 add "S" to "EIN" -> "EINS" bitSet(registerByte2,3); // "S" } } else if ( deutschHour == 2 ) { bitSet(registerByte2,5); // "ZWEI" } else if ( deutschHour == 3 ) { bitSet(registerByte2,6); // "DREI" } else if ( deutschHour == 4 ) { bitSet(registerByte2,7); // "VIER" } else if ( deutschHour == 5 ) { bitSet(registerByte2,1); // "FUNF" } else if ( deutschHour == 6 ) { bitSet(registerByte3,0); // "SECHS" } else if ( deutschHour == 7 ) { bitSet(registerByte3,2); // "SIEBEN" } else if ( deutschHour == 8 ) { bitSet(registerByte3,1); // "ACHT" } else if ( deutschHour == 9 ) { bitSet(registerByte3,5); // "N" bitSet(registerByte3,6); // "EUN" } else if ( deutschHour == 10 ) { bitSet(registerByte3,4); // "ZEH" bitSet(registerByte3,5); // "N" } else if ( deutschHour == 11 ) { bitSet(registerByte2,4); // "ELF" } else if ( deutschHour == 12 ) { bitSet(registerByte3,3); // "ZWOLF" } // only if minute is between 0-4, light up "UHR" ("ES IST ZWEI" + "UHR") if (tm.Minute <= 4){ bitSet(registerByte3,7); // "UHR" } } } void updateShiftRegisters(){ digitalWrite(LATCH, LOW); shiftOut(DATA, CLOCK, MSBFIRST, registerByte3); shiftOut(DATA, CLOCK, MSBFIRST, registerByte2); shiftOut(DATA, CLOCK, MSBFIRST, registerByte1); digitalWrite(LATCH, HIGH); } void addTime(int addHour, int addMinute){ // get time from RTC if (RTC.read(tm)) { if (addHour > 0) { tm.Hour = tm.Hour + addHour; if (tm.Hour > 12) { tm.Hour = tm.Hour - 12; } } if (addMinute > 0) { tm.Minute = tm.Minute + addMinute; tm.Second = 0; // set second to 0 if (tm.Minute > 59) { tm.Minute = tm.Minute - 60; tm.Hour = tm.Hour + 1; // add one hour } } RTC.write(tm); } } int shortHour(int tempHour){ tempHour = tempHour % 12; return tempHour == 0 ? 12 : tempHour; } void printTime(){ if (RTC.read(tm)) { print2digits(tm.Hour); Serial.write(':'); print2digits(tm.Minute); Serial.write(':'); print2digits(tm.Second); Serial.print(" "); Serial.print(tm.Day); Serial.write('.'); Serial.print(tm.Month); Serial.write('.'); Serial.print(tmYearToCalendar(tm.Year)); Serial.println(); Serial.print("registerByte3 = "); if (registerByte3 < 2 ) Serial.print(B0); if (registerByte3 < 4 ) Serial.print(B0); if (registerByte3 < 8 ) Serial.print(B0); if (registerByte3 < 16 ) Serial.print(B0); if (registerByte3 < 32 ) Serial.print(B0); if (registerByte3 < 64 ) Serial.print(B0); if (registerByte3 < 128) Serial.print(B0); Serial.print(registerByte3, BIN); Serial.println(); Serial.print("registerByte2 = "); if (registerByte2 < 2 ) Serial.print(B0); if (registerByte2 < 4 ) Serial.print(B0); if (registerByte2 < 8 ) Serial.print(B0); if (registerByte2 < 16 ) Serial.print(B0); if (registerByte2 < 32 ) Serial.print(B0); if (registerByte2 < 64 ) Serial.print(B0); if (registerByte2 < 128) Serial.print(B0); Serial.print(registerByte2, BIN); Serial.println(); Serial.print("registerByte1 = "); if (registerByte1 < 2 ) Serial.print(B0); if (registerByte1 < 4 ) Serial.print(B0); if (registerByte1 < 8 ) Serial.print(B0); if (registerByte1 < 16 ) Serial.print(B0); if (registerByte1 < 32 ) Serial.print(B0); if (registerByte1 < 64 ) Serial.print(B0); if (registerByte1 < 128) Serial.print(B0); Serial.print(registerByte1, BIN); Serial.println(); Serial.print("sensorValue = "); Serial.println(sensorValue); Serial.print("brightnessLEDs="); Serial.println(brightnessLEDs); Serial.println(); } else { if (RTC.chipPresent()) { Serial.println("The DS1307/DS3231 is stopped. Please run the SetTime"); Serial.println("example to initialize the time and begin running."); Serial.println(); } else { Serial.println("DS1307/DS3231 read error! Please check the circuitry/wiring."); Serial.println(); } delay(9000); } delay(300); } void print2digits(int number){ if (number >= 0 && number < 10) { Serial.write('0'); } Serial.print(number); } // Intro: circling corner LEDs :-)) void intro(){ int verz = 130; // delay in circle-sequence for (int i=0; i<=2; i++){ analogWrite(Minute_1,brightnessLEDs); analogWrite(Minute_2,brightnessLEDs); analogWrite(Minute_3,brightnessLEDs); analogWrite(Minute_4,brightnessLEDs); delay (verz); analogWrite(Minute_1,0); analogWrite(Minute_2,0); analogWrite(Minute_3,0); analogWrite(Minute_4,0); delay (verz); } delay(200); for (int i=0; i<=3; i++){ analogWrite(Minute_1,brightnessLEDs); delay (verz); analogWrite(Minute_2,brightnessLEDs); analogWrite(Minute_1,0); delay (verz); analogWrite(Minute_3,brightnessLEDs); analogWrite(Minute_2,0); delay (verz); analogWrite(Minute_4,brightnessLEDs); analogWrite(Minute_3,0); delay (verz); analogWrite(Minute_4,0); } delay(300); for (int i=0; i<=2; i++){ analogWrite(Minute_1,brightnessLEDs); analogWrite(Minute_2,brightnessLEDs); analogWrite(Minute_3,brightnessLEDs); analogWrite(Minute_4,brightnessLEDs); delay (verz); analogWrite(Minute_1,0); analogWrite(Minute_2,0); analogWrite(Minute_3,0); analogWrite(Minute_4,0); delay (verz); } delay(700); }