Digi-Dot-Booster am Raspberry Pi mit Lua ansteuern

Nachdem ich den Digi-Dot-Booster ziemlich schnell auf dem Raspberry Pi mit Python zum Laufen gebracht habe, stellte sich mir die Frage, mit welchem Aufwand SPI in anderen Sprachen verwendet werden kann. Als Versuchsobjekt kam wieder der Digi-Dot-Booster zum Einsatz.
Bei der Auswahl der Sprachen stand die Verfügbarkeit der Bibliotheken zur einfachen Ansteuerung des SPI Buses im Vordergrund. Nach Python habe ich mir Lua angeschaut.

Lua ist eine leichtgewichtige und besonders in embedded Umfeld weit verbreitete Skriptsprache. Die aktuelle Version ist 5.3 und hat unter anderem ganz nützliche Erweiterungen bekommen wie z.B. die Bitweis Operatoren. Bei den Tests habe ich jedoch festgestellt, dass zum Einen die Version 5.3 unter Raspbian jessie nicht über den apt-Paktemanager zur Verfügung steht und zum Anderen der lua Paaketmanager luarocks aus dem jessie Repository gar auf Lua 5.1 aufbaut. Mit dem Wissen musste ich Lua 5.1 verwenden und einfache Operationen mit Hilfsmitteln umsetzen.

Installation:

`sudo apt-get update
sudo apt-get install lua5.1`

Es gibt einen Paketmanager für Lua namens luarocks – dieser erlaubt die Installation von  zusätzlichen Komponenten (rocks) auf einfache Weise, vor allem wenn diese noch weitere Abhängigkeiten haben. Unter anderem kann damit die Bibliothek lua-periphery für die SPI Steuerung installiert werden – man soll sich das Leben ja nicht unnötig schwer machen.

`sudo apt-get luarocks
sudo luarocks install lua-periphery`

Es gibt in Lua keinen Befehl wie `sleep` für eine blockierende Pause und es gibt auch keinen einfachen Weg eine Pause im Millisekunden-Bereich mit Sprachmitteln zu implementieren. Freundlicherweise stellt die lua-periphery Bilbliothek die nützlichen Funktionen `sleep`, `sleep_ms` und `sleep_us` zur Verfügung.

-- rainbow.lua
periphery = require("periphery")

local LED_COUNT = 30
local DELAY = 40 -- ms

-- open /dev/spidev0.1 (CS1 Pin wird verwendet), SPI mode 0, max 1 MHz
local spi = periphery.SPI("/dev/spidev0.1", 0, 1e6)

-- BOOSTER_INIT mit der Anzahl der LEDs und 24 bits pro LED (WS2812)
spi:transfer({0xB1, LED_COUNT, 24})
periphery.sleep_ms(DELAY)

function clear()
	-- BOOSTER_SETRGB 0x000000, BOOSTER_SETALL, BOOSTER_SHOW
    spi:transfer({0xA1, 0, 0, 0, 0xA5, 0xB2})
    periphery.sleep_ms(DELAY)
end

local i = 0
local runs = 200
while runs > 0 do
	i = 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:transfer({0xA7, i % 0x100, math.floor(i / 0x100), 255, 100, 0, LED_COUNT - 1, 10, 0xB2})
    periphery.sleep_ms(DELAY)
    runs = runs - 1
end

clear()
spi:close()

Was man auch hier im Vergleich zu der Python Version sehen kann: Lua kann nativ keine KeyEvents verarbeiten. Evtl. gibt es auch dafür eine Bibliothek, ich habe mich jedoch hier einfach auf eine feste Anzahl von Durchläufen beschränkt.
Wie schon erwähnt kann Lua 5.1 keine Bitwise Operatoren – daher wurden die Operationen `i & 0xFF` und `i >> 8`, um den Hue Wert auf 2 Bytes zu verteilen als `i % 0x100` und `math.floor(i / 0x100)` umgesetzt.

Zum Starten von der Konsole aus `lua rainbow.lua` eingeben.

Fazit: wie man sieht, ist es auch mit Lua ziemlich einfach SPI zu nutzen. Die lua-periphery Bibliothek kann auch noch einiges mehr ansteuern: GPIO, SPI, I2C, MMIO, Serial. Es gibt sogar Python und C-Versionen davon, die ich mir evtl. auch noch anschauen werde.

Schreibe einen Kommentar