Binär-Zähler mit Arduino

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.

Video: Binär-Zähler in Aktion

Aufbau mit WS2812B-RGB-Matrix

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).

Details zur WS2812-LED

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.

Schaltung
Abb.: Schaltung

Verwendete Bauteile

Aufbau

Schematischer Aufbau
Abb.: Schematischer Aufbau
Aufbau auf dem Breadboard
Abb.: Aufbau auf dem Breadboard

Aufbau mit regulären LEDs

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.

Verwendete Bauteile

Aufbau auf dem Breadboard

Schematischer Aufbau mit LEDs
Abb.: Schematischer Aufbau mit LEDs
Video: Binär-Zähler mit LEDs

Sketch der Binärzählers

#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