Vertikal scrollen durch ein I2C 20x4 Display

Hallo Leute,
gibt es für so ein Display eine Funktion, mit der ich die Zeilen vertikal scrollen kann?

Bei jeder Eingabe einer neuen Zeile über eine Tastatur soll der bisherige Text nach oben geschoben werden, sobald mehr als 3 Zeilen beschrieben sind. Die Zeile 4 soll dabei statisch bleiben.
Genauso soll der Text mit den Pfeiltasten auch wieder nach unten gescrollt werden können.
Zeile 4 soll dabei auch wieder stehen bleiben.

Die Funktion brauche ich für eine Art Taschenrechner.
100->Enter,
300->Enter
200->Enter
Nach jedem Enter wird in Zeile 4 die Gesamtsumme angezeigt.
Jetzt 250->Enter
Dabei soll Zeile 1 nach oben im Nirvana verschwinden und in Zeile 3 die 250 angezeigt werden.
In Zeile 4 steht wieder die Gesamtsumme.
Bei Druck auf Pfeil nach oben:
Zeile mit der 250 verschwindet nach unten im Nirvana und in Zeile 1 erscheint die 100 wieder.

Außerdem bräuchte ich dafür ein dynamisches uint16_t Array, in dem die Zahlen gespeichert werden.
Vor Beginn der Rechnung ist nicht bekannt, wie viele Zeilen es am Ende werden.
Geht so etwas?

Jemand eine Idee?

Gruß
Fred

Das kannst Du doch ganz einfach selbst bauen.
Du hast den Inhalt der 2.und 3. Zeile doch in Variablen.
Die gibst Du dann in der ersten und zweiten aus.
In der 3. dann die neue Eingabe.

Gruß Tommy

Hallo Fred,
Da Du auch 'verschwunden' Zeilen wieder zurückholen willst, brauchst Du einen Puffer für alle eingegebene Zahlen. Sind das immer nur Zahlen in den Zeilen oder auch Texte? Wenn es nur Zahlen sind, ist das Speichern natürlich platzsparender, da Du dir nur die Zahlen merken musst. Ansonsten brauchst Du einen Puffer für die ausgegebenen Strings.

freddy64:
Vor Beginn der Rechnung ist nicht bekannt, wie viele Zeilen es am Ende werden.

Da wirst Du ein Maximum festlegen müssen um den Speicher für die Pufferung zu reservieren.
Dynamisch macht auf dem Arduino keinen Sinn.

Erst mal vielen Dank für die Replies,
Ich muss mich als alter Windows-Desktop-Programmierer (Visual Studio C++ mit MFC) noch an die Speichergrenzen der MMC's gewöhnen.
Früher habe ich Objecs erstellt und diese dann in einem ObjectArray gespeichert. Da gab es kein Limit und keine fest definierten Array Größen

foo = new myObj(bar);
objArray->add(foo);

Natürlich musste ich dann im destructor der Klasse wieder alle objects mit objArray->delete(foo) aus dem Speicher entfernen.

Fehler bei der Speicherverwaltung hat der DEBUGGER nach Programmende angezeigt:
Detected memory leaks .....

Hier geht alles etwas anders.
Ich habe jetzt ein Array mit der voraussichtlich maximalen Größe von 16 Elementen definiert.

#define MAX_ARRAY_SIZE 16
Das lasst sich immer noch ändern, falls die Eingaben in der Praxis länger werden sollten.

uint8_t currentRow = 0;
String number = "";

Druck auf eine Taste der Tastatur
if (keyboard.available()) {
char c = keyboard.readUnicode();
//ist der Tastencode eine Ziffer von 0-9
if (isNumeric(c) { // eine eigene Funktion, die die Tastaturcodes auswertet
number += c;
}
}

Nach jedem Druck auf "Enter" wird number.toInt() im Array gespeichert und currentRow um 1 erhöht.

Jetzt zum Scrollen:
Pfeil nach oben ->currentRow--;
if (CurrentRow >= 2) {
Zeile 1:
lcd.setCursor(0, 0)
lcd.print(array[currentRow-2])
Zeile 2:
lcd.setCursor(0, 1)
lcd.print(array[currentRow -1])
Zeile 3;
lcd.setCursor(0, 2)
lcd.print(array[currentRow])
}

Ist dieser Lösungsansatz in der Praxis einsetzbar?

Stimmt, damit wird currentRow für das Array geändert und die nächste Eingabe überschreibt ggf. einen vorhandenen Wert in dem Array.
Wenn ich eine zweite Variable verwende?
z.B. uint8_t lastInput speichert die letzte Eingabe im Array[lastInput] und currentRow verwende ich nur zum scrollen.

freddy64:
Ich muss mich als alter Windows-Desktop-Programmierer (Visual Studio C++ mit MFC) noch an die Speichergrenzen der MMC's gewöhnen.
Früher habe ich Objecs erstellt und diese dann in einem ObjectArray gespeichert. Da gab es kein Limit und keine fest definierten Array Größen

Natürlich musste ich dann im destructor der Klasse wieder alle objects mit objArray->delete(foo) aus dem Speicher entfernen.

Der C++-Compiler kann auch OOP, Du kannst also Objekte erstellen und zerstören. Außerdem gibt es die großen Brüder Teensy und ESP8566/32 mit mehr Speicher. Du könntest Dich also auf den großen Brüdern austoben und dann überlegen, ob Du es auf einen Arduino geschrunpft bekommst. Das hängt dann auch von Deinem Projekt ab.

Das liest sich möglicherweise etwas gagga, aber ich habe schon Programme auf einem Mega2560 begonnen und auf einem ProMini abgeschlossen.

Ich arbeite schon auf dem "großen Bruder" ESP32.
Im Moment ist mein größtes Problem die Trägheit der PS2Keyboard lib.
120+120+400 wie auf dem Taschenrechner ist nicht.
Es geht nur so:
eiiins -> zweiiii -> nuuul -> pluuus ->eiiins -> zweiii -> nuuul -> pluuus -> vieeer -> nuuul ->nuuul.
Für jeden Tastendruck ca. 0.3 Sekunden.

Ich werde wohl die Anfrage nach einer Arduino Kasse mit einem Stempel "Nicht lösbar" zurückschicken.

Hab so ein Teil mal für den RASPI mit 13" Touch-Screen gebaut.
quanta costa 300€

So ein Projekt ist eben nicht für 30€ aus dem Arduino-Baukasten realisierbar.

Hallo,

das diese Trägheit normal ist kann ich mir ehrlich gesagt nicht vorstellen.
Hast du die schon versucht? Soll auch mit Arduinos funktionieren
https://www.pjrc.com/teensy/td_libs_PS2Keyboard.html
Ansonsten wird woanders eine Bremse drin sein, so meine entfernte Vermutung.

@Doc
habe ich auch schon am Arduino probiert, kein Schnickschnack außer der Tastatur dran.
Das gleiche Resultat.

können solche Funktionen eine Verzögerung verursachen?

bool isNumber(char key) {
  if (key == 0x30 || key == 0x31 || key == 0x32 || key == 0x33 || key == 0x34 || key == 0x35 || key == 0x36 || key == 0x37 || key == 0x38 || key == 0x39 || key == 0x61) {
    return true;
  }
  return false;
}

bool isOperation(char key) {
  if (key == 0x2b || key == 0x3d || key == 0x45 || key == 0x46 || key == 0x4a || key == 0x64 || key == 0x65) {
    return true;
  }
  return false;
}

Wenn ja, wie kann ich das beschleunigen?

Seit wann ist ‘a’ eine Number?

Ansonsten:

bool isNumber(char key) {
  if (key >= 0x30 && key <= 0x39 || key == 0x61) {
    return true;
  }
  return false;
}

Gruß Tommy

Hi

Wobei selbst die zwölf-fach-Prüfung nicht zu einer merklichen Verzögerung führen dürfte.
Aber die 3-fach Prüfung von Tommy56 muß eben maximal nur 3x prüfen.

MfG

'a' ist die taste '00', deshalb in diesem Fall eine Number.
Die Tastatur ist eine POS Kassentastatur und da gibt es die '00', um die Eingabe zu beschleunigen.
Habe ich oben vergessen, zu erwähnen.
Die 3-fach-Prüfung sieht schon mal besser aus als mein Spaghetti ||.
Werde ich übernehmen.

Hallo,

zeig doch mal den gesamten Code inkl. Links zu verwendeten fremden Libs.
Derzeit vermute ich du "quälst" vielleicht dein Display unnnötig. :wink:

Momentan zeigt nur Serial.print(…) meine Tastatureingaben an und da nervt schon die Verzögerung der Tatstatur.
Tastendruck auf Taste x, geht, erneuter Tastendruck auf irgendeine Taste unter 0.3 Sekunden geht nicht
und Serial.print gibt keine Ausgabe zurück.

Verwendete Lib ist diese.

char c = keyboard.readUnicode();
Serial.print(F("Code "));
Serial.print(c);

Das Scrollen durch das Display steht noch hinten an.

Wenn Du weiterhin nur Bröckchen des Codes lieferst, wirst Du wohl nie ans Ziel kommen.
Du wurdest nicht umsonst nach dem ganzen Code gefragt.

Gruß Tommy

@Tommy56
Code Beispiel wäre der Sketch aus den examples der PS2Keyboard lib.
Simple_Test.ino

Kliiiieeeck geht, klick, klick, klick geht nicht.

Das glaube ich Dir nicht. In dem Beispiel gibt es kein readUnicode().
Aber wenn Du halt keine Hilfe brauchst, es ist Dein Problem, nicht unseres.

Gruß Tommy