Hallo!
Gibt es eine Möglichkeit unter Arduino, ein 128x64 LCD im Loop nur immer
um einzelne Linien zu ergänzen und nicht jedes mal das ganze Bild von
neuem zu zeichnen?
Das Programm wird nämlich sehr langsam, wenn immer alle Linien neu
gezeichnet werden. Es würde maximal nur 1 Pixel hinzukommen von einem
Bild zum nächsten. Und da habe ich mir gedacht, ich kann dieses Pixel
zum bereits vorliegenden Bild hinzufügen.
Ich verwende die <U8glib.h> library. Derzeit zeichne ich das Bild nur
neu, wenn es die maximale y-Länge von 63 Pixel erreicht wird:
if (int(Faktor * Pulshoehen[Index]) > 62)
{
u8g.firstPage();
do
{
u8g.drawLine(0, 63, 127, 63);
u8g.drawLine(0, 0, 0, 63);
for (int i = 0; i < 128; i++)
{
u8g.drawLine(0+i, 63, 0+i, 63 - int(Faktor * Pulshoehen
[i])); // zeichnen aller Treffer
}
}
while( u8g.nextPage() );
Faktor = Faktor / 2; // Reduzierung des Maßstabs um die
Hälfte
}
Mit u8g.firstPage(); lösche ich aber quasi den Memory und ich bin
gezwungen, alle Linien neu zu zeichnen anstatt nur eine einzelne um 1
Pixel längere Linie hinzuzufügen.
Habe schon probiert, nur die drawLine-Befehle ohne while
(u8g.nextPage()) Schleife aufzurufen. Da zeichnet er aber einen Mist.
Und diese while-Schleife außerhalb des Loops zu positionieren geht ja
auch nicht...
Vielleicht könnt ihr mir ja helfen und sagen, ob dies prinzipiell
machbar oder eben nicht machbar ist.
Es ist ein I2c 128x64 Display mit nur 5 Anschlüssen (siehe Abbildung).
Danke im voraus, stoppi
Explizit dein Display kenne ich nicht, aber bei monochromen (SPI)
Displays ist es i.d.R. so, dass das Display-RAM nur beschreib- aber
nicht lesbar ist. Das hat zur Folge, dass nur 8 Pixel (in einem Byte
sind 8 Bildpunkte gespeichert) gleichzeitig gesetzt werden können.
Wenn du einen Graph zeichnen möchtest, mußt du den neu zu zeichnenden
Pixel und dessen "Nachbarn" im Byte neu zeichnen.
Hierfür mußt du auf das Displayram direkt zugreifen.
Bei einem Schwarzweiss LCD bearbeitet man immer 8 pixel aufs mal. Die
sind senkrecht uebereinander. Und ja, wenn sich immer nur ein pixel
aendert, kann man das mit einem XOR machen.
Ich benutze die u8g2 lib am STM32 ohne Arduino. Es kann also sein, dass
ich voll daneben liege, aber die Standard u8g2 macht SPI über
Bitbanging. Auf dem STM32F411 mit 84MHz ergibt sich dabei ein SPI Takt
von nur etwa 270kHz (gemessen). Auf dem Arduino mit 16MHz wird es wohl
noch viel weniger sein.
Ändert man die entsprechenden Call Backs, so dass sie die SPI Hardware
nutzen (was gar nicht so schwer ist), dann sinkt das Bedürfnis nach
bitweisen Updates rapide.
Christoph E. schrieb:> ein 128x64 LCD im Loop nur immer> um einzelne Linien zu ergänzen
Warum im loop - ein übliches Verfahren ist ein Speicherabbild des
Displays, in dem die nötigen Änderungen gemacht werden, und ein
Hintergrundprozess (Time Interrupt), der das Display aus dem RAM
auffrischt. Das kann man leicht so einstellen, dass das Auffrischen
einen bestimmten Prozentsatz der Rechenzeit belegt.
Georg
georg schrieb:> Warum im loop - ein übliches Verfahren ist ein Speicherabbild des> Displays,
Der Trick der u8g-lib ist, daß sie ohne dieses Speicherabbild auskommt,
um sie auf µCs mit kleinem RAM einzusetzen. Es ist eine lib für kleines
RAM und nicht für schnelle Bilder.
MfG Klaus
Im Grunde müsstest Du dir immer nur von den 128 Spalten den höchsten
Pixel merken, vergleichen, und dann bei der einen Spalte den
nächsthöheren Pixel setzen. Vielleicht gibt es in dieser Library so
etwas wie drawPoint?
Vielen Dank einmal für die Hilfestellungen...
Dem Gesagten entnehme ich also, dass es in dieser Konstellation
(library) wohl nichts wird mit meinem Vorhaben.
Es ändert sich eigentlich pro Durchlauf maximal die Höhe einer Spalte um
1. Wenn der Stauchungsfaktor größer als 1 ist, dann ändert sich die Höhe
einer Spalte nur nach mehrmaligen Durchläufen. Da sich in der Regel also
nahezu nichts ändert pro Durchlauf ist der immer erfolgte komplette
Bildaufbau extreme Zeitverschwendung.
Das merke ich eben, wenn ich das Bild nur dann erneuere, wenn ein Balken
die maximale Höhe (64 Pixel) erreicht hat und der Stauchungsfaktor *2
genommen werden muss. Dann erhalte ich gefühlte 50mal schneller ein
komplettes Spektrum
Hey Christoph,
falls es sich wirklich um den ST7920 handelt, dann werden für ein
Schreibvorgang 2 Byte gesendet, die 16 Pixel entsprechen...
laut Datenblatt liegen die aber horizental im Display-RAM.
Seite 15:
https://www.lcd-module.de/eng/pdf/zubehoer/st7920_chinese.pdf
Schreibvorgang: Seite 22
Vertikal wäre natürlich für deine Anwendung optimal, aber falls du dir
doch noch ein Speicherabbild im RAM vorhalten würdest, dann könntest du
es wohl auch realisieren.
Dan werden halt die Pixel links/rechts auch erneut geschrieben, aber 2
Byte übertragen ist besser wie das ganze Bild.
Mit einem XOR kann man gezielt einzelne Bits in einem Byte invertieren.
0b00010000 XOR 0b11111111 = 0b11101111
0b00010000 XOR 0b00000000 = 0b00010000
resp
0b00011000 XOR 0b11111111 = 0b11100111
0b00011000 XOR 0b00000000 = 0b00011000
Das XOR ist ein Befehl des Prozessors. Gibt's auch in C. Die Operanden
sind kommuntativ.