Digi-Dot-Booster am Raspberry Pi mit Python ansteuern

Folker hat gerade den Digi-Dot-Booster angekündigt und ich hatte die Möglichkeit, mich  schon im Vorfeld  etwas damit zu beschäftigen. Zur Ansteuerung kamen bei den Tests unterschiedliche Boards, die ich in meiner Bastler-Kister habe. Am Interessantesten neben Arduino ist sicherlich Raspberry Pi und darum geht es auch im folgenden Beitrag.

Zum Testen habe ich den schon etwas älteren Rapberry Pi B genommen, als Betriebssystem kommt Raspbian zum Einsatz. Bei mir habe ich die grafische Oberfläche deaktiviert, weil ich hauptsächlich damit ohne Maus und Tatstatur per SSH arbeite.

Zum Programmieren habe ich mich für Python entschieden – die Sprache ist weit verbreitet und viele hatten schon mal damit zu tun gehabt. Man muss sich außerdem keine Gedanken um low-level APIs von C und das Kompilieren machen. Rasbian bringt auch eine Entwicklungsumgebung (IDE) für Python mit (https://www.raspberrypi.org/documentation/usage/python/) – man kann also auch direkt auf dem RPi komfortabel programmieren und direkt aus der IDE seine Programme laufen lassen und debuggen.

Der Digi-Dot-Booster wird entsprechend an die SPI Port Pins des GPIO Headers angeschlossen. Da der Digi-Dot-Booster keine Daten zurück schickt, wird nur die MOSI Leitung fürs Senden angeschlossen. RESET Pin kann optional angeschlossen werden, um den Reset des Moduls vom RPi aus im Code steuern zu können.

Anschluß vom LED-Booster am RPi B

Damit man mit Python auf die Hardware des Raspberry Pi zugreifen kann, müssen zusätzliche Bibliotheken installiert werden:

`sudo apt-get update
sudo apt-get install python-dev python-rpi.gpio python-spidev`

In Rapsbian ist SPI standardmäßig deaktiviert, das Aktivieren geht am einfachsten über das eigene Config-Tool:

`sudo raspi-config -> 5 Interfacing Options -> SPI`

Nach einem Reboot des RPi sollten dann `/dev/spidev0.0` und `/dev/spidev0.1` im System auftauchen.

Nun steht der Arbeit mit dem Digi-Dot-Booster nichts mehr im Wege. Hier ist ein Beispiel zur Ansteuerung von 30 ws2812 LEDs über den Digi-Dot-Booster:

# rainbow.py
import spidev
import time

DELAY = 0.04
LED_COUNT = 30

spi = spidev.SpiDev()

def initSPI():
    # open /dev/spidev0.1 (CS1 Pin wird verwendet)
    spi.open(0, 1)  
    spi.mode = 0b00
    return

def initLEDs():
    # BOOSTER_INIT mit der Anzahl der LEDs und 24 bits pro LED (WS2812)
    spi.writebytes([0xB1, LED_COUNT, 24])
    time.sleep(DELAY)
    return


def clear():
    # BOOSTER_SETRGB 0x000000, BOOSTER_SETALL, BOOSTER_SHOW
    spi.writebytes([0xA1, 0, 0, 0, 0xA5, 0xB2])
    time.sleep(DELAY)
    return

i = 0
initSPI()
initLEDs()

try:
    while True:
        i += 5
        i = i % 360
        # BOOSTER_SETRAINBOW HUE (2 Bytes), SATURATION, VALUE, von der ersten (0) bis
        # zur letzten LED in 10-er Schritten, BOOSTER_SHOW
        spi.writebytes([0xA7, i & 0xFF, i >> 8, 255, 100, 0, LED_COUNT - 1, 10, 0xB2])  
        time.sleep(DELAY)
except KeyboardInterrupt:
    clear()
    spi.close()

Zum Starten von der Konsole aus `python rainbow.py` eingeben.

 

Update: Durch die Konfiguration des richtigen SPI Modes per `spi.mode = 0b00`  ist keine Steuerung des CS im Code notwendig.

14 Gedanken zu „Digi-Dot-Booster am Raspberry Pi mit Python ansteuern

  1. Hallo ich sitz grad ein bisschen ratlos vor dem Quellcode

    Wenn ich es richtig verstanden hab muss ich ja nur diese zeile ändern wenn ich was anderes haben möchet
    spi.writebytes([0xA7, i & 0xFF, i >> 8, 255, 100, 0, LED_COUNT – 1, 10, 0xB2])

    Da das die Zeile für das BOOSTER_SETRAINBOW ist

    wenn ich jetzt z.b. BOOSTER_SETRANGE haben will
    spi.writebytes([0xA6, 0, 0, 255, LED_COUNT – 1, 5, 0xB2])

    irgend wie steh ich total auf dem schlauch
    irgend wo hab ich einen denk fehler drinn

  2. Hallo wosjack,
    im Prinzip richtig, nur ist der Befehl falsch. Laut Dokumentation vom DD-Booster hat der Befehl BOOSTER_SETRANGE folgende Struktur: 0xA6 BEG END. D.h. 0xA6 steht für den Befehl selbst, BEG für den Startindex – also z.B. 0, END für Endindex – also z.B. 4. Dabei wird die aktuelle Farbe aus dem Farbregister genommen, also muss man davor noch BOOSTER_SETRGB oder BOOSTER_SETHSV aufrufen.
    Beispiel: spi.writebytes([0xA3, i & 0xFF, i >> 8, 255, 100, 0xA6, 0, 4, 0xB2])
    Heißt, mit 0xA3 wird die Farbe in H (2 erste Werte), S (255), V (100) Format gesetzt, mit 0xA6 wird der Bereich von LED 0 bis LED 4 auf diese Farbe gesetzt und mit 0xB2 (BOOSTER_SHOW) bestätigt.

  3. Hallo,

    leider bekomme ich es nicht zum laufen. Ich habe einen Raspberry Pi 3 Model B den DD-Booster und einen W2812B LED Streifen. Habe alles so angeschlossen wie in der Schematic beschrieben, Python installiert und SPI aktiviert.

    spidev0.0 und /dev/spidev0.1 sind ebenfalls vorhanden.

    Habe das obige Beispielscript in einer Datei erstellt, die Anzahl der LED auf 25 reduziert da mein Streifen nur 25 hat und in der Konsole wie genannt aufgerufen, allerdings passiert nichts. Die LED beim Booster blinkt auch konstant.

    Wäre für Hilfe dankbar, Thorsten

  4. Habe das Problem in meiner Verdrahtung entdeckt – Masse war falsch verbunden, dann hat auch die rote LED auf dem BB-Booster leicht geleuchtet statt geblinkt. Die Belegung der Pins bleibt die gleiche wie auf dem Bild für RPi1, man muss nur von oben vom Pin 1 aus nach unten die Pins abzählen.

  5. Ich hab ziemliche Probleme das board auf einem PiZero W zum laufen zu bekommen.

    Die verdrahtung sieht korrekt aus (auf angepasste Pi3 pins). Aber wenn ich befehle schicke passiert:
    1. die rote übertragungs-LED blinkt erst mit mehreren sekunden verspätung
    2. ca 10s nachdem die rote LED reagiert wird erst der erste befehlt bearbeitet.

    Irgendwie scheint es als wäre alles unglaublich verlangsamt. Auf einem klassischen Rpi hatte ich diese Probleme nicht.

    Hat jmd eine idee?

    • I’ll post my fix in english, in case anyone finds this on google:

      I had massive SPI delay problems. The cause seems to be a wrong clock speed to which the SPI clock is connected.

      So first we need to fix the clock speed. Open up /boot/config.txt and set the following settings:
      core_freq=200
      core_freq_min=200

      this locks the clock to 200MHz. Some people suggest 250, but 200 works a lot better in my case.

      Additionally forcing HDMI audio will remove the chance of the system using the GPIO for audio stuff, blocking it for SPI:
      hdmi_force_hotplug=1
      hdmi_force_edid_audio=1

      Some people suggest blacklisting the broadcom sound driver, but it didn’t make a difference in my case. If you want to:
      create the file
      /etc/modprobe.d/snd-blacklist.conf
      with the content:
      blacklist snd_bcm2835

      Increase the SPI buffer. Normally the buffer is only 4k. you can increase it by adding
      spidev.bufsize=32768
      to the end of
      /boot/cmdline.txt

      Note that it’s a single line. Don’t use a linebreak!

      reboot the system.

      This kindof seems to work for me. For some reason the maximum data package can’t be too big. Only a couple of bytes in size (<10. Theoreticly it should be possible to send up to 256bytes to the booster).

      If someone has a better fix, please let me know. In my case it will work for now (I hope).

  6. Wie kann ich die Helligkeit einer einzellenen LED einstellen?
    Ich verwende BOOSTER_SETRGB um RGB Werte zu setzen aber möchte die Helligkeit jeweils anpassen.

    Danke

  7. Die Helligkeit kann man nicht über einen separaten Befehl steuern. Am einfachsten ist es mit dem HSV Farbmodell, wo der letzte Wert die Helligkeit bestimmt. Beim RGB Modell muss man die Werte selbst proportional runter rechnen. Sprich wenn #F00 – Rot in voller Helligkeit ergibt, würde #800 weniger helles Rot ergeben.

  8. Ich habe den Digi-Dot-Booster nach Verdrahtung oben an einen Raspi 3B angeschlossen. Am Ausgang hängen 3 WS2812B. SPI ist akitivert und die python3 Bibliotheken installiert.
    Als Programm habe ich das Beispiel genommen und modifiziert:

    # rainbow.py
    import spidev
    import time

    DELAY = 0.04
    LED_COUNT = 3

    spi = spidev.SpiDev()

    def initSPI():
    # open /dev/spidev0.1 (CS1 Pin wird verwendet)
    spi.open(0, 1)
    spi.mode = 0b00
    return

    def initLEDs():
    # BOOSTER_INIT mit der Anzahl der LEDs und 24 bits pro LED (WS2812)
    spi.writebytes([0xB1, LED_COUNT, 24])
    time.sleep(DELAY)
    return

    def clear():
    # BOOSTER_SETRGB 0x000000, BOOSTER_SETALL, BOOSTER_SHOW
    spi.writebytes([0xA1, 0, 0, 0, 0xA5, 0xB2])
    time.sleep(DELAY)
    return

    i = 0
    initSPI()
    initLEDs()

    try:
    while True:
    print(‚i = ‚,i)
    i = i + 1
    spi.writebytes([0xA1, 128, 128, 128, 0xA5, 0xB2])
    time.sleep(DELAY)
    except KeyboardInterrupt:
    clear()
    spi.close()
    Nachdem Einschalten des Raspis blinkt die rote LED schnell, wenn der Desktop geladen ist, ca. 1x die Sekunde kurz. WIrd das Programm ausgeführt, flackert die rote LED. An dem LED-Streifen kommen die +5V an.

    Leider leuchten die LEDs nicht. Was kann ich prüfen? Ich finde keine weiteren Demos.

    • Ich habe das Setup mit der neuen Pin Belegung und einer externen Stromquelle. Leider bekomme ich beim Ausführen von rainbow.py nur das flackern vom Digi-Dot-Booster, bei der LEDLeiste passiert nichts.

  9. Hi there,

    I also could not get it working but solved it:

    SPI bus speed even from my old PI was above 12 MHz. All was working as soon as I added this line to the init routine:

    spi.open(0, 1)
    spi.mode = 0b00
    spi.max_speed_hz = 10000000

    The first two lines are from the standard script for reference. The third line is my finding how to make it work. Now it is so robust, I keep on using this system for all my installation.

    Have fun!

    Cheers,
    Horst

Schreibe einen Kommentar