Forum: Mikrocontroller und Digitale Elektronik 128x64 display im loop immer nur pixelweise ergänzen


von Christoph E. (stoppi)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

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.

von Pandur S. (jetztnicht)


Lesenswert?

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.

von Christoph E. (stoppi)


Angehängte Dateien:

Lesenswert?

Danke für die Antworten, Ralph und Sabberalot. Werde mich danach 
umschauen...
Bräuchte ich nicht so ein Gatter anstelle des XOR?

: Bearbeitet durch User
von Thomas K. (muetze1)


Lesenswert?

Anhand deiner Tabelle wäre Y = B. Da bräuchtest du kein Gatter, nur ein 
Stückchen Draht und A kannst du ignorieren...

von Peter D. (peda)


Lesenswert?

Die Angabe des konkreten GLCD-Typs wäre durchaus sinnvoll.
Z.B. hat der T6963 Controller Bit-Set/Reset-Befehle, um einzelne Pixel 
zu ändern.

von Christoph E. (stoppi)


Lesenswert?


von Bernd S. (wirrer_haarschopf)


Lesenswert?

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.

von georg (Gast)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

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

von Der Mitleser (Gast)


Lesenswert?

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?

von Christoph E. (stoppi)


Lesenswert?

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

: Bearbeitet durch User
von Adam P. (adamap)


Lesenswert?

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.

von Pandur S. (jetztnicht)


Lesenswert?

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.

von Christoph E. (stoppi)


Lesenswert?

Danke einmal für die Anregungen und Hinweise. Ich werde mir das einmal 
zu Gemüte führen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.