Servus zusammen.
Ich habe heute meinen 16er-WS2812B-Ring von Watterott (http://www.watterott.com/de/WS2812B-RGB-Ring-16) bekommen und mir ist spontan eine Idee dazu gekommen.
Warum nicht eine binäre Uhr daraus machen?
16 LEDs = 16 Bit = 4 Bit für die Stunden und jeweils 6 Bit für die Minuten und Sekunden.
Dies bedeutet im Umkehrschluss, dass die Stunden nur von 0 - 12 dargestellt werden können. (4 Bit = 1+2+4+8 = 15)
Minuten und Sekunden werden natürlich bei 6 Bit komplett dargestellt, denn mit 6 Bit kann man maximal die Zahl 63 darstellen.
Da die Uhr natürlich auch genau gehen soll, habe ich in meinem Fundus gekramt und noch eine RTC (Real Time Clock) DS1307 gefunden.
HW-Zutaten:
1 x Arduino (egal welcher)
1 x 16 WS2812B LEDs im Ring oder als Streifen
1 x DS1307 RTC
7 x Jumper-Kabel
SW-Zutaten:
1 x RTC-Library von http://www.pjrc.com/teensy/td_libs_DS1307RTC.html
1 x Time-Library von http://www.pjrc.com/teensy/td_libs_Time.html
1 x FastLED-Library von https://github.com/FastLED/FastLED
Die fertig verkabelte Hardware sollte so aussehen:
Spoiler anzeigen
Hier ist der Sketch, der keinerlei Anspruch auf Perfektion hat. Jeder, der noch die eine oder andere Optimierung beisteuern kann und will, der ist herzlich eingeladen, diese als Kommentar zu posten und bitte auch zu erklären
Nun aber der Sketch:
Spoiler anzeigen
/*
From the DS1307 connect the Pins as follows:
GND => GND
VCC => 5V
SDA => Arduino A4 (on a Nano)
SCL => Arduino A5 (on a Nano)
*/
//Include Libraries
#include <FastLED.h> //for LED-addressing (https://github.com/FastLED/FastLED)
#include <Wire.h> //to read out the RTC
#include <Time.h> // http://www.pjrc.com/teensy/td_libs_Time.html
#include <DS1307RTC.h> // http://www.pjrc.com/teensy/td_libs_DS1307RTC.html
//Define some stuff
#define NUM_LEDS 16 //Number of LEDs (used to create the array)
#define DATA_PIN 6 //Data-Pin on the Arduino
#define HourColor Red //Color to show for the Hour-Bits
#define MinuteColor Green //Color to show for the Minute-Bits
#define SecondColor Blue //Color to show for the Second-Bits
#define HourNeutral Black //Color to show for the Unused-Hour--Bits
#define MinuteNeutral Black //Color to show for the Unused-Minute-Bits
#define SecondNeutral Black //Color to show for the Unused-Seconds--Bits
#define LEDDimLevel 75 // How bright should we shine?
//Stuff needed for the LEDs
CRGB leds[NUM_LEDS]; // Create the array
void setup()
{
//LED related
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS); // fill the array
//RTC related
Wire.begin(); // Start the wire library
}
void loop()
{
// First, clear the existing led values
FastLED.clear();
// take the brightness down
LEDS.setBrightness(LEDDimLevel);
// Taken the following code from http://www.pjrc.com/teensy/td_libs_DS1307RTC.html and stripped a few bits for here
tmElements_t tm;
if (RTC.read(tm)) { // If we get a result from the RTC
if (tm.Hour > 12) { // Is it the hour = 12?
tm.Hour = tm.Hour -12; // Then substract 12 to start over with 1 (4 Bit-Limit)
}
displayHour(tm.Hour); // Show the hour in binary format
displayMinute(tm.Minute); // Show the minute in binary format
displaySecond(tm.Second); // Show the second in binary format
}
// Taken the above code from http://www.pjrc.com/teensy/td_libs_DS1307RTC.html and stripped a few bits for here
delay(250); // wait some msec
}
// Function found here: http://www.multiwingspan.co.uk/arduino.php?page=led5
void displayHour(byte Stunde)
{
for (int h = 0; h <= 3; h++) // count from most right Bit (0) to 4th Bit (3)
{
if (bitRead(Stunde, h) == 1) // Read the single Bits from right to left and if there is a !1!, bring the LED up
{
leds[h] = CRGB::HourColor; // show the color defined at the top of this sketch
}
else
{
leds[h] = CRGB::HourNeutral; // if the LED is not used, take it down or to a different color. See top of the ketch
}
}
FastLED.show(); // Show the LEDs
}
void displayMinute(byte Minute)
{
for (int m = 0; m <= 5; m++)
{
if (bitRead(Minute, m) == 1)
{
leds[4 + m] = CRGB::MinuteColor; // Start at the 1st LED for the minutes (4) and add the Minute-Bit
}
else
{
leds[4 + m] = CRGB::MinuteNeutral;
}
}
FastLED.show();
}
void displaySecond(byte Sekunde)
{
for (int s = 0; s <= 5; s++)
{
if (bitRead(Sekunde, s) == 1)
{
leds[10 + s] = CRGB::SecondColor; // Start at the 1st LED for the seconds (10) and add the Seconds-Bits
}
else
{
leds[10 + s] = CRGB::SecondNeutral;
}
}
FastLED.show();
}
Alles anzeigen