LCD Laufschrift

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

    ich bin grade dran mir ein Raspberry Internet Radio zu bauen.
    Alles funktioniert soweit wie es soll. Nun möchte ich das Sendernamen die mehr als 20 Buchstaben enthalten, wie eine Laufschrift angezeit werden. (von rechts nach links).

    Das funktioniert auch soweit, aber in der Zeit wo der Sendername ausgegeben wird, wird der rest des Displays nicht mit ausgegeben (Zeile 2,3,4) und ich kann in dieser Zeit auch keine Sender wechseln. (Hardware ereignisse)

    Den Fehler habe ich zwar gefunden aber ich weiss nicht wie ich das umgeben kann.

    Der Fehler selbst:
    Jedes mal wenn die Funktion ausgabe aufgerufen wird und der Text größer 20 Zeichen ist,
    bleibt er solange mit der Ausgabe beschäftigt bis der Text abgearbeitet ist. So nun kann in der Zeit ja nichts anderes gemacht werden :wallbash:

    Wie bekomme ich jetzt in Python eine parallelität hin, sodass der Text scrollt (von rechts nach links) und ich gleichzeitig die anderen Zeilen aktualisieren / ausgeben kann?

    Ich habe ein 4*20 Zeichen Display (HD44780)

    Hat jemand von euch sowas ähnliches schonmal realisiert?

    Für Hilfestellungen aller Art wäre ich euch sehr Dankbar.


    Hier ein Code ausschnitt:

  • Du könntest dein Programm multithreaded machen *pfeif* :D

    Das ist in Python bedingt möglich, in deinem Fall könnte es funktionieren. Schau mal in die Doku, ist allerdings etwas haarig.

    Ich habe sowas gemacht (Multithreading), um die Temperatursensoren auf dem 1w quasi parallel abzufragen, ohne das Hauptprogramm anhalten zu müssen. Läuft mit einer Queue, in die der Name der abzufragenden Sensoren eingekippt wird...

    Bei dir müsstest du eine Klasse definieren, die genau 1 Zeile ausgibt (Übergabeparameter ist die Zeilennummer und der Text) und eine Queue, die die Ausgabeereignisse aufnimmt.
    Wichtig: Die Verwendung der LCD Schreibbefehle darf immer nur von einem Thread zur gleichen Zeit ausgeführt werden... Musst also mit Semaphoren arbeiten... Wie gesagt, ist nicht simple... Schau mal in die Doku(s), ist demonstriert...

    Hab ich auch noch vor, aber ist derzeit noch auf der Todo-Liste... kannst ja schon mal vorarbeiten :lol:

  • Ist das ernst gemeint? Du willst eine pseudoparallele Ausführung umsetzen und diese dann mit semaphoren wieder nacheinander auführen? (Das Mittel der Wahl währen hier übrigens ein Mutex, das ist eine spezielle (vereinfachte) Form der Semaphoren speziell für MUTal EXclusion also gegenseitigen Ausschluss. Deutlich einfacher zu verwenden (falls es die in Python gibt, was ich jedoch stark annehme))

    Insgesamt kann ich nur sagen: Lass die parallelität in diesem Zusamenhang sein, das macht absolut keinen Sinn, du willst nichts gleichzeitig ausführen, nur sehr nah beieinander.

    Damit will ich nicht sagen dass du nicht lernen solltest wie das funktioniert, das ist immer gut, aber für diese Anwendung ist es Schwachsinn.


  • Du könntest dein Programm multithreaded machen *pfeif* :D
    ...

    Ja hey Zentris ...

    Du hast vielleicht Suchten :-/ ... warum nicht gleich als KLM realisieren ;) ...
    Mönsch - mach doch den armen Kerl nicht fertig.

    Ein dunkler Gruss aus dem finsteren Süden,
    -ds-

  • Hallo, danke erstmal für die Antworten.

    Nunja mit Semaphore wird es mehr als haarig, weil ich ja die Variablen immer sperren und freigeben muss. Trotz Sender wechsel etc... So ist ja eine parallelität auch nicht wirklich gegeben.



    Insgesamt kann ich nur sagen: Lass die parallelität in diesem Zusamenhang sein, das macht absolut keinen Sinn, du willst nichts gleichzeitig ausführen, nur sehr nah beieinander.

    Damit will ich nicht sagen dass du nicht lernen solltest wie das funktioniert, das ist immer gut, aber für diese Anwendung ist es Schwachsinn.

    Ja das sehe ich auch solangsam ein. Nur stellt sich für mich die Frage, wie es dann ohne geht?
    Ich habe einige Videos von Raspberry Internet Radio's auf Youtube gesehen und einige Code's mir runtergeladen, aber leider verstehe ich den sinn nicht wie es dort gelöst wurde.


    Horroreyes

    Wie meinst du das den mit dem Counter? Theoretisch könnte ich ja den String zerlegen und dann einzeln an die Ausgabe Funktion geben?

  • Du machst es die viel zu schwer.
    Vorweg: Ich spreche kein Python, daher ist das als Pseudocode anzusehen:

    Das sollte deine komplette Funktion ersetzen können. Ist etwas kürzer geworden^^

    Python wird auch eine switch-anweisung haben, damit ließe sich das 4x if noch ersetzen, noch besser wäre es aber LCD_LINE_X direkt der Funktion zu übergeben anstelle einer Zahlk als Zeilennummer, dann brauchst du auch garkein if/switch mehr


    Das war der erste Versuch etwas in Python zu schreiben, und ich kann es nicht einmal auf dumme Fehler prüfen... also bitte nicht zu streng sein^^[/php]


  • Du machst es die viel zu schwer.
    Vorweg: Ich spreche kein Python, daher ist das als Pseudocode anzusehen:

    Das sollte deine komplette Funktion ersetzen können. Ist etwas kürzer geworden^^

    Python wird auch eine switch-anweisung haben, damit ließe sich das 4x if noch ersetzen, noch besser wäre es aber LCD_LINE_X direkt der Funktion zu übergeben anstelle einer Zahlk als Zeilennummer, dann brauchst du auch garkein if/switch mehr

    Das war der erste Versuch etwas in Python zu schreiben, und ich kann es nicht einmal auf dumme Fehler prüfen... also bitte nicht zu streng sein^^[/php]

    ALTER !!! :D
    Wenn du Python nicht kennst, dann mach ihm doch bitte keine Vorschläge dazu...
    Python hat keine Switch-Konstrukte, das macht man da etwas "durch die Brust ins Auge" oder so. :lol:

    BTW: Multithreads in Python.. Mein Vorschlag war eigentlich eher so als ein (lustiger) Wink zu verstehen, das man damit machen KANN, aber nicht muss
    Letztlich vereinfacht sich aber so einiges, wenn man das Gerüst (Workerthreads/Queue) einmal stehen hat und dann nur noch den Text einwirft... egal wo, egal wann in der logischen Abfolge.

    Horroreyes:
    Semaphore/Mutex: läuft auf das gleiche hinaus: eine (kritische, weil nur begrenzt verfügbare) Resource zur gleichen Zeit nur einem Prozess zur Verfügung zu stellen.
    Der Abschnitt, der das LCD anspricht. ist so eine. Konkret ist doch offenbar gewünscht, dass während der Ausgabe der Zeit oder anderer Infos auch noch Sender/Titelinfos durchlaufen. Das muss man schon irgendwie parallelisieren, sonst bleibt während des Titeldurchlaufs die Uhr stehen usw...
    Insofern ist die deine Bezeichnung "Schwachsinn" für diesen Vorschlag - um mal bei deiner plumpen Wortwahl zu bleiben - Schwachsinn :neutral:
    (Ich verwende ja normalerweise dieses abwertend gemeinte Vokabular hier nicht, aber da du ja damit kein Problem zu haben scheinst, sei es drum :thumbs1: )

    Leider (wie schon geschrieben) bin ich in meinem Projekt noch nicht an diesem Punkt. Allerdings, wenn mich "der Hafer sticht", vielleicht ziehe ich das vor, muss eigentlich nur das Display anlöten... :s

  • Ach ja: Back to the roots

    Frage an den TO:
    Wie ist dein Display angeschlossen? Direkt mit 6 Leitungen an die GPIOs oder per I2C-Adapter?

    Hintergrund:
    Per I2C ist die Ansteuerung recht langsam, dafür braucht man nicht so viele Interface-Pins.
    Der direkte Anschluss ist schneller (doppelte Umsetzung entfällt), aber etwas komplizierter, wobei es dafür auch schon jede Menge Module gibt.

    *Lötkolben rauskram*

  • Ok, ich habe mich mal rangesetzt und "auf die Schnelle" was in Python bzgl. Multithreaded LCD Ansteuerung zusammengeschmiedet, damit ihr seht, dass das gar nicht so wild ist :geek:

    Zur Beachtung:
    Alles (noch) experimentell, es kommt nach der Abarbeitung noch zu einem Fehler bei der Thread-Beendigung.... es geht mir um die Darstellung des Prinzips!
    :thumbs1:

    Da geht also noch was! :lol:
    Kann mich da morgen Abend nochmal hinsetzen, wird aber spät bei mir, vielleicht kann das von anderen weitergebaut werden, die Ausgabe erfolgt in Zeile 27-33, da ist noch potential drin, vor allem bzgl. Richtung und scrolling... :

    Environment:
    Ich habe ein hier mal schnell mein altes Adafruid i2c 16x2 LCD Pi Plate drangestöpselt.
    Die verwendeten Module sind ja zu sehen, ggf. runterladen bei Adafruid. OS ist ein Standard-Rasbian.

    Spoiler anzeigen
  • Zentris: wenn du dir die Mühe gegeben hättets meinen code nazuzuvollziehen, dann hättest du gesehen, dass die Zeit dabei nicht stehen bleibt.
    Zentris: Ok switch gibt es in Python nicht, damit ist diese kleine Anmerkung hinfällig, der Rest des satzes bleibt aber bestehen
    Zentris: Ich habe doch selbst erklärt, dass ein Mutex ein Spezialfall von Semaphoren darstellt, nett von dir, dass du mir das jetzt nochmal erklärst
    Zentris & dvb: Multithreading um Zeilen eines LCD zu steuern? Ernsthaft?
    Ich habe mit keinem Wort gesagt Multithreading wäre schwer, Übermäßiger Aufwand oder zu langsam (in Python oder generell). Multithreading ist für Zeilen eines LCD aber wirklich übertrieben. Guckt mal bitte auf eure Wecker, die haben auch mehrzeilige LCDs und brauchen dafür kein multithreading... und eine Uhr läuft da auch noch nebenbei... Prinzipiell bräuchte man dann ja für jede Zelle des LCD einen Thread, weil man vllt nur eine Zahl irgendso hochzählen will? Bitte bleibt vernünftig.

    Sinnvoll wäre vermutlich die LCD-Anzeige insgesamt als eigenen Thread neben anderen Dingen zu basteln.

  • Horroreyes: [ ] du hast mein Python script angesehen =(

    Ich habe genau das gemacht: Die Ansteuerung des LCD als Ganzes in einen Thread gepackt.
    Damit ist es egal, wer wann wo was auf dem Display ausgeben will, es wird Zeichen für Zeichen für Zeichen geschrieben und zwischendurch das LCD kurz freigegeben, damit "quasiparallel" ausgegeben werden kann. :thumbs1:

    Somit kann z.B. unten (endlos in einer Loop) der Titel durchlaufen und oben die Zeitanzeige / Titelposition /weiss der geier was aktualisiert werden: Genau das, was der TO doch wollte...
    Und mal ehrlich: der Code ist nicht aufwändig/kompliziert... da geht allerdings noch was, ich habe es nur "mal schnell" hingeschrieben...

    Frohe Ostern :)

  • Dein Code sieht ja gut aus, aber eine andere Library verwenden ist schon ein bisschen geschummelt :P
    (Möglicherweiße (wahrscheinlich) besser, aber keine Antwort auf das Problem)
    Ansonsten haben wir wohl ein bisschen an einander vorbeigeredet, ich hatte den TO so verstanden, dass er pro Zeile Parallel sein wollte, und eure Antworten entsprechend interpretiert. Sorry wenn das zu Missverständnissen führte, war nicht so gemeint.

  • Ja, deswegen habe ich ja in meinem Beitrag #10 gefragt, wie der TO das LCD angekoppelt hat.

    Mein Beispiel bezieht sich auf das Adafruid LDC, das ist per I2C angehängt... (bei einer nativen Ansteuerung per GPIOs sieht es ein klein wenig anders aus, aber ich habe dann vorgestern doch nicht mehr gelötet, nur gesteckt :D )

    Vielleicht sollten wir warten, bis der TO aus dem Osterschlaf zurück ist :lol:, dann kann man das konkreter machen :thumbs1:


  • Genau :thumbs1:


    So da bin ich wieder :) Erstmal frohe Ostern!
    Ich hatte in den letzten Tagen wenig Zeit fürs Raspberry... deswegen die Verzögerung.


    Zitat

    Ach ja: Back to the roots

    Frage an den TO:
    Wie ist dein Display angeschlossen? Direkt mit 6 Leitungen an die GPIOs oder per I2C-Adapter?

    Hintergrund:
    Per I2C ist die Ansteuerung recht langsam, dafür braucht man nicht so viele Interface-Pins.
    Der direkte Anschluss ist schneller (doppelte Umsetzung entfällt), aber etwas komplizierter, wobei es dafür auch schon jede Menge Module gibt.

    *Lötkolben rauskram*

    So ich habe das Diplay nicht über I2C angeschlossen, sondern über Datenleitungen (RS,E,D4-D7)
    Zum Display selbst: Ich habe es bei Ebay gekauft. Firma k.A. aber es macht seinen Job.
    Die selben Display's bei reichelt.de waren mir dann doch etwas zu teuer.

    Das Problem selbst habe ich jetzt endlich gelöst.
    Das Code-Stück was ich oben gepostet habe war in meiner lcd_display.py .Aufgerufen wird die Fkt. "ausgeben" aber in der Datei music.py. Somit muss der Compiler/Linker (oder wer auch immer) in die andere Datei rein, warten bis die Fkt. zu Ende ist und dann wieder zurückspringen.

    Jetzt ist das aber so, dass ich den String schon in der music.py zerlege und die zerlegten Strings dann der Fkt. ausgeben übergebe. Da in der music.py eine Endlossschleife ist zähle ich das "i" hoch und resete es bei (i>len(string_sender_info)) auf i=0. Mit jedem Anstieg von "i" wird der String neu zerlegt und ausgegeben. Somit brauche ich die for-Schleife nicht, da diese die eigentliche Verzögerung brachte. In der Endlossschleife ist eine time.sleep() verbaut somit kann ich die Geschwindigkeit regulieren.

Jetzt mitmachen!

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