LED Streifen mit SK6812 für Hintergrundbeleuchtung

In einigen Bereichen wollen wir eine farbige Hintergrundbeleuchtung per LED erzeugen. Dazu haben wir nach passenden LED Streifen gesucht. Die meisten Streifen lassen sich per RGB Signal steuern. Dies bedeutet, dass alle LEDs des LEDs Streifen immer genau die gleiche Farbe habe. Inzwischen gibt es aber auch einige Streifen, bei denen man jede LED einzeln ansteuern kann. Zu diesen Streifen gehören der WS2801 und der SK6812, für den wir uns entschieden haben.

Mokona und der SK6812

Was ist der SK6812

Der SK6812 ist ein kleiner Mikrocontroller, der mit einer RGBW LED bestückt ist. Dies bedeutet, dass man für jeden einzelnen Punkt auf dem Streifen festlegen kann, welchen RGBW Wert er bekommen soll. Dazu sind die Mikrocontroller über einen sehr einfachen Bus miteinander verbunden. Dieser Bus wird mit 800kHz Takt angesprochen. Dabei ist es so, dass der SK6812 sobald er neue Daten auf dem Eingang bekommt, die bisherigen Daten auf den Ausgang schiebt und somit an den nächsten Mikrocontroller auf dem Bus.

Der Vorteil des SK6812 gegenüber dem WS2801 ist, dass es auch eine weiße LED gibt. Somit ist es leichter möglich, weißes Licht zu erzeugen.

Einrichten des SK6812 auf dem Raspberry Pi

Wir wollen den Streifen erst einmal über einen Raspberry ansteuern, weil dies besonders einfach ist. Hier können wir einfach die Steuerung per Python umsetzen. Ob später mal eine Steuerung über den Pokeys dazu kommt, müssen wir noch evaluieren.

Als erstes muss der Streifen angeschlossen werden. Wir nutzen gleich ein externes Netzteil, so dass wir den Streifen nur an den Datenbus des Raspberry anschließen. Dazu verwenden wir den Pin 18, der PWM unterstützt.

Um das ganze einzurichten müssen nacheinander folgende Befehle ausgeführt werden:

sudo apt-get update
sudo apt-get install gcc make build-essential python-dev git scons swig

git clone https://github.com/jgarff/rpi_ws281x

cd rpi_ws281x/
sudo scons

cd python
sudo python setup.py build
sudo python setup.py install

Die Befehle folgen dabei der Anleitung in diesem Blog-Eintrag für den WS2812. Die Bibliothek unterstützt auch direkt den SK6812.

Da wir PWM verwenden muss auch noch das Soundmodule der ARM CPU deaktiviert werden. Andernfalls könnte es zu Störungen kommen:

sudo nano /boot/config.txt

und dort am Ende der Datei

dtparam=audio=on

auskommentieren:

#dtparam=audio=on

Dann noch das nachträgliche Laden des Modules unterbinden:

sudo nano /etc/modprobe.d/snd-blacklist.conf

und

blacklist snd_bcm2835

einfügen.

Nach einen Systemneustart kann mit dem Befehl:

lsmod

nachgeschaut werden ob das  „snd_bcm2835“ Module nicht mehr geladen ist. Es sollte in der Auflistung nicht mehr auftauchen.

Beispiele zum Ansteuern des Streifen

Jetzt können wir einfach ein Python Test-Skript zusammen stellen. Dazu benötigen wir die folgenden Parameter zum Initialisieren:

from neopixel import *
 
# LED strip configuration:
LED_COUNT      = 300     # Number of LED pixels.
LED_PIN        = 18      # GPIO pin connected to the pixels (18 uses PWM!).
LED_FREQ_HZ    = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA        = 10       # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 255     # Set to 0 for darkest and 255 for brightest
LED_INVERT     = False   # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL    = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53
LED_STRIP      = ws.SK6812_STRIP_GRBW   # Strip type and colour ordering

# Create NeoPixel object with appropriate configuration.
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
# Intialize the library (must be called once before other functions).
strip.begin()

Der Parameter „LED_DMA“ sollte auf 10 gestellt werden. Ältere Versionen der Library haben den Channel 5 verwendet. Dies funktioniert jedoch mit einer aktuellen Raspbian Version nicht mehr.

Jetzt reichen zwei einfache Befehle, um die Farben zu setzen und die Daten an den LED Streifen zu senden. Mit dem Befehl strip.setPixelColor wird die Farbe eines einzelnen Pixels gesetzt. Mit dem Befehl strip.show werden dann die aktuell gesetzten Farben angezeigt. Diese beiden Funktionen werden in den folgenden Beispielen verwendet.

Am einfachsten ist es erst einmal, die Farben für den gesamten Streifen zu setzen. Hierzu müssen einfach alle LEDs auf eine Farbe gesetzt werden und dann angezeigt werden.

for i in range(strip.numPixels()):
    strip.setPixelColor(i, Color(255,0,0))
strip.show()

Wichtig ist, dass das Script als Admin also mit sudo und mit Python 2 ausgeführt wird. Nur so kann der Zugriff auf den entsprechenden Speicher für die PWM stattfinden. Ansonsten bekommt man eine Fehlermeldung. Wenn alles funktioniert dann leuchtet der LED Streifen rot.

Einfacher Farbverlauf der rotiert

Als nächstes bauen wir einen Regenbogen, der langsam durch rotiert. Dazu brauchen wir einen Endlosschleife.

RUN_COLORS = [
 (255,0,0),
 (0,255,0),
 (0,0,255),
 (255,0,0)
]

l = strip.numPixels()
lc = len(RUN_COLORS) - 1
bl = l / lc
while True:
    for startPos in range(l):
        for i in range(l):
            relPos = (i - startPos) % bl
            block = (i - startPos) // bl %lc 
            factors = (relPos * 1.0 / bl , (bl - relPos)*1.0 / bl)

            red = RUN_COLORS[block+1][0] * factors[0] + RUN_COLORS[block][0] * factors[1]
            green = RUN_COLORS[block+1][1] * factors[0] + RUN_COLORS[block][1] * factors[1]
            blue = RUN_COLORS[block+1][2] * factors[0] + RUN_COLORS[block][2] * factors[1]
            color = Color(int(red),int(green),int(blue))
            strip.setPixelColor(i, color)

        strip.show()
        time.sleep(50/1000.0)

Der wichtigste Teil des Skriptes ist die Berechnungsformel für die Farben der einzelnen Pixel. Hierzu wird der Streifen in Blöcke für die einzelnen Farbverläufe zerlegt und dann anhand der Blöcke die einzelnen Farben berechnet und um die aktuelle Startposition verschoben.

Damit der Farbverlauf langsam genug rotiert, nutzen wir die time.sleep Funktion. hierzu muss das time Module mit import time importiert werden. Dies kann ganz am Anfang des Skriptes passieren.

Feuereffekt

Als nächstes wird eine Art Feuereffekt umgesetzt. Hierzu wird ein Zufallsgenerator benötigt. Dieser wählt zufällig Punkte aus, an denen die Helligkeit erhöht wird. Daneben werden in jeder Runde aus den Nachbarpunkten die aktuelle Farbe berechnet und die Farbe langsam abgeschwächt.

l = strip.numPixels()
actColors = [[0,0,0]] * l
for i in range(l):
    actColors[i] = [20,0,0]
numOfNewValues = 8
for i in range(l):
    strip.setPixelColor(i, Color(actColors[i][0], actColors[i][1], actColors[i][2]))
strip.show()
time.sleep(self.wait_ms/1000.0)

while True:
    for i in range(numOfNewValues):
        index = random.randrange(l)
        actColors[index][0] = min(actColors[index][0] + 100, 255)
        actColors[index][1] = min(actColors[index][1] + 60,255)
       
    oldColors = actColors
    actColors = [[0,0,0]] * l

    for i in range(l):
        act = oldColors[i]
        right = oldColors[(i+1) % l]
        left = oldColors[(i-1) % l]
        actColors[i] = [max(right[0]//6 + act[0]*2//3 + left[0]//6 - 2,0),max(right[1]//6 + act[1]*2//3 + left[1]//6 - 5, 0), 0]
    
    for i in range(l):
        strip.setPixelColor(i, Color(actColors[i][0], actColors[i][1], actColors[i][2]))
    strip.show()
    time.sleep(self.wait_ms/1000.0)

Man muss etwas experimentieren, wie viele zufällige Punkte man für ein stabiles Ergebnis braucht. Dies ist von der Länge der Streifen und der gewünschten Helligkeit abhängig.

2 Antworten auf „LED Streifen mit SK6812 für Hintergrundbeleuchtung“

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.