WS2801 einzeln ansteuern

  • Hallo zusammen,

    ich fand keins der Unterforen passend, deswegen ist es hoffentlich in Allgemein richtig. :conf:

    Ich hab bereits den ganzen Vormittag und Mittag damit verbracht, eine Lösung zu finden, bin aber nicht wirklich auf das richtige gekommen.. aber mal von vorne:

    Die Anzeige meiner Ampel realisier ich mit LED Strips aus WS2801 in Form von 3x 7 Segment-Anzeigen. Ich will entsprechend der benötigten Anzeige die Segmente einzeln ansteuern (also jede LED für sich, ein Segment besteht aus 7 LEDs).

    Ich hatte bereits vor einiger Zeit einiges mit diesem Tutorial getestet und es hat soweit ganz gut funktioniert.

    Jetzt will ich das ganze aber in Java umschreiben und finde dafür keine passende Library oder bin nur zu doof, diese anzuwenden.

    Meine grundsätzliche Struktur hab ich bereits (Farbcodes, Aufteilung in Ziffern, Segmente) soweit fertig, und funktioniert nach Consolenausgabe auch wie gewünscht.

    Für die Ansteuerung der LEDs find ich aber nicht das richtige.

    Mit Google lande ich immer bei der Library Pi4j mit WiringPi, Serial und I2C, aber ich häng bei der Anwendung.

    Folgendes Schema:

    Wenn sich die Ziffer oder Farbe der 7-Segment-Anzeige ändert, übergeb ich die Werte Farbe und Ziffer an die class Ziffer. Diese schaut dann für jedes Segment, ob dieses an oder aus sein muss. Dieser Wert wird dann weiter an die class Segment übergeben, in welcher der aktuelle Status (Farbe/Aus) gespeichert ist. Wenn für dieses Segment die Farbe geändert werden muss, sollen nur die 7 LEDs dieses Segments neu angesteuert werden. Dies würde ich dann an dieser Stelle an einen Buffer übergeben.

    Dieser Durchlauf soll für alle 3 Ziffern mit je 7 Segmenten ausgeführt werden.

    Wenn alle überprüft wurden, soll aus dem Buffer die LEDs, welche verändert werden sollen, diese über den Bus das neue Signal erhalten. Die LEDs, welche gleich bleiben, sollen nicht angesteuert werden.

    Das, was mir in den vorhin genannten Libraries fehlt, ist, dass ich eine einzelne LED ansteuern kann (also auch eine Adresse allein mitten drin) und dass diese dann erst am Ende alle auf einmal über eine Methode überschrieben werden (wie das Pixels.show() in oben genannten Tutorial).

    Den Buffer könnte ich ggf. natürlich auch selbst schreiben, aber hoffentlich gibt es da bereits was. Aber die einzelne Ansteuerung der LEDs ist sehr wichtig, da es später auch eine größere Variante der Ampel geben wird und bei der Menge der LEDs dann die Buszykluszeit zu groß werden würde, wenn ich auch die LEDs ansteuern müsste, die sich nicht verändern.

    Ich hoffe, mir kann da jemand weiter helfen.

    Wenn mein bisheriger Code nützlich wäre, kann ich den gerne nachliefern.

    Liebe Grüße

    Fipsi

    P.S.: ich beschäftige mich erst seit sehr kurzer Zeit mit Java.

  • > Das, was mir in den vorhin genannten Libraries fehlt, ist, dass ich eine einzelne LED ansteuern kann (also auch eine Adresse allein mitten drin)

    Die LEDs sind alle auf dem SPI-Bus. Das kann man wie ein grosses Schieberegister betrachten, bei dem immer alle LEDs angesteert werden.

    Es bleibt also nichts anderes uebrig als einen grossen Buffer mit dem Zustand aller LEDs zu halten und den dann am Stueck ueber SPI durch die LEDs zu takten.

    > Mit Google lande ich immer bei der Library Pi4j

    Und was passt daran nicht? Ich hab's zwar nicht probiert, aber mit com.pi4j.io.spi muesste man die LEDs doch ansteuern koennen.

  • > Das, was mir in den vorhin genannten Libraries fehlt, ist, dass ich eine einzelne LED ansteuern kann (also auch eine Adresse allein mitten drin)

    Die LEDs sind alle auf dem SPI-Bus. Das kann man wie ein grosses Schieberegister betrachten, bei dem immer alle LEDs angesteert werden.

    Es bleibt also nichts anderes uebrig als einen grossen Buffer mit dem Zustand aller LEDs zu halten und den dann am Stueck ueber SPI durch die LEDs zu takten.

    > Mit Google lande ich immer bei der Library Pi4j

    Und was passt daran nicht? Ich hab's zwar nicht probiert, aber mit com.pi4j.io.spi muesste man die LEDs doch ansteuern koennen.

    Du meinst also doch jede LED einzeln durchzuhaken? Ich will halt z. B. LED 1 - 7, 21 - 28, usw. ansteuern und die andren "übergehen".

    Die Lib passt schon.. aber da kann ich keine LED einzeln ansprechen, sondern müsste alle LEDs angeben.

    Liebe Grüße

    Fipsi

  • > aber da kann ich keine LED einzeln ansprechen, sondern müsste alle LEDs angeben

    Ein grosses ByteArray mit je drei Bytes fuer die LEDs anlegen und initialisieren.

    Die einzelnen Objekte wissen, in welche Bytes im Array sie schreiben muessen und schreiben ihren Zustand dort hinein.

    Zum Schluss den ganzen Buffer an die LEDs schicken.

    In C, ohne Objekte, aber als Muster koennte es taugen: https://blog.heimetli.ch/raspberry-led-strip-c.html

  • Ich beschäftige mich auch gerade mit der Ansteuerung der WS2812B - allerdings mit einem Microcontroller und C.

    Mit einem Pufferspeicher musst Du ohnehin arbeiten, da immer alle LEDs geschrieben werden müssen, auch wenn Du nur eine LED ändern willst.

    Du kannst auf den Pufferspeicher allerdings sehr einfach zugreifen: Er besteht einfach aus jeweils 3 Bytes pro LED - 1.Byte ist für die Farbe Grün, zweites für Rot und das Dritte für Blau. Wenn Du also den Blauton der zweiten LED zugreifen möchtest, schreibst Du den 6. Eintrag um - da der Pufferspeicher bei 0 beginnt ist das der Index [5].

    Der Datentransfer ist extrem schnell: Für 1 Bit brauchst Du 1,35 Microsekunden. Du kannst also 740 KBits pro Sekunde übertragen. Da eine LED 24 Bit hat, wären das ca. 30.000 LEDs / Sekunde. Bei einer oder mehreren Ampeln spricht also nichts dagegen alle LEDs hintereinander zu hängen.

    Ein paar Tipps - beziehen sich aber auf C - in Java gibt es sicherlich adäquates:

    Damit Du komfortabel auf die LEDs zugreifen kannst, bietet es sich an den Puffer als Struktur aufzubauen. Mit Hilfe einer Union kannst Du auf den gleichen Speicherbereich unterschiedlich zugreifen:

    Code
    #define NumOfLEDs 61
    ...
    union LEDDaten
    {
      BYTE Daten[NumOfLEDs*3];
      BYTE GRB[NumOfLEDs][3];
      struct {BYTE Green, Red, Blue;} Color[NumOfLEDs];
    }LED;

    Ich kann nun auf Den Puffer auf 3 Verschiedene Weisen zugreifen:

    1. mit LED.Daten[LEDPointer] greife ich Byteweise auf die LED-Daten zu. Sehr nützlich um die Daten am Datenpin raus zu schreiben...
    2. mit GRB[LEDPointer][0] greife ich auf grün, mit GRB[LEDPointer][1] auf rot und mit GRB[LEDPointer][2] auf blau direkt zu. Sehr nützlich, wenn ich z.B. schnell auf einzelne Farben mit einem Variablenwert zugreifen möchte....
    3. am leserlichsten ist es aber, wenn ich auf den Puffer mit Hilfe der Struktur zugreife. z.B. LED.Color[LEDPointer].Green greift direkt auf den Wert der grünen Farbe zu, auf die die Variable LEDPointer gerade zeigt. LED.Color[1].Blue würde auf den Blauwert der zweiten LED (LED 1 hat den Index 0) zugreifen.

    Ich hoffe ich konnte Dir damit helfen...

    ...wenn Software nicht so hard-ware ;) ...

    Freue mich über jeden like :thumbup:

  • VeryPrivat da liegt der Hund begraben: Ich wollte vom Bus her schon nur eine einzelnde LED ansteuern. Aber das geht nicht. Na dann nicht.

    Ich hatte irgendwo was von max. 100.000 kHz gelesen, was bei 630 LEDs (voraussichtlich die große Ampel) 151,2 ms dauern würde.

    Die 7-Segment-Anzeige soll die Restzeit in Sekunden anzeigen.. das wäre etwas... unvorteilhaft und würde blöd ausschauen. Aber gut, wenn man die Taktung auch hochstellen kann.

    Das ist die Segment-Klasse. Also ich hab die eh schon gespeichert, dann brauch ich auch die aktuelle Farbe gar nicht speichern.

    Dann lass ich das am Ende in der Main durch den Output laufen und dann sollte das funktionieren...

  • Ich hatte irgendwo was von max. 100.000 kHz gelesen

    nicht alles durcheinander würfeln, geht um ws2801?

    https://www.embeddedadventures.com/datasheets/SMRT-PIXEL_WS2801.pdf

    Maximum input clock frequency 25MHz

    oder um I2C mit Portextender dann kann jede Zeile, jede Spalte einzeln gesteuert werden, auch eine LED oder eine ganze Zeile oder eine ganze Spalte.

    Ohne System und mit Nennung was es werden soll findet man keine gemeinsame Sprachregelung.

    lasst die PIs & ESPs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

  • nicht alles durcheinander würfeln, geht um ws2801?

    https://www.embeddedadventures.com/datasheets/SMRT-PIXEL_WS2801.pdf

    Maximum input clock frequency 25MHz

    oder um I2C mit Portextender dann kann jede Zeile, jede Spalte einzeln gesteuert werden, auch eine LED oder eine ganze Zeile oder eine ganze Spalte.

    Ohne System und mit Nennung was es werden soll findet man keine gemeinsame Sprachregelung.

    Ja, um WS2801. Ich sollt mir langsam echt mal angewöhnen, Datenblätter gleich am Anfang anzuschauen.. :wallbash::wallbash:

    Das System besteht eben nur aus einem WS2801-Strip und Raspberry Pi, sonst nichts. Ich hab's mir grad ausgerechnet, 300 kHz würden mir schon reichen.

    Wenn ich des noch richtig auf dem Schirm hab, verändern die LEDs ihre Farbe ja eh erst, wenn der Bus wieder Ruhe gibt, oder? Nicht, dass sich eine LED nach der anderen veändert...

    Vielen Dank euch und

    liebe Grüße

    Fipsi

  • Ich hatte irgendwo was von max. 100.000 kHz gelesen

    Ich sollt mir langsam echt mal angewöhnen, Datenblätter gleich am Anfang anzuschauen..

    ja solltest du, der erste je gemachte Fehler ist eine falsche Annahme!

    lasst die PIs & ESPs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

  • Es läuft doch nicht so ganz..

    Folgendes ist mein Code für den Output:

    wenn ich versuch, die Segmente b und c in Grün zu beleuchten, kommt auf a und b weiß an.

    Wenn ich color ausgeben lass, steht in der Konsole -1.

    in

    Code
    Anzeige.get(stelle_nr).getSegment(segmente.get(segment_nr)).getFarbe(0);

    ist das erste Byte der Farbe abgelegt.

    Weiß jemand, wo mein Fehler liegt?

  • Japp.. ich hatte da das *3 für die drei Bytes/LED vergessen..

    Nachdem ich nen Denkfehler hatte, bin ich jetzt auf folgendes gekommen, welches auch funktioniert! :)

    Danke euch für eure Hilfe :)

  • Besser solche Netzteile verwenden.

    unterschreibe ich und lieber mehr Netzteile für mehr Stripes verwenden als die 10A auszureizen denn die Sekundärstrippe samt Stecker sieht nicht nach 10A aus.

    Diese Hohlstecker haben üblicherweise eine 4A Grenze in allen Datenblättern.

    Nur wenige Hohlstecker schaffen bis 7A für Notebooks aber denen ist es auch egal ob 20V oder 18V ankommen, 2V weniger machen den Notebooks nichts, aber bei 5V sind 2V weniger eine Katastrophe! (bei Notebooks haben die Hersteller aber alle Toleranzmarken Stecker und Buchse geprüft, bei Feld- Wald- und Wiesenstecker und Buchsen ist es eben fraglich)

    lasst die PIs & ESPs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

  • Für die Allgemeinheit und Laien bin ich voll auf deiner Seite, dass dieser Hinweis gilt.

    Um euch von meiner Seite aus zu beruhigen: Ich bin Elektromeister, ich weiß, was ich tue.

    Ich verwende Netzteile wie dieses.

    Und da meine fertigen Geräte eh ein komplett geschlossenes Gehäuse haben, kann ich diese auch da einbauen.

    Liebe Grüße

    Fipsi

  • Hallo Fipsi,

    absolut korrekt und wie Du schreibst, nur mit Gehäuse.

    In dem Tutorial was oben angeführt wird ist an dem Netzteil nicht mal der Schutzleiter angeschlossen, von einem Gehäuse ganz zu schwiegen.

    Ich hab ja nicht die Netzteile an sich bemängelt sondern wie sie dort gehandhabt werden, bitte nicht falsch verstehen.

    Schau Dir das mal an, dann werden zwei Elektromeister in dem Fall gleicher Meinung sein.

    Viele Grüße

    Thotaa

  • Hallo Thotaa,

    das ist mir schon klar, dass du die Handhabung meinst.

    Ein Netzteil an sich kann man ja auch prinzipiell nicht bemängeln, da es immer vom Einsatzzweck abhängig ist.

    Aber dieser ist in dem Fall eben kritisch zu betrachten, wie du bereits gesagt hast.

    Liebe Grüße

    Fipsi

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!