/**
* Firmware fuer die Neo-Pixel-Binary-Clock.
* Open Source - man kann damit in jeder Form machen, was man moechte.
* Autor: Christian Aschoff / caschoff _AT_ mac _DOT_ com
* Mehr Selbstbau-Projekte unter http://www.christians-bastel-laden.de
* V 1.2
* letztes Update: 8.4.2015
*
* Versionshistorie:
* V 1.01 - Schlafverhalten des DCF77-Emfaengers war falsch.
* V 1.1 - Auf die aktuellen Bibliotheken und Boards aktualisiert.
* V 1.2 - Verbesserte RTC-Initialisierung.
*
* Fuer einen korrekten Betrieb beachte man die Tipps zum Betreiben eines
* NeoPixel-Strips von Adafruit hier:
* https://learn.adafruit.com/adafruit-neopixel-uberguide/overview
*
* Ausserdem muss die Adafruit NeoPixel-Library im library-Ordner liegen,
* diese gibt es hier:
* https://github.com/adafruit/Adafruit_NeoPixel
*
* Pinbelegung:
* Siehe weiter unten bei den Boards.
*/
#define SIGNATURE "Neo-Binary-Clock V 1.2 vom 8.4.2015."
#include <Adafruit_NeoPixel.h>
#include <RTClib.h>
#define PIN 6
byte c; // Hilfsvariable, zaehlt einfach hoch, fuer den Farb-Wechsel-Effekt
uint32_t color1, color2, color3; // Die drei Farben fuer Stunde/Minute/Sekunde
// Initialisierung der Adafruit-NeoPixel-Library
#define NUMPIXELS 13
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
// Die Echtzeituhr initialisieren...
RTC_DS1307 rtc;
volatile boolean needsUpdateFromRtc = true;
// Die gelesene Zeit...
int hours, minutes, seconds;
/**
* Die Standard-Modi.
*/
#define STD_MODE_NORMAL 0
#define STD_MODE_COLORTEST 1
#define STD_MODE_BLANK 2
#define STD_MODE_COUNT 2
// Startmode...
byte mode = STD_MODE_NORMAL;
/**
* Funktion zum loeschen des Strips.
*/
void clearStrip() {
for (int i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, 0);
}
}
/**
* Funktion fuer saubere 'Regenbogen'-Farben.
* Kopiert aus den Adafruit-Beispielen (strand).
*/
uint32_t wheel(byte WheelPos) {
if (WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
void setup() {
strip.begin();
clearStrip();
// alle LEDs an...
for (byte i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, wheel((256 / NUMPIXELS) * i));
strip.show();
delay(50);
}
delay(200);
Serial.begin(57600);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
Serial.println(F(SIGNATURE));
Serial.print(F("Compiled: "));
Serial.print(F(__TIME__));
Serial.print(F(" / "));
Serial.println(F(__DATE__));
attachInterrupt(0, updateFromRtc, FALLING);
// alle LEDs aus...
for (byte i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, 0);
strip.show();
delay(50);
}
}
void updateFromRtc() {
needsUpdateFromRtc = true;
}
void loop() {
// 1*/Sekunde die Zeit neu lesen (via Interrupt)
if (needsUpdateFromRtc) {
needsUpdateFromRtc = false;
DateTime now = rtc.now();
Serial.print(F("RTC-Time: "));
Serial.print(now.hour());
Serial.print(F(":"));
Serial.print(now.minute());
Serial.print(F(":"));
Serial.print(now.second());
Serial.print(F(" RTC-Date: "));
Serial.print(now.day());
Serial.print(F("."));
Serial.print(now.month());
Serial.print(F("."));
Serial.println(now.year());
hours = now.hour();
minutes = now.minute();
seconds = now.second();
// die Zeit in Einzelstellen aufteilen...
byte h1 = hours / 10;
byte h2 = hours - 10 * h1;
byte m1 = minutes / 10;
byte m2 = minutes - 10 * m1;
c++;
color2 = wheel(c + (256 / 3));
color3 = wheel(c + 2 * (256 / 3));
if (mode == STD_MODE_NORMAL) {
// den Strip loeschen...
clearStrip();
// die einzelnen Stellen binaer ausgeben...
for (byte i = 0; i < 4; i++) {
if ((m2 & (1 << i)) == (1 << i)) {
strip.setPixelColor(0 + i, color2);
}
if ((m1 & (1 << i)) == (1 << i)) {
strip.setPixelColor(6 - i, color2);
}
if ((h2 & (1 << i)) == (1 << i)) {
strip.setPixelColor(7 + i, color3);
}
if ((h1 & (1 << i)) == (1 << i)) {
strip.setPixelColor(12 - i, color3);
}
}
// und zu guter Letzt den Strip aktualisieren...
strip.show();
needsUpdateFromRtc = true;
delay(60000);
}
}
}