Code zu langsam

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Moin,

    ich würde gerne das Thema noch einmal aufwärmen, denn auch ich vermute die Wurzel meines Problems in einem zu langsamen Skript.

    Ich möchte gerne eine LED-Matrix komplett selber bauen. Dafür ist es ja nötig, dass ich die LEDs so ansteuere, dass sie zwar in echt nur einen Bruchteil der Zeit leuchten, es durch die Trägheit des Auges aber wie ein Dauerleuchten aussieht.

    Mit einem Arduino habe ich rausgefunden, dass 1ms leuchten und ca. 8ms nicht leuchten funktioniert.

    Als ich einen einfachen Code für den Raspberry Pi geschrieben und ihn ausprobiert habe, hat es leider nicht funktioniert und die LED hat geflackert.

    Hier der Code:

    Das ganze soll auf einem Raspberry Pi Zero W laufen. Derzeit habe ich für das Programmieren noch den Desktop aktiviert und steuere das Ganze über VNC.

    Liegt die Langsamkeit des Skripts nur daran oder ist der Zero generell für Codes, die ggf. noch viel Rechenleistung (es muss ja später auch noch die Matrix mit berechneten Daten gefüttert werden) benötigen und trotzdem schnell sein sollen, einfach nicht aus?

    Ich habe auch noch einen längeren Code für die Matrix (also nicht nur für eine einzelne LED) inklusive Datenübertragung geschrieben, da kommt mir das Flackern noch heftiger vor.

    Ich hoffe, mir kann da jemand weiterhelfen :)

    Gruß Tobi

    2 Mal editiert, zuletzt von Tobi2003 (14. Juli 2021 um 21:20)

  • Moin Tobi2003,

    erstmal: Herzlich Willkommen im Forum!

    Ich weiß nicht ob es eine gute Idee ist, sich an einen Thread zu hängen der schon soooo alt ist.

    Vielleicht kopiert ihn ein Admin oder Mod deinen Beitrag um.

    Ansonsten Code, bitte, in Codetags, dieses Zeichen "</>", setzen. Liest sich einfach besser.

    Leider kann ich dir bei Python nicht helfen. Sri...

    73 de Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"
    Vielleicht trifft man sich in der RPi-Plauderecke.
    Linux ist zum Lernen da, je mehr man lernt um so besser versteht man es.

  • Ich vermute, das Betriebssystem des Pi zieht zu viel Zeit ab und stört damit das Timing deines Programms.

    Auf einem Mikrocontroller müsste das eigentlich tun, was es soll.

    Du kannst ja mal versuchen, dir in einer (Endlos)Schleife die Milliseconds der Systemzeit ausgeben zu lassen. Wenn dort lücken auftreten, sind das Zeiten, in denen dein Programm nicht läuft, weil das Betriebssystem oder andere Programme den Prozessor beanspruchen.

    Wenn du allerdings eine Matrix steuern willst, musst du das ja nicht nur mit einer, sondern mit vielen LEDs machen. Dann bringt dir sleep nicht viel, weil dein gesamtes Programm blockiert ist. Da könntest du besser auf Timer-Interrupts zurückgreifen.

    Innerhalb der Schleife kannst du den Rechenaufwand noch reduzieren, indem du Konstanten verwendest statt Variablen. Und die Multiplikation mit 8 kannst du vor der Schleife einmal machen, statt in jedem Durchlauf erneut. Aber das macht alles keinen riesigen Unterschied.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

    Einmal editiert, zuletzt von Gnom (14. Juli 2021 um 11:03)

  • Danke für die Tipps für Forum und Pi!

    Dann werde ich wohl während dem Programmieren mit dem Flackern leben müssen und nach Fertigstellung den Desktop ausschalten.

    Oder gibt es noch andere Tipps von eurer Seite?

  • Und was soll das bringen? Das OS als solches bremst bei solch kurzen Zeiten - ob da nun ein Desktop mit läuft oder nicht.Genau für solche aufgaben gibt es ja Microcontroller die diesen ganzen Overhead nicht haben.

    Könntest du mir als Anfänger bitte erklären, wie ich mein Projekt nun umsetzen kann bzw. welchen Microcontroller du mir empfehlen könntest?

    Wichtig ist für mich:

    - viel Speicherplatz für Variablen: Deswegen kann ich meine Arduinos, die ich zu Hause habe, nicht verwenden

    - Internetzugang, da das Programm online steuerbar sein soll

    -> schnell ausgeführtes Programm wegen oben genanntem Problem

  • Moin Tobi2003,

    um mal deinen Projektumfang ab zustecken...

    Wieviel Led's sollen benutzt werden?

    Alle einzeln ansteuern? Oder ein Baustein?

    Sollen festvorgegebene Muster dargestellt werden?

    73 de Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"
    Vielleicht trifft man sich in der RPi-Plauderecke.
    Linux ist zum Lernen da, je mehr man lernt um so besser versteht man es.

  • Moin Bernd666,

    meine LED-Matrix hat 8 Zeilen, die Spalten habe ich noch offen gelassen. Um einen gescheiten Text anzeigen zu können, rechne ich aber mal mit mindestens 8 Modulen á 8 Spalten.

    Ich steuere die Matrix mit Schieberegistern: Eines pro 8 Spalten sowie eines für die 8 Zeilen (also kompletter Eigenbau).

    Das heißt, jedes Mal, wenn eine der Zeilen angesteuert werden soll (also 8 mal pro Zyklus) müssen die Schieberegister neu mit Daten befüllt werden.

    Natürlich muss auch der eingegebene Text (dieser soll nachher über eine Webseite o.Ä. eingegeben werden) erst in die einzelnen Pixel umgewandelt werden.

    Das würde natürlich nicht dauernd passieren, sondern z.B. erst, wenn ein kompletter Durchgang um ist (der Text soll über die Anzeige laufen, um auch längere Texte anzeigen zu können).

  • Moin Tobi2003,

    das sind aber herkömmliche Led's oder diese WS2812?

    Habe im Moment keine Vorstellung wie so ein Matrixmodul aussieht.

    73 de Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"
    Vielleicht trifft man sich in der RPi-Plauderecke.
    Linux ist zum Lernen da, je mehr man lernt um so besser versteht man es.

  • Wenn ich dich richtig verstehe, geht es dir bei en 1 bzw. 8 ms um das Multiplexing. Also, du steuerst eine ms lang die erste Spalte an, dann eine ms die zweite usw.

    Grundsätzlich ist das kein Problem. Du musst nur völlig anders rangehen als in deinem Codebeispiel.

    Du brauchst 9 Schieberegister, die du in Reiche schaltest. Eines davon steuert den Strom der jeweiligen Zeile an (8 Ausgänge = 8 Zeilen - immer nur eine aktiv), die anderen Schieberegister steuern die 64 Spalten jeweils für diese eine Zeile an. Du musst also 9x8 Bits an die Schieberegister senden, um eine Zeile korrekt anzusteuern. Dann bereitest du die Daten für die nächste Zeile vor, prüfst, ob die ms schon rum ist und sendest dann wieder die 9x8 Bit usw.

    Das Senden könntest du mit einem Timer-Interrupt steuern, damit es gleichmäßig erfolgt.

    Wenn der Pi das nicht hinbekommt, kannst du das leicht mit einem Arduino machen. Die Berechnung der Matrix kann der Pi machen, er übergibt dann nur das aktuelle Muster an den µC und der steuert die Ausgabe. Die Matrix selbst ist ja nur 64 Bytes groß.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Wenn ich dich richtig verstehe, geht es dir bei en 1 bzw. 8 ms um das Multiplexing. Also, du steuerst eine ms lang die erste Spalte an, dann eine ms die zweite usw.

    Grundsätzlich ist das kein Problem. Du musst nur völlig anders rangehen als in deinem Codebeispiel.

    Du brauchst 9 Schieberegister, die du in Reiche schaltest. Eines davon steuert den Strom der jeweiligen Zeile an (8 Ausgänge = 8 Zeilen - immer nur eine aktiv), die anderen Schieberegister steuern die 64 Spalten jeweils für diese eine Zeile an. Du musst also 9x8 Bits an die Schieberegister senden, um eine Zeile korrekt anzusteuern. Dann bereitest du die Daten für die nächste Zeile vor, prüfst, ob die ms schon rum ist und sendest dann wieder die 9x8 Bit usw.

    Genau das habe ich vor. Das gezeigte Skript war bloß ein Test, ob der Raspberry Pi die LED flimmerfrei zum Leuchten bringt, was eben nicht der Fall ist.

    Hier mal ein Bild meiner Test-Schaltung. Diese hat nur 8 Spalten, reicht ja für erste Tests. Leider sind mir die LEDs ausgegangen, weitere sind aber bereits bestellt ;)

    Deine Idee, dass quasi jeder „Computer“ das macht, was er am besten kann, gefällt mir sehr gut, danke dir! Ich habe aber keine Vorstellung davon, wie man die einzelnen berechneten Datenlisten übertragen kann, hast du da einen Ansatz?

  • Ganz einfach mit einer seriellen Verbindung.

    Der Pi berechnet das Muster, das angezeigt werden soll. Vereinfacht mal folgend

    Code
       X    XXXXXX
      XXX   XX   XX
     XX XX  XX  XX
    XX   XX XXXXX
    XXXXXXX XXXXX
    XXXXXXX XX  XX
    XX   XX XX   XX
    XX   XX XXXXXX

    Das ergibt 8 Zeilen zu je 2x8 Bit

    00010000 11111100

    00111000 11000110

    01101100 11001100

    11000110 11111000

    usw.

    Diese 16 Bytes überträgst du an den µC. Der Schickt dann jeweils das Zeilenmuster (10000000 für die erste, 01000000 für die zweite usw...) und die zugehörigen Spaltenmuster an die Schieberegister.

    Für 8 Schieberegister mit je 8 Spalten werden es natürlich entsprechend mehr Bytes (64).

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Noch was am Rande:
    Wenn ich dein Foto richtig verstehe, steuerst du die LEDs direkt mit dem Schieberegistern an. Bei einer LEDs geht das gerade noch, aber eigentlich sind die Scheibergister nicht mal dafür stark genug. Die können meist nur 70 mA gesamt - bei 8 LEDs eingeschaltet hast du aber 160 mA. Wenn aber deine Schieberegister 64 Spalten ansteuern, dann muss das Schieberegister der zugehörigen Zeile im schlechtesten Fall den Strom von 64 LEDs aufnehmen. Das schafft es auf keinen Fall. Wenn also deine bestellten LEDs da sind und du sie eingelötet hast, wirst du wahrscheinlich eine Enttäuschung erleben.

    Wenn du Glück hast, genügen die Schieberegister für die Spalten. An den Zeilen brauchst du aber auf jeden Fall einen passenden Treiber, das heißt, einen Transistor, der genügend Strom ableiten kann. Bei 64 LEDs mit je 20 mA wären das 1,28 A. Du müsstest also mit dem Schieberegister einen relativ leistungsfägigen PNP-Transistor für jede Zeile steuern.

    Sollten auch die Schieberegsiter für die Spalten zu schwach sein, müsstest du hinter jedes Schieberegister einen ULN2803 (NPN-Array) schalten.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Wenn ich dein Foto richtig verstehe, steuerst du die LEDs direkt mit dem Schieberegistern an.

    Ich steuere jede Reihe sowie jede Spalte bereits mit einem Transistor an (man sieht sie auch im Foto). Oder habe ich dich jetzt irgendwie falsch verstanden und du meintest doch was anderes, was ich noch nicht gemacht habe? :/

    Ich habe jetzt überall BC337-Transistoren verwendet, war das falsch?

    Hier mal noch der Schaltplan:

  • Stimmt, die hab ich gar nicht gesehen. Warum nimmst du einzelne Transistoren und nicht Arrays wie den ULN?

    Der 337 ist ein NPN mit 0,8 A - für die Steuerung der Spalten ist der ok. Das ULN Array würde auch gut funktionieren.

    Für die Zeilenansteuerung solltest du aber einen PNP nehmen, weil die Last da nicht vor, sondern hinter dem Transistor hängt. Außerdem kommst du dort auf bis zu 1,28 A (64 LEDs mit je 0,02A) - du solltest also einen etwas stärkeren nehmen.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Warum nimmst du einzelne Transistoren und nicht Arrays wie den ULN?

    Weil ich von dem ULN Array noch nie was gehört habe ?

    Kann ich das Array auch für die acht Zeilen verwenden oder soll ich mir dafür PNP-Transistoren holen?

  • Bei einer LEDs geht das gerade noch, aber eigentlich sind die Scheibergister nicht mal dafür stark genug. Die können meist nur 70 mA gesamt - bei 8 LEDs eingeschaltet hast du aber 160 mA

    es gibt doch ultrahelle LEDs die bei unter 10mA schon die Netzhaut wegbrennen (20mA 11Cd oder 8Cd und unter 10mA sehr hell sind!)

    ULN2803a für 8 LEDs aber Strom max beachten, pro Port 0,5A in Summe aller 8 aber nur 2,5A

    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)

Jetzt mitmachen!

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