< Projekte
PIC2WS2812
Steuerung von WS2812-LEDs mit 8-Bit PIC Microcontroller
Grundlagen
Die PIC Lösung
Software
Defines

Darum geht's:

Die Ansteuerung von LEDs durch Mikrocontroller bietet dem geneigten Hobby-Elektroniker ein weites Betätigungsfeld für kreative Anwendungen. Ein paar einzelne LEDs oder die Treibertransistoren für einen RGB LED-Streifen lassen sich noch recht einfach über ein paar Port-Pins des Mikrocontrollers ansteuern, aber wenn man viele LEDs einzeln steuern möchte, z.B. für einen "LED Cube" oder einen Lauflicht-Effekt bei einer Lichter-Kette, steigt der Schaltungs- und Verdrahtungsaufwand schnell an.

Hier gibt es aber eine geniale Lösung in Form von LEDs mit eingebautem Controller, wie z.B. die hier verwendeten RGB-LEDs vom Typ WS2812 oder WS2812B. Entsprechende LED-Produkte werden auch unter der Bezeichnung "NeoPixel" vertrieben. Es gibt sie in diversen Formen: als RGB LED-Streifen in verschiedenen Ausführungen (bis 144 LEDs/m), als LED-Ringe, LED-Matrix oder auch als einzelne RGB-LEDs im "klassischen" Gehäuse mit Anschluss-Drähten. 

Der Clou: Es lassen sich praktisch beliebig viele LEDs einzeln ansteuern, ohne irgendwelche zusätzlichen Treiber-Schaltungen und mit geringstem Verdrahtungsaufwand bzw. einfachster Ausführung der Leiterplatte! Und es wird dafür nur ein einziger Ausgangspin des Mikrocontrollers für die Steuerung aller angeschlossenen LEDs benötigt!

Das Prinzip:

Die Daten aller LEDs werden seriell über nur eine Signalleitung übertragen. Für jede einzelne LED enthält das Datenpaket jeweils drei Bytes mit den Helligkeitswerten (0..255) für die drei Farben: Grün, Rot, Blau (G R B). Die Daten für alle LEDs (1..n) werden dann einfach nacheinander gesendet:

G1 R1 B1 G2 R2 B2 G3 R3 B3 ... Gn Rn Bn

Aber woher weiß die einzelne LED (bzw. deren interner Controller), welche Daten für sie bestimmt sind? Das ergibt sich durch die Reihenfolge, in der die LEDs verschaltet sind! Die LEDs sind nämlich nicht parallel an der gemeinsamen Signalleitung angeschlossen, sondern jede LED hat einen Signal-Eingang und einen Signal-Ausgang, der mit dem Signal-Eingang der jeweils nachfolgenden LED verbunden ist:


Das komplette Datenpaket vom Mikrocontroller liegt nur am Dateneingang der ersten LED an. Diese übernimmt den ersten Datensatz (G1 R1 B1) für sich selbst und gibt alle weiteren Daten (ab G2 R2 ...) über den Daten-Ausgang an die zweite LED weiter. Aus Sicht der zweiten LED beginnt das Datenpaket also mit G2 R2 B2. Auch diese LED übernimmt wieder "ihre" ersten drei Datenbytes und leitet den Rest des Paketes (ab G3 ...) an die dritte LED weiter. So wird das Datenpaket von LED zu LED weitergereicht und immer kürzer, bis keine Daten mehr übrig sind oder bis die letzte LED ihre zugehörigen Daten empfangen hat.

Das Protokoll:

Die Schnittstelle der LED entspricht keiner der bei Mikrocontrollern gebräuchlichen seriellen Standard-Schnittstellen (wie z.B. UART), sondern erfordert eine spezielle Impulslängen-Modulation. Im Datenblatt der LED bzw. des Controllers (WS2811) wird das Protokoll und Timing genauer beschrieben. Der in der Praxis wichtige Teil des Timings lässt sich kurz wie folgt zusammenfassen:

  • Ein 0-Bit wird als kurzer High-Impuls mit einer Länge von 200ns ... 500ns übertragen
  • Ein 1-Bit wird durch einen High-Impuls von > 550ns übertragen (max. < 5µs)
  • Maximale Datenrate ist 800 KBits/s, d.h. >= 1,25µs zwischen den steigenden Flanken der Impulse
  • Ein Low-Signalpegel von > 5..6 µs markiert das Ende des Datenpakets (Sync- bzw. Reset-Pause)

Die Reset-Pause ist im Datenblatt mit min. 50µs angegegeben, allerdings zeigen Experimente, daß schon eine wesentlich kürzere Pause den Reset auslöst, daher dürfen die Abstände der Bit-Impulse innerhalb des Datenpakets etwa 5µs nicht überschreiten, um nicht irrtümlich als "Ende des Datenpakets" interpretiert zu werden! Erst in der Pause werden die vorher übertragenen Daten in die PWM-Register der LEDs kopiert, so daß dadurch alle LEDs nahezu gleichzeitig auf die neuen Farbwerte umschalten.

Tipps und Hinweise:

Die LEDs benötigen eine saubere Spannungsversorgung mit 5V! Das betrifft nicht nur den obligatorischen Bypass-Kondensator direkt an jeder LED, sondern auch die ausreichende Dimensionierung des Netzteils. Bei Weiß mit voller Helligkeit nimmt jede LED 60 mA Strom auf. Hat man z.B. einen LED-Streifen von 2m Länge mit 144 LEDs pro Meter, sind das nach Adam Riese 288 * 0.06 = schlappe 17,3 Ampere! Also bitte erst rechnen und die u.U. zu erwartende Stromaufnahme nicht unterschätzen!

Nicht zu vernachlässigen ist in diesem Zusammenhang auch der Widerstand der VCC- und GND-Leiterbahnen über die Länge des LED-Streifens. Wenn z.B. die Spannung vom Netzteil bei dem genannten 2m-Streifen nur an einem Ende eingespeist wird und viele LEDs hell geschaltet werden, kommt es bei weiter vom Einspeisepunkt entfernten LEDs zu einem deutlichen Spannungsabfall, der zu Funktionsstörungen führt. Ggf. muss man bei entsprechenden Anwendungen mehrere Einspeisepunkte am Streifen vorsehen, um zu große Spannungseinbrüche zu vermeiden!

Natürlich ist die Stromaufnahme entsprechend geringer, wenn immer nur wenige LEDs gleichzeitig hell geschaltet sind oder alle LEDs nur relativ schwach leuchten. Dann reicht evtl. auch ein schwächeres Netzteil und ein einzelner Einspeisepunkt am LED-Streifen aus.

An den Einspeisepunkten sollte jeweils ein 1000µF Elko (VCC-GND) angeschlossen werden. 

In der Signalleitung vom Mikrocontroller zur LED soll ein 300-500 Ohm Serienwiderstand eingebaut sein, nahe am Eingangspin der LED. Bei meinem Test-Streifen war ein 130-Ohm Widerstand eingelötet, das hat zwar recht lange funktioniert, doch plötzlich war die erste LED hin! Offenbar sind die Eingänge doch recht empfindlich.

Weitere Hinweise gibt es hier: https://learn.adafruit.com/adafruit-neopixel-uberguide/best-practices

Weiter geht's mit dem Hardware-nahen Teil der Implementation auf dem PIC12F1840.


Kontakt