Ich habe wieder mal ein Problem. Ich habe wieder mal Zeit gefunden mich an mein kleines Projekt gesetzt. Ich habe ein Raspberry Pi 3, mit dem steuere ich momentan die WS2812 an. Allerdings möchte ich das nicht mehr tun, da die einzigen PWM-Pins für den Audioausgang des Pi sind.
Nun wollte ich einen Arduino UNO über eine Schnittstelle einsetzten um die WS2812 anzusteuern. Habt ihr Tipps welche Schnittstelle ich da am besten benutzen sollte oder hat jemand Erfahrung mit einem ähnlichem Projekt?
Wenn's doch ein Master-Slave-Verhältnis werden soll: I²C kann der Arduino ganz gut - vll. So die Daten der LEDs zum Arduino bringen, sofern der RPi Das nicht komplett abgibt.
HotSystems:
Wieso verwendest du einen PWM-Ausgang für die WS2812 ?
Mit der richtigen Library kannst du jeden beliebigen Pin verwenden.
Soweit mir bekannt ist.
Ich habe aktuell die Neopixel Bibliothek da ich mit dieser relativ viel auf dem Arduino gemacht habe. Diese benötigt einen PWM-Ausgang.
postmaster-ino:
Hi
Wenn's doch ein Master-Slave-Verhältnis werden soll: I²C kann der Arduino ganz gut - vll. So die Daten der LEDs zum Arduino bringen, sofern der RPi Das nicht komplett abgibt.
MfG
Ist I²C schnell genug? Ich habe 13x13 LEDs (also 169 LEDs) zur normalen Ausgabe mit dem Arduino Uno bräuchte ich schon 5,07 ms, wenn ich korrekt gerechnet habe. Da ich allerdings 30 FPS erreichen möchte und dort dann eine Zeit von 30ms pro Frame habe bleiben mir noch ca. 25ms zum Übertragen und Auswerten.
Ich weis zwar nicht wie schnell der I²C-Bus überträgt, aber ich denke wenn dieser 676 Bytes in 5ms übertragt wäre das kein Problem. Ich komme auf die Byteanzahl weil ich 4 Bytes genommen habe, 1 Byte für die Adressierung der LED und die anderen drei für die Farbe.
Wo hast du das gelesen, dass ein PWM-Pin gebraucht wird ?
In sämtlichen Beiträgen, die ich bisher darüber gelesen habe, wird ein beliebiger digitaler Pin benötigt.
Die WS2812 haben einen eigenen Controller, der die PWM pro Led erzeugt.
HotSystems:
Wo hast du das gelesen, dass ein PWM-Pin gebraucht wird ?
In sämtlichen Beiträgen, die ich bisher darüber gelesen habe, wird ein beliebiger digitaler Pin benötigt.
Die WS2812 haben einen eigenen Controller, der die PWM pro Led erzeugt.
In der Bibliothek Adafruit NeoPixel steht es drin. und wenn ich einen anderen Pin versucht hab hat es nicht funktioniert. Zumindest nicht beim Raspberry Pi 3, und ich meine beim Arduino UNO ebenfalls nicht.
bdorer:
In der Bibliothek Adafruit NeoPixel steht es drin. und wenn ich einen anderen Pin versucht hab hat es nicht funktioniert. Zumindest nicht beim Raspberry Pi 3, und ich meine beim Arduino UNO ebenfalls nicht.
Ok, dann fehlen mir die Argumente.
Ich selbst habe die Neopixel bisher nicht verwendet, allerdings mehrfach gelesen, das es jeder digitale Pin auch tut. Ich werde es aber bei Gelegenheit mal testen.
Evtl. meldet sich ja mal einer, der das schon kennt.
Also ich kann nur vom Atmega sprechen. Da tut es die Lib an beliebigen Pins.
Raspi wollte ich demnächst mal probieren.
Ahhh, gerade mal gelesen. Die NEO-Pixel lib beim Raspi brauch in der Tat einen PWM - Pin und zwar
nicht um damit Helligkeit zu regeln (wäre bei WS2812 auch Käse und ging gar nicht) sondern
um das recht anspruchsvolle Timing der 2812 Stripes auch im Multitaskingenvironment
des Raspi hin zu kriegen. Also da hast du Recht.
Aber beim Arduino (oder anderen Atmegas) geht das wirklich an jedem Pin. Man sollte
dann allerdings keine Interrupts mehr benutzen, sonst ist das Timing hin.
HotSystems:
Danke für deine Bestätigung. Konnte mir nicht vorstellen, dass ich mich so "verlesen" habe.
Sry dann habe ich mich geirrt.
Also werde ich eine Kommunikation brauchen vom Raspberry Pi zum Arduino. Wie oben schon gefragt reicht die I²C-Schnittstelle mit der Geschwindigkeit. Da ich nachher Musik per Bluetooth an den Raspberry Pi schicken will und dann die LEDs dazu leuchten sollen, sollten ca 30 FPS schon möglich sein.
Es gibt PC-Programme, die für die Kommunikation mit dem Arduino die serielle Schnittstelle mit hohen Baudraten nutzen. Das könnte Gründe haben. Leider wurde das letzte Thema dazu abgebrochen, bevor ich mir die Software auf dem PC installieren konnte. So habe ich keine Erfahrungen sammeln können, eigentlich schade.
Wenn Du die Datenrate reduzieren könntest, wärst Du auf der sicheren Seite. Der Arduino kann ja auch Animationen berechnen, möglicherweise reicht ein Synchronimpuls mit Parametern per I2C.
beeblebrox:
... sondern um das recht anspruchsvolle Timing der 2812 Stripes auch im Multitaskingenvironment
des Raspi hin zu kriegen.
Damit dürftest Du in Schwarze getroffen haben
Ein PWM-Pin zur Datenkommunikation, das muß ich mir merken. SPI für APA102 ist ja normal.
Ich habe folgenden Gedanken-Häger,
Ich habe vor die Daten der LEDs folgender maßen vom Raspberry an den Arduino zu schicken: welche LED, roter Wert, grüner Wert, blauer Wert
Das sind 4 Bytes und diese möchte ich direkt in den NeoPixel Befehl:
strip.setPixelColor(welche LED, roter Wert, grüner Wert, blauer Wert) und wenn keine Daten mehr übertragen werden die LEDs angezeigt werden.
Ich bin anscheinend zu blöd das hin zu bekommen.
Ich wollte eine Variable hochzählen lassen jedes mal wenn ein Serial.read() gemacht wird aber irgendwie hat das nicht funktioniert.
Ich denke, Du brauchst 2 Zähler: einer für die 4 Byte, wenn der 4 ist, wird strip.setPixelColor ausgeführt, der LED-Zähler erhöht und der Bytezähler wieder auf 0 gesetzt.
Wenn die Daten für alle LED übertragen wurden, wird show() aufgerufen und der LED-Zähler auf 0 gesetzt.
Dann kann es von vorn beginnen.
bdorer:
Ich habe vor die Daten der LEDs folgender maßen vom Raspberry an den Arduino zu schicken: welche LED, roter Wert, grüner Wert, blauer Wert
Tommy56:
Ich denke, Du brauchst 2 Zähler: einer für die 4 Byte, wenn der 4 ist, wird strip.setPixelColor ausgeführt, der LED-Zähler erhöht und der Bytezähler wieder auf 0 gesetzt.
Wozu wird der LED-Zähler benötigt, wenn die Nummer der LED Teil der Nachricht ist?
agmue:
Wozu wird der LED-Zähler benötigt, wenn die Nummer der LED Teil der Nachricht ist?
Damit er weiß, wenn die Daten für alle LEDs übertragen sind und er strip.show() aufrufen kann. Das hatte ich in meinem Beitrag auch geschrieben.
Klar könnte man das auch alles mit 1 Zähler und Modulo 4 fürs Erkennen des Endes der Daten für eine LED machen.
Ich gehe dabei davon aus, dass er immer alle LED übertragen will (so habe ich ihn verstanden), wahrscheinlich aber in beliebiger Reihenfolge, sonst wäre die LED-Nummer überflüssig.
Alle LEDs möchte ich nicht übertragen. Da dies für mich unnötige erscheint. Ich möchte nur diese Übertragen die sich geändert haben.
Hier mal mein Code bis jetzt. Allerdings wenn ich diesen so ausführe kommen immer 4 Antworten Seriell zurück.
#include <Adafruit_NeoPixel.h>
#define PIN 0
#define PixAnza 169
//Definition der LED Strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PixAnza, PIN, NEO_GRB + NEO_KHZ800);
//Für das Empfangene Byte
unsigned char incomingByte;
//Für die Ansteuerung der LEDs
unsigned char LED = 0;
unsigned char red = 0;
unsigned char green = 0;
unsigned char blue = 0;
//Variabel trennen der ankommenden Bytes
unsigned char i;
char Data = LOW;
void setup()
{
//Serielle Kommunikation mit Raspberry Pi
Serial.begin(115200);
//Strip initiallisieren und leer Anzeigen
strip.begin();
strip.show();
}
void loop()
{
//Serielle Schnittstelle auslesen
i = 0;
if (Serial.available() > 3)
{
while (Serial.available() > 0)
{
incomingByte = Serial.read();
switch (i)
{
case 0:
LED = incomingByte;
break;
case 1:
red = incomingByte;
break;
case 2:
green = incomingByte;
break;
case 3:
blue = incomingByte;
break;
case 4:
default:
break;
}
i++;
if (i > 4)
{
Data = HIGH;
i = 0;
}
}
}
if (Data == HIGH)
{
strip.setPixelColor(LED, red, green, blue); // Es werden die korrekten Farben an die korrekte LED übertragen
Serial.print("LED:");
Serial.print(LED);
Serial.print(" rot:");
Serial.print(red);
Serial.print(" grun:");
Serial.print(green);
Serial.print(" blau:");
Serial.println(blue);
Data = LOW;
}
//So oft wie möglich damit die FPS relativ hoch sind
//Dauer für die Ausgabe an LEDs (bei 169): 5,07ms
strip.show(); //Die LEDs beginnen zu leuchten
}
Wenn ich nun die Daten übertrage kommen die Atworten folgendermaßen.
Antwort nur LED korrekt
Antwort LED und rot korrekt
Antwort LED, rot und grün korrekt
Antwort alle korrekt
Was mache ich falsch, bzw. wo habe ich meinen Gedanken fehler?
OK, wie willst Du aber dem Arduino sagen, dass die Übertragung fertig ist und er strip.show() machen soll? Ich würde erst alle übertragen und dann show() aufrufen, sonst ergibt sich ein falsches Bild.
Da wäre dann wahrscheinlich ein ENDE-Satz (z.B. LED-Nr=255,0,0,0) möglich.