Kurz gesagt: Ein Skript in /SCRIPTS/RGBLED/ liest deine Schalter, entscheidet den Flugzustand und färbt damit Ringe und Schalter. Fertig zum Download gibt es das im LED-Konfigurator für die TX16S MK3 – mit Live-Vorschau, ohne eine Zeile Code.
Neu bei EdgeTX? Drei Begriffe vorab
Lua ist eine kleine Skriptsprache, die EdgeTX direkt auf der Funke ausführt – damit lassen sich Funktionen nachrüsten, ohne die Firmware anzufassen. Eine Special Function ist eine Regel im Modell nach dem Muster „wenn Schalter X, dann tu Y“ (Ansage abspielen, Skript starten …). Der Mixer ist die Tabelle, die festlegt, welcher Stick oder Schalter auf welchem Kanal bei der Drohne ankommt.
Warum die LEDs mehr können sollten als Regenbogen
Beim FPV schaue ich vor dem Start nicht aufs Display. Die Brille hängt schon halb im Gesicht, die Drohne steht zwei Meter vor mir, und die wichtigste Frage ist: Ist sie gearmt? Genau dafür sind Licht und Farbe perfekt, weil man sie aus dem Augenwinkel wahrnimmt. Ein ruhiges Blau heißt „sicher“, ein kräftiges Rot heißt „Props können drehen“.
Die TX16S MK3 bringt dafür die Hardware schon mit: um jeden Gimbal einen Ring aus zehn RGB-LEDs und über dem Display sechs Schalter SW1–SW6, die ebenfalls in jeder Farbe leuchten können. EdgeTX liefert ein paar fertige Effekte mit, aber keiner davon weiß etwas über deine Drohne. Das ändert ein eigenes Lua-Skript.
Was die TX16S MK3 hergibt: 20 + 6 RGB-LEDs
| LEDs | Anzahl | Lua-Aufruf |
|---|---|---|
| Ring rechter Gimbal | 10 | setRGBLedColor(0…9, r, g, b) |
| Ring linker Gimbal | 10 | setRGBLedColor(10…19, r, g, b) |
| Schalter SW1–SW6 | 6 | setCFSLedColor("SW1", r, g, b) |
| alles anzeigen | – | applyRGBLedColors() |
Zwei Dinge sind wichtig. Erstens: Die set…-Funktionen schreiben nur in einen Puffer, sichtbar wird es erst mit applyRGBLedColors(). Zweitens: Die Schalter-LEDs gehören normalerweise EdgeTX, das damit anzeigt, ob ein Schalter an oder aus ist. Damit dein Skript sie übernehmen darf, musst du bei jedem Schalter „Lua override“ einschalten (Model Setup → Customizable Switches, für AN und AUS). Ohne diesen Haken passiert auf SW1–SW6 schlicht nichts – der häufigste Grund, warum solche Skripte „nicht gehen“.
Welcher Ring welche Indizes hat und wo LED 0 sitzt, solltest du an deiner eigenen Funke einmal prüfen: Bei mir liegt Ring 0 (LED 0–9) um den rechten Gimbal, und die LEDs laufen in 36-Grad-Schritten im Kreis. Ich rechne sie so, dass 0 Grad rechts und 90 Grad oben liegen – genau wie bei einem Stickausschlag. Dann kann man einen Leuchtpunkt direkt dem Stick folgen lassen.
Das Grundgerüst eines EdgeTX-RGBLED-Skripts mit setRGBLedColor
Ein LED-Skript ist ein normales EdgeTX-Lua-Skript, das eine Tabelle mit init, run und background zurückgibt. Es liegt in /SCRIPTS/RGBLED/ und wird über eine Special Function vom Typ RGB leds gestartet. Das kleinste sinnvolle Beispiel – Ringe rot, sobald der Arm-Schalter SF unten ist, sonst grün:
local function run()
local armed = getValue("sf") > 512 -- SF unten
local r, g = 0, 200
if armed then r, g = 255, 0 end
for i = 0, 19 do setRGBLedColor(i, r, g, 0) end
applyRGBLedColors()
end
return { run = run, init = function() end, background = function() end } Das funktioniert, hat aber zwei Schwächen. run() wird sehr oft aufgerufen – Farben 100-mal pro Sekunde neu zu schreiben kostet Rechenzeit, die die Funke lieber für Mixer und Telemetrie hat. Ich begrenze deshalb über getTime() (10-ms-Takt) auf etwa 33 Bilder pro Sekunde, das reicht für flüssige Animationen. Und „gearmt“ ist bei den meisten Piloten nicht einfach ein Schalter, sondern hängt von Prearm-Logik ab – dazu gleich mehr.
Zustände statt Schalter: die Prioritätsliste
Die eigentliche Idee ist, nicht Schalter anzuzeigen, sondern Zustände der Drohne. Mehrere Schalter können gleichzeitig aktiv sein, also braucht es eine feste Reihenfolge. Meine lautet:
- Return Home – nur wenn der Schalter aktiv ist und die Telemetrie GPS-Satelliten meldet (
getValue("Sats")). Ohne GPS gibt es kein Return Home (RTH), also auch keine Anzeige, die etwas Falsches verspricht. - Turtle – Flip over after crash: Nach einem Absturz dreht die Drohne einzelne Props rückwärts, um sich wieder auf die Füße zu stellen.
- Beeper – die Drohne piept, weil sie irgendwo im Feld liegt und gesucht wird.
- Disarmed
- Flugmodus – Acro, Angle oder Horizon.
Warnungen stehen oben, weil sie wichtiger sind als der Normalbetrieb. Wer den Beeper einschaltet, um eine abgestürzte Drohne zu suchen, soll das Suchmuster sehen, egal ob die Drohne formal noch gearmt ist.
Muster, die etwas bedeuten
Farben allein reichen nicht, weil man bei Tageslicht Orange und Rot schnell verwechselt. Deshalb gibt es für die Zustände eigene Bewegungsmuster, die zu ihrer Bedeutung passen – im Farbkonzept „Einzigartig“ des Konfigurators sind sie alle kombiniert:
Im Acro-Modus folgt auf beiden Ringen ein heller Punkt dem jeweiligen Stick. Das sieht nicht nur gut aus, sondern ist auch ein ehrlicher Stick-Check vor dem Start: Wenn der Punkt nicht dahin wandert, wo der Daumen hindrückt, stimmt etwas mit Kalibrierung oder Stick-Mode nicht.
Der Gasbalken auf SW1–SW6
Die sechs Schalter nebeneinander sind wie gemacht für einen Balken. Ich lese dafür nicht den Gas-Stick, sondern Kanal 3 nach dem Mixer (getValue("ch3")). Der Unterschied ist wichtig: Bei mir begrenzt die Funke das Gas je nach Rateprofil auf 70 oder 50 %. Der Stick sagt dann „Vollgas“, an der Drohne kommt aber nur die Hälfte an – und der Balken zeigt ehrlich die Hälfte. Warum das Gaslimit bei mir in der Funke sitzt statt in Betaflight, erkläre ich im Artikel über den Flotten-Standard mit den Betaflight-Rateprofilen FAST, SLOW und SNAIL.
Je nach Profil wechselt auch die Farbe: Grün nach Rot für FAST, ein Lila-Rosa-Verlauf für die langsamen Profile. So sehe ich beim Blick auf die Funke, welches Profil aktiv ist, ohne das Display zu lesen.
Stolperfallen aus der Praxis
- setRGBLedColor(20…25) für die Schalter funktioniert nur, wenn der Schalter keine Funktion hat (Typ NONE). Für echte Schalter immer
setCFSLedColormit dem Schalternamen nehmen. - Helligkeit nicht doppelt anwenden. Ich dimme alle Farben über einen Faktor aus einer globalen Variable (nachts auf 20 %). Der erste Gedanke war,
setRGBLedColordafür global zu überschreiben – damit läuft man aber Gefahr, manche Farben zweimal zu dimmen. Besser: eigene kleine Wrapper-Funktionen im Skript. - Kleine Werte flackern. Sehr niedrige Helligkeiten (unter etwa 5 %) sehen auf den LEDs unruhig aus. Der Balken schaltet deshalb unterhalb einer Schwelle ganz ab.
- Stick-Mode beachten.
getStickMode()liefert den Mode 1 bis 4 und damit, welche Achsen auf welchem Stick liegen. Wer das ignoriert, sieht den Punkt im Mode 1 am falschen Ring. - Nichts blockieren. Keine Schleifen, die warten, keine Dateizugriffe in
run(). Das Skript läuft neben dem Mixer, und der hat Vorrang.
Der Konfigurator: zusammenklicken statt programmieren
Weil das Ausprobieren von Farben direkt auf der Funke mühsam ist (Skript ändern, SD-Karte, Modell neu laden, gucken), habe ich mir eine Vorschau im Browser gebaut – und sie jetzt für alle freigegeben. Der LED-Konfigurator für die TX16S MK3 zeigt eine simulierte Funke, deren Sticks sich zufällig bewegen, damit man die Effekte in Bewegung sieht. Du wählst ein Farbkonzept, passt jeden Zustand an, trägst ein, welcher Schalter bei dir Arm, Flugmodus, Turtle und Beeper ist, und lädst das fertige Skript herunter. Die Effekte im Browser rechne ich mit denselben Formeln wie im Lua-Skript. Ehrlicherweise: Auf meiner eigenen Funke fliege ich bisher Atmen, Stick-Punkt, Halbkreise und Blinken – Radar, Heimweg-Welle und Horizont-Linie habe ich bisher nur in der Vorschau getestet. Falls dir auf deiner MK3 etwas anders vorkommt als in der Vorschau, schreib es in die Kommentare.
Und wenn mein Arm-Schalter kein einfacher Schalter ist?
Der öffentliche Konfigurator fragt einen Arm-Schalter und eine Stellung ab – das passt für die meisten Setups. Bei mir ist „gearmt“ komplizierter: Ich arme mit einem Prearm-Fenster, das nur zehn Sekunden nach einem Tastendruck offen ist, und der Arm-Zustand steckt in einem Logical Switch. Mein eigenes Skript liest deshalb diesen Logical Switch statt eines Schalters. Wie dieses Prearm-Fenster aufgebaut ist und warum die Disarm-Ansage bei mir nur beim echten Disarm kommt, steht in Prearm mit 10-Sekunden-Fenster in EdgeTX. Alle weiteren Anleitungen zu meiner Funke sammle ich unter TX16S MK3 Tutorials.
Und falls die Ringe „armed“ zeigen, der Kopter aber nicht anläuft: Dann blockiert Betaflight selbst. Die Gründe stehen in Betaflight Arming Disabled Flags erklärt.
Dein Setup ist anders?
Anderer Arm-Schalter, kein Beeper, Ringe in anderer Reihenfolge? Schreib es unten in die Kommentare – was mehrere brauchen, baue ich in den Konfigurator ein. Und falls du über mein Instagram-Video (FLYWURST) hier gelandet bist: Das ist genau das Skript, das du dort auf der Funke gesehen hast, nur mit meiner eigenen Arm-Logik.
Häufige Fragen
Wie viele LEDs hat die TX16S MK3?
Je Gimbal-Ring zehn RGB-LEDs, zusammen 20. Dazu kommen sechs RGB-Schalter (SW1–SW6) mit je einer LED. In Lua sind die Ringe die Indizes 0–19 von setRGBLedColor, die Schalter sprichst du über setCFSLedColor mit dem Schalternamen an.
Wo muss das LED-Skript auf der SD-Karte liegen?
Im Ordner /SCRIPTS/RGBLED/. Gestartet wird es über eine Special Function (oder Global Function) vom Typ „RGB leds“, in der du das Skript auswählst.
Was macht applyRGBLedColors()?
setRGBLedColor und setCFSLedColor schreiben nur in einen Puffer. Erst applyRGBLedColors() schickt alle Farben auf einmal an die LEDs. Deshalb alle Farben eines Bildes setzen und dann einmal anwenden.
Ab welcher EdgeTX-Version geht das?
setRGBLedColor und applyRGBLedColors gibt es seit EdgeTX 2.10. setCFSLedColor für die Schalter-LEDs und getStickMode stehen laut Quellcode ab 2.12 bereit, die TX16S MK3 wird ohnehin erst ab 2.12 unterstützt. Ich selbst fliege mit einem EdgeTX-3.0-Build.
Warum reagieren SW1–SW6 nicht auf mein Skript?
Bei den Customizable Switches muss „Lua override“ eingeschaltet sein. Sonst gehört die Schalter-LED weiter EdgeTX. setRGBLedColor auf die Indizes 20–25 funktioniert nur, wenn der Schalter gar keine Funktion hat (Typ NONE) – für echte Schalter immer setCFSLedColor nehmen.
Kommentare
Noch keine Kommentare — schreib den ersten!