Die Idee für dieses kleine Projekt kam aus der Situation heraus, dass ich mir einen 12bit RGB-LED-Ring
(WS2812) bestellt hatte und nun dafür einen sinnvollen Einsatz suchte.
Die Uhr funktioniert quasi wie eine normale Analoguhr mit Zeigern, jedoch werden statt den Zeigern jeweils
eine bunte LED angezeigt (grün für Stunden, blau für Minuten und rot für Sekunden). Die Besonderheit dieser
Uhr ist jedoch, dass sie nur 12 verschiedene Anzeigemöglichkeiten bietet, damit sind zwar die Stunden
korrekt (im 12-Stunden-Format), jedoch dürfen Minuten und Sekunden nicht direkt abgelesen werden, sondern nur
die Position der jeweiligen LED. Daraus folgt, dass man an dieser Uhr Minuten und Sekunden nicht präzise
ablesen kann.
Einen weiteren Unterschied zu einer analogen Uhr gibt es noch: Die Position der Stunden ist immer fix bei der
aktuellen Stunde und schaltet erst nach Ablauf von 59 Minuten auf die nächste Stunde um.
Das hier verwendete DS1307 Real-Time-Clock-Modul (RTC) ermöglicht das Auslesen und Setzen von Datum und Uhrzeit. Dank der integrierten Batterie verliert es die Uhrzeit auch nicht bei einem Stromverlust. In diesem Projekt wird Datum/Uhrzeit nur initial gesetzt und muss dann wieder auskommentiert werden, damit bei einem Neustart/Reset des Arduinos diese Daten nicht wieder überschrieben werden! Für die Darstellung der Uhrzeit wird das Datum nicht benötigt und daher auch nicht ausgelesen.
Das DS1307-Module wird folgendermaßen an den Arduino angeschlossen (Anschluss DS wird hier nicht benutzt):
DS1307 | Arduino |
---|---|
VCC | 3V |
GND | GND |
SCL | Analog PIN 5 |
SDA | Analog PIN 4 |
Vorsicht: Manche RTC-Module haben integrierte Ladeautomatiken, die bei Nutzung einer CR2032-Knopfzelle Schäden verursachen können. Daher sollte man in diesen Fällen eine wiederaufladbare Lithium-Ionen-Knopfzelle (LIR2032) verwenden.
Aufbau und Anschluss des RGB-LED-Ringes siehe hier
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#define PIN_LED_RING 8
#define NUMPIXELS 12
#define LED_BRIGHTNESS 35
#define DS1307_ADDRESS 0x68 // I²C Address
Adafruit_NeoPixel ring = Adafruit_NeoPixel(NUMPIXELS, PIN_LED_RING, NEO_GRB + NEO_KHZ800);
byte ledMapping[NUMPIXELS] = {6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5};
int hours=0, minutes=0, seconds=0;
byte h=0, m=0, s=0;
float divisor = 0.0166666;
uint32_t colorSeconds, colorMinutes, colorHours;
void setup()
{
Wire.begin();
Serial.begin(9600);
/*
* You have to set the date/time only once.
* Comment the following line after setting the date/time because it
* will be overwritten after every setup/restart of your circuit.
*/
//setDate();
ring.begin();
byte b = min(255, LED_BRIGHTNESS);
colorSeconds = ring.Color(max(3, b/10), max(2, b/15), 0);
colorMinutes = ring.Color(0, b/4, b/3);
colorHours = ring.Color(0, b, 0);
}
void loop()
{
readTime();
showClock();
delay(1000);
}
void readTime()
{
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 7);
seconds = bcdToDec(Wire.read());
minutes = bcdToDec(Wire.read());
hours = bcdToDec(Wire.read() & 0b111111);
Serial.println((String)hours + ":" + (String)minutes + ":" + (String)seconds);
}
void setDate()
{
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(0x00);
Wire.write(decToBcd(30)); // seconds
Wire.write(decToBcd(04)); // minutes
Wire.write(decToBcd(11)); // hours (24-hour format)
Wire.write(decToBcd(7)); // weekday
Wire.write(decToBcd(29)); // day
Wire.write(decToBcd(10)); // month
Wire.write(decToBcd(2017)); // year
Wire.write(0x00);
Wire.endTransmission();
}
void showClock()
{
s = (byte)(divisor*seconds*NUMPIXELS);
if (s>=NUMPIXELS) {
s = 0;
}
m = (byte)(divisor*minutes*NUMPIXELS);
if (m>=NUMPIXELS) {
m = 0;
}
h = hours%12;
for(byte i=0; i<NUMPIXELS; i++) {
ring.setPixelColor(i, 0);
}
ring.setPixelColor(ledMapping[s], colorSeconds);
ring.setPixelColor(ledMapping[m], colorMinutes);
ring.setPixelColor(ledMapping[h], colorHours);
ring.show();
}
int decToBcd(int value)
{
return ((value/10*16) + (value%10));
}
int bcdToDec(int value)
{
return ((value/16*10) + (value%16));
}
zurück