Die Idee, eine Binär-Uhr mit dem Arduino als Steuerungseinheit zu bauen, habe ich schon eine Weile. Daher habe ich zunächst eine Test-Schaltung für einen Binärzähler mit einer 4x4-RGB-LED-Matrix aufgebaut, der Sekunden und Minuten hochzählt. Nach 59:59 Minuten fängt der Zähler wieder bei 00:00 an.
Der Schaltplan selbst ist sehr simpel, denn außer der LED-Matrix und dem Arduino werden lediglich ein
Widerstand und ein Kondensator benötigt.
Die LED-Matrix besteht aus 16 WS2812B-LEDs; dies sind einzeln adressierbare RGB-LEDs. Sie verfügen über einen
integrierten Chip und belegen daher nur einen einzigen digitalen Output des Arduino-Boards. Das Datensignal
des Arduino bestimmt dann, in welcher Farbe der Controller welche LED leuchten lassen soll.
Darüber hinaus lassen sich viele WS2812-LEDs hintereinander schalten.
In diesem kleinen Projekt sind auf der Matrix 16× WS2812-LEDs hintereinander geschaltet.
In meinem Sketch habe ich die Library von Adafruit verwendet
(siehe: https://github.com/adafruit/Adafruit_NeoPixel).
Jede LED mit WS2812-Controller verfügt über vier Anschlüsse:
- VCC (3,3V oder 5V),
- GND (=Ground),
- DIN bzw. IN (=Data In)
- DOUT bzw. OUT (=Data Out).
Jede WS2812 LED benötigt bis zu 60mA. Es ist also ratsam, ein Netzteil zu verwenden. Dieses Netzteil sollte
mit einem Elektrolyt-Kondensator (1000uF, 6,3V) unterstützt werden. Der GND des Netzteils und der GND des
Arduinos müssen verbunden werden. In meinem Beispiel habe ich die USB-Stromversorgung des Arduino verwendet.
Nun kann man einfach einen digitalen Kanal des Arduinos über einen Widerstand (300 – 500 Ohm) mit dem DIN
der ersten LED verbinden. Ihr DOUT wird dann wiederum mit dem DIN der nächsten LED verbunden usw.
Der Widerstand ist nur vor der ersten LED nötig.
Anstatt der WS2812B-RGB-Matrix kann man natürlich auch ganz reguläre LEDs in verschiedenen Farben verwenden und diese einzeln ansteuern. Im folgenden Aufbau habe ich mir die Tatsache zu Nutze gemacht, dass man auch die analogen Pins als digitale Ausgänge verwenden kann.
#include <Adafruit_NeoPixel.h>
#define PIN 8
#define NUMPIXELS 16
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
byte ledMapping[16] = {0, 1, 2, 3, 7, 6, 5, 4, 8, 9, 10, 11, 15, 14, 13, 12};
// set the time where the counter should begin
byte minutes = 0;
byte seconds = 0;
void setup()
{
pixels.begin();
}
void loop()
{
delay(1000);
seconds++;
if (seconds >= 60) {
minutes++;
seconds = 0;
}
if (minutes >= 60) {
minutes = 0;
}
// show seconds
showLedGroup(seconds, pixels.Color(30, 0, 0), 0);
// show minutes
showLedGroup(minutes, pixels.Color(0, 30, 0), 8);
}
/**
* Shows the binary representation of a value with LED on/off
*/
void showLedGroup(byte value, uint32_t ledColor, byte ledOffset)
{
byte digits[8];
intToBitArray(value, sizeof(digits), digits);
reverseArray(digits, sizeof(digits));
for(int i=0; i<sizeof(digits)-1; i++) {
if (digits[i] == 1) {
pixels.setPixelColor(ledMapping[i+ledOffset], ledColor);
} else {
pixels.setPixelColor(ledMapping[i+ledOffset], pixels.Color(0, 0, 0));
}
}
pixels.show();
}
/**
* Converts a byte value to an array of bit values
*/
void intToBitArray(byte in, byte count, byte* out)
{
/* assert: count <= sizeof(int)*CHAR_BIT */
byte mask = 1U << (count-1);
byte i;
for (i = 0; i < count; i++) {
out[i] = (in & mask) ? 1 : 0;
in <<= 1;
}
}
/**
* Reverses an array of bytes
*/
void reverseArray(byte* arr, byte arrLength)
{
byte i = arrLength - 1;
byte j = 0;
while(i > j) {
byte temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i--;
j++;
}
}
zurück