[Gelöst] TFT / besserer Code gesucht

Hallo!
Ich suche momentan nach einem bunten TFT-Display, das von meinem Arduino jede Sekunde so etwa 30 Mal vollständig neu geladen werden kann. Es sollte mit meinem Due kompatibel sein und im Idealfall nicht den DAC0 benötigen. Die Größe sollte mindestens 128x128 sein, touch brauche ich nicht, wäre aber nett. Ich habe momentan ein ST7735-Adafuit-Display, da kann man so einfache Sachen wie Pong spielen, bei denen nicht unbedingt das Display vollständig mit 30 FPS neu geladen, sondern nur der Ball schwarz überpinselt und an einer neuen Stelle wieder hingemalt werden muss. Wenn ich nur Pong spielen will, ist das ganz witzig, aber nicht, wenn ich jedes Mal das Display neu laden will, z.B. für kleine Videos oder so, das schafft mein Due genauso wenig wie mein Uno, das flimmert nur vor sich hin. Ich habe versucht, die Display-Daten zu speichern, hat es nicht geklappt. Das Display wurde nur noch 1x pro Sekunde neu geladen, es war zum vergessen. Obwohl meine Rechnung etwas anderes gesagt hat: Der Lib konnte ich entnehmen, dass das Display eine SPI-Übertragungsrate von 24000000 hat. Wenn jetzt also an das Display die Farbe (2 Bit) und vielleicht noch X und Y in jeweils 1 Bit 128x128 Mal versendet, also würde das 24000000 / ((48 ) * (128128)) = 45.7764 ergeben, laut meinem GTR. Das könnte bei komplizierten Prozessen problematisch werden, aber nicht, wenn einfach nur ein Pixel über den Bildschirm wandern soll. Mein Code:

#include <Adafruit_GFX.h>    
#include <Adafruit_ST7735.h> 
#include <Adafruit_ST7789.h> 
#include <SPI.h>
#define TFT_CS   10
#define TFT_RST  -1
#define TFT_DC   8
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);
uint16_t buffer[128][128];
void setup() {
  Serial.begin(9600);
  tft.initR(INITR_144GREENTAB);
  tft.fillScreen(ST77XX_BLACK);
  clear();
}
uint16_t bufPos = 0;
void loop() {
  clear();
  drawPixel(bufPos & 127, bufPos >> 7, ST77XX_WHITE);
  display();
  delay(20);
  bufPos++;
}
void clear(){
  for(byte i = 0;i < 128;i++){
    for(byte j = 0;j < 128;j++){
      buffer[i][j] = 0;
    }
  }
}
void drawPixel(byte x, byte y, uint16_t color){
  buffer[x][y] = color;
}
void display(){
  for(byte i = 0;i < 128;i++){
    for(byte j = 0;j < 128;j++){
      tft.drawPixel(i, j, buffer[i][j]);
    }
  }
}

Warum klappt das nicht?
Brauche ich ein neues Display oder einen neuen Code?

Hi

128 wird 'nicht ganz' in ein Bit rein passen.
Eher werden dafür 7 Bit benötigt.
Womit sich die zu übertragende Datenmenge von 4 auf 16 Bit erhöht hat.
(wobei mir Deine Rechnung nix sagt)
Wenn jetzt das Protokoll eh ganze Byte für X und Y haben will, sind noch zwei Bit mehr beteiligt.

Stichwort Protokoll: Schon Mal reingeschaut, was Da wirklich alles versendet wird, bevor ein Punkt irgendwo erscheint?

Auch ganz triviales Zeug - z.B. Pong, womit man heute keinen 3-Jährigen mehr vom Handy weg locken kann - will immer noch komplett programmiert sein, mit allen Schikanen, wie einem Ball, Der sich nur pixelweise bewegt.

MfG

postmaster-ino:
Hi

128 wird 'nicht ganz' in ein Bit rein passen.
Eher werden dafür 7 Bit benötigt.
Womit sich die zu übertragende Datenmenge von 4 auf 16 Bit erhöht hat.
(wobei mir Deine Rechnung nix sagt)
Wenn jetzt das Protokoll eh ganze Byte für X und Y haben will, sind noch zwei Bit mehr beteiligt.

Stichwort Protokoll: Schon Mal reingeschaut, was Da wirklich alles versendet wird, bevor ein Punkt irgendwo erscheint?

Auch ganz triviales Zeug - z.B. Pong, womit man heute keinen 3-Jährigen mehr vom Handy weg locken kann - will immer noch komplett programmiert sein, mit allen Schikanen, wie einem Ball, Der sich nur pixelweise bewegt.

MfG

Ich lern's nie, dass es einen unterschied zwischen i und ty gibt! Aber eigentlich war das auch in meine Berechnung einbezogen.
Ich habe schon Pong programmiert. Sogar mit 2-Spieler-Modus, Farbauswahl von Paddle und Ball und Highscore-Speicherung auf einer SD-Karte. Bis jetzt mein längstes Programm. Und auch nicht einfach den Ball im 45°-Winkel, sondern mit Sinus und Cosinus. Schon Monate her.
Meine Rechnung für die FPS-Rate:
24000000 Bits / Sekunde
4 zu übertragende Bytes
8 Bit = 1 Byte
128x128 Pixel
24000000 / ((48) * (128128))

Okaaaaay, ich habe mal ins Protokoll geschaut, das ist echt sch ... ön blöd für mein Vorhaben.

postmaster-ino:
Pong, womit man heute keinen 3-Jährigen mehr vom Handy weg locken kann

Also in derSchule habe ich das mit meinem Pong schon geschafft. Da wollten das alle spielen und haben sich sogar halb darum gekloppt. Bei "Flagman" war's noch extremer.
Aber bei sowas muss man darauf achten, dass es nicht zu professionell aussieht. Ein Arduino Uno und daneben ein Breadbord mit 100 Kabeln interessiert jeden, aber eine kleine, nette Kiste mit einem rausschauenden Joystick - das hat der bestimmt gekauft!

Gibt es eine Möglichkeit, diesen ganzen setAddrWindow-Stuss zu vermeiden?

Was meinst Du damit?

Gruß Tommy

Schau Dir mal Lieber das Bitmap Example für Dein Vorhaben an.

Ich schaue mal kurz ob ich Dir das anpassen kann.. ansonsten gäbe es noch eine Lib von Paul Stoffregen

Echt nett von dir!
Ja, das Bitmap-Beispiel, das klappt gut, aber nicht zu schnell. Der braucht schon so 'ne halbe Sekunde, bis die Bitmap zu sehen ist.

Ich glaube, ich konnte es dem Beispiel entnehmen. An den Anfang meines void display() muss tft.setAddrWindow(0, 0, 127, 127) und das drawPixel(i, j, buffer_[j]) muss durch pushColor(buffer*[j]) ersetzt werden. Richtig?*_

Versuch mal das hier..

So hab ich eine andere Adafruit Lib optimiert.. habe keinen due, daher kein Plan ob das so reicht.

Bis jetzt haben alle Uno-Sketche von mir auf dem Due geklappt, es wird, glaube ich, eher andersrum kritisch, der Arduino Due hat mehr Ram und Flash.

HTML-Fan:
Bis jetzt haben alle Uno-Sketche von mir auf dem Due geklappt, es wird, glaube ich, eher andersrum kritisch, der Arduino Due hat mehr Ram und Flash.

Mir ging es eher um eine Doppelinitialisierung des SPI, bzw Mitnutzung der Base SPI Klassen. Beim ESP32 zum Beispiel kann man die aus den Libs erstellten SPIs nicht mitnutzen und muss diese mit transaction neu initialisieren. Es gab schonmal keinen Kompilierfehler.

EDIT:
Bei einigen Librarys von Ada wird aus dem SPiff gelesen, über schleifen hin und her kopiert, durch 2 RGB Conversions geschickt und dann noch nach setAddrwindow einzeln mit drawPixel abgeschickt.

Auf dem ESP ging das bei 480x272px bei 3byte/Pix von ursprünglich 600ms auf 80ms zurück.. im Prinzip nur noch genau solang wie ein SPI halt für die Bytes brauch.

Also dieser Code, den du mir geschickt hast, der klappt nicht. Das Display bleibt schwarz.

Ich habe den code unter dem gleichen Link aktualisiert..

Versuch das mal.. funktioniert das Fill, blinkt das Display rot/schwarz/weiss?

Ich habe es selbst herausgefunden: Man muss zuerst den CS auf LOW und den DC auf HIGH setzen und nach der Übertragung den CS auf HIGH.
Es entsteht ein merkwürdiges lila Muster.

Kennt ihr zufällig ein Programm, das ein Video in Bilder umwandelt, also aus einem 1-Sekunden-Video mit 30 FPS 30 Bilder werden?

Allgemeine Tools findet man bei Google.. mit Irfanview kann man dann mit der Stapelverarbeitung alle auf einmal zum BMP konvertieren.

Hi,

Frage mich aber nicht wie, ich habe vor 5 Jahren das letzte mal damit (Vorgänger VirtualDub) was gemacht.
Aber es geht definitiv damit Video -> Bilder, als auch Bilder -> Video, oder Video zu Video und dabei verschiedene Filter drüber jagen.

Gruß André