[SOLVED] Inhalt eines LC-Displays (20x4) auslesen?

Hallo Freunde der Bits und Bytes,
im Rahmen eines größeren Projektes auf einem ATMEGA 1284... drängt sich mir folgende Frage auf:

Kann man den Inhalt eines LCD-Displays (20x4) auslesen und später wiederverwenden? So im Sinne von „lcd.Save()“ und späterem „lcd.Restore()“... oder so ähnlich?

Das würde manche Sketches stark vereinfachen, wenn man z.B. bei Rückkehr aus einem obenliegenden „YesNo_Dialog()“ oder so, nicht den – manchmal aufwändig gestalteten – Ursprungsinhalt manuell wieder herstellen müßte ?! Interessant wäre es auch besonders beim später geplanten Modul 40x4.

Nach dem Studium des Datenblattes von HITACH müßte es theoretisch möglich sein. „Wie selbstverständlich“ wird dort überall von 'schreiben' UND 'lesen' gesprochen. Nach dem „Zerlegen“ der „LiquidCrystal.h / .cpp“ geht es von Hause aus nicht. So eine Funktion (oder auch „Methode“) fände ich jedoch äußerst hilfreich.

Hat jemand nützliche Tipps zur Hand?
LG, Rudi

Das wäre doch dann nur in dem Fall nötig wenn der Mikrocontroller neustartet und das LCD nicht, oder?? Und wenn dieser neustartet wird das LCD eh wieder neu initialisiert bzw. überschrieben!?

Gruß

Jeden Text den du ausgibst muss ja irgendwo im Programm zum ersten mal auf das Display geschrieben werden.
Und dein Programm muss doch einfach nur diese Stelle erneut aufrufen.

Du hast es beschrieben als display.save(). Wenn du es unbedingt über eine Art "save" machen möchtest musst du die Zeichen die du ausgeben willst auch noch in einen Array speichern und dann kannst du doch diesen Array noch einmal "restore() en"

Wenn jetzt deine Grundidee ist, ich speichere mir dutzendfach den bisherigen Inhalt weg um es dann mit dem passenden Inhalt wieder restore() machen zu zu können, dann müsstest du in deinem Programm sehr genau Buch führen in welchem Speicher steht jetzt welcher Text.

Da wird es bedeutend einfacher sein das ganze Programm so zu strukturieren, dass bei jedem Sprung (auch bei "Rücksprung") der dazu passende Text noch einmal neu ausgegeben wird.

Dazu programmiert man sich eine eigene function die man dann einfach mit einer Textnummer als Parameter aufruft.

const byte HelloText  = 1;
const byte StatusText = 2;

void ShowText (int TextNr)
{
  switch (TextNr) {
    case HelloText:
      lcd.setCursor(0,0)
      lcd.print("Hello");
      lcd.setCursor(1,0)
      lcd.print("zweite Zeile");
      lcd.setCursor(2,0)
      lcd.print("dritte Zeile");
      lcd.setCursor(3,0)
      lcd.print("vierte Zeile");
      break;

    case StatusText:
      lcd.setCursor(0,0)
      lcd.print("Status");
      lcd.setCursor(1,0)
      lcd.print("BattVolt");
      lcd.setCursor(2,0)
      lcd.print("Temp1:");
      lcd.setCursor(3,0)
      lcd.print("Temp2:");
      break;
   }

viele Grüße Stefan

Nach dem Studium des Datenblattes von HITACH müßte es theoretisch möglich sein. „Wie selbstverständlich" wird dort überall von 'schreiben' UND 'lesen' gesprochen. Nach dem „Zerlegen" der „LiquidCrystal.h / .cpp" geht es von Hause aus nicht. So eine Funktion (oder auch „Methode") fände ich jedoch äußerst hilfreich.

nur ganz wenige Libs lesen vom Display.
Wenn sie lesen, dann lesen sie überwiegend nur das BusyFlag.
Eigentlich kenn ich nur die HD44780 von Bill die das macht.
Nicht mal die HD44780 von Bill liest das BusyFlag.
Halbwissen: geschriebenen Zeichenregister kannst nicht zurücklesen

Kurz gesagt:
Mach dir selber deinen 40x4 Zeichen Puffer.
Aber wenn du schreibst, du willst die Ebene "Davor" zurückschreiben, dann müsstest du das sogar zweimal halten, das aktuelle und das "vorhergehende", also wie "pages".
Und bei jedem lcd.clear() dann die Page umschalten
und wenn gewünscht ein lcd.restore(dieseOderJenePage) machen.
schlimm wirds bei setCursor ... was überschreibst dann

Bin mir nicht so sicher, ob das klug ist.

RudiDL5:
Nach dem Studium des Datenblattes von HITACH müßte es theoretisch möglich sein.

Dann wäre ein gängiger Weg, die Lib anhand des Datenblatts um die Lesefunktion zu erweitern.

Ansonsten die Ausgaben sauber in Funktionen kapseln und diese bei Bedarf wieder aufrufen.

Gruß Tommy

Hallo Rudi,
Du liebst also den Überfluß!? (=Pleonasmus)

LCD = liquid crystal display = LC-Display

Viel Freude am Überfluß!

Na jaaaa, ich bin unsicher ob an meiner Idee etwas flüssiges bis überflüssiges dran ist :wink:

Fakt ist, dass ich ein recht großes, mehrfach verschachteltes Menü (mit einer ebenso großen Menge an Funktionen und Unterfunktionen) auf dem 1284 erstellt habe. Der 1284 alleine bietet genügend Raum für diverse Spielereien, bis hin zur spartanischen Verwaltung einer SD-Card und Beherbergung vieler benötigter Ports. Es kommen demnächst auch noch einiges vieles hinzu. Grundsätzlich dient das alles zur Steuerung von Musik-Komponenten innerhalb eines langsam wachsenden Synthesiszer-Systems im Eurorack-Format.

Nun habe ich mich bei der Fummelei innerhalb der Menüs oft verhaspelt und etwas damit gehadert... Das „Grobe Konzept“ steht im Kopf – nur bei einigen Details hapert es dann manchmal. Man kann eben nicht ALLES 100% vorausplanen, sonst kommt man bei so etwas nie wirklich zum Planungs-Ende...

Da kam mir ein Gedanke aus meiner alten DOS-Zeit wieder hoch. Damals in „Clipper“ und „Turbo-Pascal“ war es super einfach, auch umfangreiche Programme kurzfristig mit irgendwelchen Dialogen zu überlagern, bei denen ich den Hintergrund dann später mit einem Wisch in den Ursprungszustand versetzen konnte.

Genau genommen ist es doch heute noch in Windows genau so mit all den schönen Dialogen, Fenstern usw. Nur der Anwender merkt davon nix mehr was „wirklich“ geschieht. Ich denke da nur innerhalb „Delphi“ an die sogenannten „Modalen Dialog“, und sei es nur für Fehler, Ja-Nein-Abfragen oder spezielle Einstellungs-Optionen. Sogar auf meinem Keyboard ist so eine Struktur. Dort allerdings mit einem TFT Touch Screen. SO WEIT wollte ich nun doch nicht gehen.

Nun, ich habe das (20x4) Display ja schon seit Jahren in Besitz ... und schon vor längerer Zeit über „Schreiben UND Lesen“ etwas in Erfahrung gebracht. Habs aber noch nie wirklich "genau" studiert. Und am letzten Sonntag kam ich halt auf die Idee, so etwas auf dem 20x4 (später 40x4) auch einzusetzen. Ich denke in meinem jugendlichen Leichtsinn, das vereinfacht mir sehr vieles, wo andere halt nur immer wieder alles neu aufbauen wollen oder schräge Klimmzüge machen wollen oder müssen. Man ist ja bequem geworden (ich zumindest) und versuche alles, meine Bequemlichkeit zu pflegen...

Letztendlich sollen ja auch andere Menschen mit dem Gerät umgehen können – ohne dass ich erst ein mehrwöchiges Seminar zur Bedienung eines friemeligen und komplizierten Programmes anberaumen muß. Alles soll irgendwie recht „intuitiv“ und „benutzerfreundlich“ aufgebaut werden.

Wie auch immer, ich habe (analog Tommy56‘s Aussage) zu dieser „verrückten Idee“ bereits die „LiquidCristal.h / .cpp“ derart aufgeschlüsselt und zerlegt, dass sie DIREKT INNERHALB meines Sketches OHNE „#include...“ - aber dennoch als „Class“ sehr gut arbeitet. Nur mit den Dingen rund um das „LESEN“ bin ich noch etwas am Forschen und weiß im Moment noch nicht, wohin mich das treibt – und ob ich damit überhaupt Erfolg habe.

LG, Rudi

RudiDL5:
Nach dem Studium des Datenblattes von HITACH müßte es theoretisch möglich sein. „Wie selbstverständlich“ wird dort überall von 'schreiben' UND 'lesen' gesprochen.

Hat jemand nützliche Tipps zur Hand?

Suchst sowas:?

read()

read data byte from LCD
(requires r/w signal control)
returns negative value on failure

Schon zu Zeiten des C64 gab es Sprites, d.h. rechteckige Bildschirm-Ausschnitte die man beliebig vom Bildschirm lesen oder auf dem Bildschirm irgendwo darstellen konnte (PacMan...). Heute würd man sowas vielleicht Bitmap oder Icon nennen.

Bei Pixel-orientierten Bildschirmen (TFT...) könnte man zu den Funktionen GetPixel und PutPixel entsprechend noch GetImage und PutImage implementieren, zum Lesen und Schreiben von Blöcken von Pixeln, oder von Blöcken von Zeichen auf LCD Displays.

Für die Implementierung sollte man aber wissen, ob der Display-Controller das Auslesen des Speichers überhaupt erlaubt. Falls nicht, dann muß die Bibliothek eine Kopie des Displays beinhalten, die bei allen Änderungen am Bildschirm entsprechend aufdatiert wird. Bei 4x20 Zeichen werden dafür 80 Byte benötigt, das liegt durchaus im Rahmen des verfügbaren RAM.

BTW die LcdMenu Bibliotheken könnten schon geeignete Funktionen enthalten.

Als allererstes ist die R/W Leitung normalerweise fix auf Schreiben gestellt um ein Pin zu sparen.

Wenn Deine Bibliothek das nicht kann dann mußt Du sie erweitern.

Am einfachsten ist meiner Meinung den Displayinhalt in einem Array zwischenzuspeichern. Du braucsht zusätzlich zum Datenarray auch eine Adressvariable um bei unadresierten Schreibzugriffen zu wissen wohin die daten ins Array zu schreiben sind. Das LCD modul macht das auch automatisch ab Kurserposition.

Du kannst ja einfach eine Funktion schreiben die den ins Array und ins LCD Modul schreibt. Die Schreibzugriffe kannst Du im ganzen Sketch (außer in der Fuktion) einfach mittels Ersetzen austauschen.

zb LCD.print wird zu lcdprint und dort rufst Du LCD.print und Arrayabspeichern auf.
gleiches für Cursor setzen clear.

Grüße Uwe

Einstweilen erst einmal vielen Dank für die Ideen und Gedanken zu meiner Frage.

Suchst sowas:?

Danke für den Link. Das habe ich mir gestern noch kurz angesehen und finde, dass es viel Lesestoff ist den ich mir aber am kommenden WE in Ruhe ansehen werde. So beim schnellen "überfliegen" fand ich darin einige sehr nützliche Sachen, die ich für mich verwenden könnte.

Als allererstes ist die R/W Leitung normalerweise fix auf Schreiben gestellt um ein Pin zu sparen.

Das ist auf jeden Fall ein sachliches aber auch im ersten Moment "erschlagendes" Argument.

Wie schon von Tommy56 vogeschlagen, habe ich die LiquidCrystal.h bereits aufgeschlüsselt und fange an zu verstehen, was dort im Hintergrund abläuft. Auf jeden Fall werde ich das alles näher untersuchen. Vielleicht gelingt mir ja eine Lösung, ggf. auch mit einem Pin mehr, die genau das bewirkt was mir vorschwebt. Ein Pin mehr ist relativ egal, weil ich am 1284 noch genügend freie zur Verfügung habe.

LG, Rudi

RudiDL5:
Danke für den Link. Das habe ich mir gestern noch kurz angesehen und finde, dass es viel Lesestoff ist den ich mir aber am kommenden WE in Ruhe ansehen werde. So beim schnellen "überfliegen" fand ich darin einige sehr nützliche Sachen, die ich für mich verwenden könnte.

Naja - im Moment geht es nur um read aus dem Display.
Das macht die lib - unter dem Hinweis des auflösens eines möglicherweise bestehenden hardwareseitigen und nicht zu verändernden R/W-PIN auf dem Display. Siehe Uwe in #9
Dazu benötigt man aber erstmal eine Auskunft zur Beschaffenheit und viel besser einen Link zur Herkunft.

@my_xy_projekt

Vielen Dank für den Hinweis. Das mit eventuellen Problemen bei der Hardware ist mir auf jeden Fall bewußt. So auch die Aussage von @Uwe mit dem vielleicht fest verdrahtetem R/W-Pin. Das Gute daran ist aber, dass ich mir auf diesem Sektor absolut gar keine Gedanken machen muß.

Dieses o.g. „Große Projekt“ ist meine Anfang 2019 beschriebene Idee „Drumbox mit Arduino“ aus diesem Beitrag: Arduino Forum Leider ist es kurz danach zu erheblichen Störungen im familiären Umfeld gekommen... so dass ich erst jetzt in der „Corona-Ruhe“ die Muße gefunden habe, weiter daran zu bauen und zu experimentieren.

Tatsache ist, dass ich einzelne Komponenten aus dieser „Idee“ nicht als „großes Ganzes“ behandele, sondern die einzelnen Teile daraus autonom und steckbar sind. Bei Bedarf könnte ich also „mal eben“ eine der Platinen neu erstellen oder umbauen und anschließend wieder in das „Große Ganze“ integrieren.

So hatte ich z.B. das LC-Display ursprünglich via I2C angeschlossen. Es ist aber ebenso nicht fest verdrahtet und ich habe erst gestern „mal eben“ einen kleinen „Aufsteck-Adapter“ für den UNO R3 dazu gebastelt, bei dem ich alle Leitungen zum Display via Jumper einzeln ein- oder ausblenden kann. Quasi zur „Grundlagenforschung“ mit allen Freiheiten und ohne Wackelkontakte.

Nun, und in diesem Zusammenhang habe ich (wie von Tommy56 empfohlen) die „LiquidCrystal.h“ direkt als „Class“ in einen Test-Sketch integriert und kann damit experimentieren, OHNE auf jegliche externe LIBs via „#include“ zugreifen zu müssen. Der erste Schritt darin war das „Ein- und Ausschalten“ der Hintergrund-Beleuchtung mittels „lcd.backlight()“, was ich bisher nur aus der "LiquidCrystal_I2C.h" kenne. Für ein „stand-alone-Display“ ist das nicht vorgesehen. Meine Class-Adaption könnte das jetzt aber ebenso. Wobei hierzu dann 2 Widerstände und ein Transistor nötig wären. Mal sehen wie sinnvoll sich das alles verhält.

Genau so konnte ich nun (erfolgreich) damit experimentieren, wie ich mit dem „4-Bit-Modus“ und mit dem „8-Bit-Modus“ jonglieren kann. Ein Manipulieren des R/W-Pins ist ebenso machbar. Und letztendlich ist es mir gelungen, einzelne Methoden aus der Class mit separaten Commands nachzubilden. Egal ob lcd.setCursor(), lcd.clear(), lcd.wasauchimmer()...

Nun untersuche ich gerade, wie das halt mit dem „Lesen“ vom Display im 4- und 8-Bit-Modus funktioniert. Aber nachdem ich die LIB und auch die Angaben von HITACHI nun anscheinend recht gut verstanden habe... mache ich mir keine Sorgen mehr, dass mir meine LCD-Versuche letztendlich in der Form gelingen wie es mir vorschwebt.

LG, Rudi

Wenn ich früher Daten auf ein Display ausgegeben habe, dann habe ich immer einen Platz im RAM gehabt, auf den ich alles reingeschrieben habe, was ins Display sollte. Und in einem Interrupt mit festen Tackt wurde dieser Text aus dem RAM dann ins Display geschrieben. OK ich musste eigentlich nie wissen was im Display steht, aber auch das wäre bei dieser Vorgehensweise natürlich recht leicht. Jede Pos. am Display hatte eine Pos. in diesem "Displayspeicher".
Ich hatte auch noch einen Speicher, für sämtliche Pins an den PIO´s. Da war auch für jeden Pin eine Speicherstellt, wo ich 0 oder 1 reingeschrieben habe. Und die wurden dann im PIO-Interrupt auch in festen Zeitlichen Abständen entsprechend ausgegeben.

Franz

Ich finde es für einen großen Vorteil, der 20x4 (20x2, 16x4, 16x2, 16x1, 8x2, 8x1) LCD Displays, das man keinen extra Displayspeicher braucht. Auch braucht man kein Fontspeicher (außer man definitert Sonderzeichen).

Man schreibt einfach ins Display an Stelle y,x, fertig

Mache ich mit bei meinen Uhr-Thermometer Project zu nutze, die Temparatur wird einfach alle 10 Sec neu geschrieben und bleibt. Die Uhrzeit wird jede Sec neu geschrieben...

Nur zur Info und falls von Interesse:

Das LESEN vom LC-Display funktioniert! Besser als ich ursprünglich gehofft hatte... Daraus sind schon wieder viele interessante neue Sachen gewachsen, denn mit ein paar zusätzlichen Methoden wie

  • lcd.readByte( spalte, zeile );
  • lcd.backup();
  • lcd.restore();
  • lcd.clearLine( zeile );
  • lcd.scrollUp();
  • lcd.scrollDown();

die auf 16x2 UND 20x4 funktionieren, macht die Programmierung größerer Dinge darauf echt Spaß. Und es wird mir mit Abstand jetzt viel einfacher gemacht, als es mit den üblichen "Buffern" und ähnlichen haarigen Klimmzügen möglich wäre. Genau so wie ich es von "früher" her gewohnt bin und ich es immer geschätzt habe.

Bis demnächst und "man(n) liest sich"
LG, Rudi

Läßt Du uns auch an den Ergebnissen Deiner Arbeit teilhaben?

Gruß Tommy

Hallo Tommy,

klaro, auf jeden Fall. Nur ist das "im Moment" noch bei mir im "Rohzustand". Heißt: Ich muß aus dem Sketch erst mal eine separate LIB machen und kann das dann gerne zur Verfügung stellen. Ich weiß auch noch gar nicht, in wie weit das mit I2C funktioniert. Hierzu ist noch einiges an Forschung nötig. Bei meiner aktuellen Version habe ich den beschriebenen R/W-Pin einsetzen müssen. Und bei der Pin-Knappheit auf dem UNO ist das schon etwas "beengt". Daher ist der nächste Schritt halt die Verarbeitung via I2C.

LG, Rudi

Alles klar, dann weiterhin viel Erfolg.

Gruß Tommy

Ich dachte schon du hast eine LIB gefunden, die das alles kann :frowning:

Franz