ich steuere über einen Arduino Uno einen adressierbaren LED-Strip an (Port 3). Dies mache ich über die FastLED Bibliothek per FastLED.show(). Das funktioniert auch wunderbar.
Zusätzlich möchte ich über tone() Töne auf einen Lautsprecher ausgeben (Port 7 über eine Transistorschaltung angebunden). Auch das funktioniert wunderbar alleine.
Problem:
Wenn ich versuche einen Ton auszugeben der über mehrere loop()-Schleifen zu hören ist wird mir bei jeder Schleife durch den FastLED.show() Befehl der Ton unterbrochen, was bei 10 Schleifen pro Sekunde zu einem unschönen stottern/scheppern führt.
Bisherige Fehlersuche:
aukommentieren des FastLED.schow() Befehls -> saubere konstante Tonausgabe (es liegt also definitiv an diesem Befehl)
Portwechsel des LED-Strips bzw. der Lautsprecherausgabe auf andere Ports -> Problem bleibt
Abklemmen der Data-Leitung des LED-Strips vom Arduino -> Problem bleibt
Kennt jemand dieses Problem oder hat eine Idee?
Danke.
Ohne jetzt eine einzige Zeile code angeguckt zu haben: möglicherweise nutzen beide Bibliotheken den selben Timer zur erzeugung von PWM.
Dann könnte es sein das FastLED.show den Timer zurücksetzt und es dadurch für einen kurzen Durchlauf den Ton verändert. Wenn das oft genug passiert klingt das wie ein kracksen oder wie ein China-Spielzeug bei dem die Batterie leer ist.
Ich hatte sowas auch mal (ton und softPWM war es bei mir glaube ich). Habe dann eine eigene Bibliothek geschrieben die Ton und PWM erzeugt und konnte damit dem Problem ausweichen.
Das Protokoll zur Ansteuerung der WS2812 ist sehr schnell (800kHz) und die Zeiten der HIGH- und LOW-Impulse sind sehr zeitkritisch (0,15µS Genauigkeit sind erforderlich) Das erreicht man nur wenn der Ausgabeteil in Maschinensprache direkt den Ausgang angpricht und man jegliche Unterbrechung sprich Interrupt verhindert wird.
Darum wird die Tonausgabe während der Übertragung der Daten an die LED unterbrochen.
Die einzige Lösung sehe ich, die Tonerzeugung von der LED-Ansteuerung zu trennen. Das entweder durch Verwendung von 2 Arduinos oder durch ein TongeneratorIC wie zB einen Midisyntiseiser wie den VS1053B. Ich kenne jetzt kein einfacheres IC der nur ein Rechtecksignal mit einer gewissen Frequenz ausgibt.
as31:
Problem:
Wenn ich versuche einen Ton auszugeben der über mehrere loop()-Schleifen zu hören ist wird mir bei jeder Schleife durch den FastLED.show() Befehl der Ton unterbrochen, was bei 10 Schleifen pro Sekunde zu einem unschönen stottern/scheppern führt.
Wahrscheinlich verwendest Du die falschen LEDs für Dein Vorhaben
Wenn Du LEDs mit WS2811 Controller verwendest, z.B. auch WS2812-LEDs mit eingebautem WS2811-Controller, dann werden diese rein über das Timing angesteuert und Deine Library blockiert alle Interrupts auf dem Controller während des FastLED.show() Befehls, um das sehr enge Timing einzuhalten. Ohne Blockierung von Interrrupts kann diese Art LEDs mit 8-Bit AVR Controllern nicht zuverlässig befeuert werden.
Wenn Du LEDs mit WS2801-Controller und Clock-Leitung verwenden würdest, dann wäre das Timing beim Ansteuern der LEDs sehr viel zeittoleranter und die Interrupts können weiterlaufen, z.B. für die exakte Zeitzählung (millis(), micros()) und auch Servosteuerung, Tonausgaben, serieller Empfang etc.
Entweder brauchst Du zwei Controller, die Du synchronisieren mußt, so dass die Blockierung während FastLED.show() keine negativen Auswirkungen auf die Ansteuerung der übrigen Hardware hat.
Oder Du brauchst LEDs mit ansteuerbarer Clock-Leitung für zeittolerante Ansteuerung, z.B. WS2801.
Wow - vielen Dank für die schnelle und plausible Erklärung.
Ich werde die beiden Lösungsansätze (zwei Arduinos bzw. zwei eigene Timer) mal weiter verfolgen.
Auf eine LED mit Clock würde ich nur ungern umsteigen, da die LEDs jetzt schon fertig verbaut sind.
Danke nochmal und noch einen schönen Adventssonntag...
Das wird sich auch nicht ändern. Für die WS2811/12 brauchte es des richtige Timing und das erreicht man nur mit Assembler und gesperrte Interrupts. Da kann kein anderes Programm/Bibliothek zwischenzeitlich mal einen Ausgang setzen/löschen.