Forum: Mikrocontroller und Digitale Elektronik ESP32 C++ Code Frage


von Thorsten S. (whitejack)


Lesenswert?

Nabend,

kann mir jemand sagen wie und wo ich in diesem ESP32 Codepaket:

https://files.waveshare.com/upload/6/6d/RGB-Matrix-P4-64x32-Demo.zip

ESP32/SimpleTestShapes

Ich die Anordnung der Panel verändern kann. Es muss an der Stelle sein, 
wo alle Routinen in den physikalischen Speicher schreiben.

Der Code ist so angelegt dass man bei 12 (PANEL_CHAIN 12) 64x64 Panel 
ein 768x64 Pixel Display erhält, also 12 Panel lang, ein Panel hoch.

Ich benötige nun 128x384 also 2 Panel lang und sechs Panel hoch.

Danke.

TS

von Εrnst B. (ernst)


Lesenswert?

Die Bibliothek organisiert ihre Framebuffer exakt so, wie die Displays 
angesprochen werden, und das sind eben 16 (4 Adress-Bits) lange 
Pixel-Zeilen pro RGB-Ausgang. (32 mit zusätzlichem E-Pin, daher kommen 
deine 64)

Wenn du die Panels anders anordnest, wirst du einiges am Code ändern 
müssen (updateMatrixDMABuffer(x,y,...) als Startpunkt), oder selber eine 
Koordinaten-Umrechnung in deinem Application-Code machen müssen.

: Bearbeitet durch User
von Thorsten S. (whitejack)


Angehängte Dateien:

Lesenswert?

Hallo Ernst,

danke für die Erklärung und den Einstiegspunkt. Ich nutze das Beispiel 
mittlerweile übrigens mit 4 bit Farbtiefe statt 8 damit ich 12 Panel 
betreiben kann.

Ich habe in der von dir erwähnten Funktion mal y_coord und x_coord 
direkt bei der Übergabe getauscht:

::updateMatrixDMABuffer(int16_t y_coord, int16_t x_coord, uint8_t red, 
....

Dann steht der Text auf dem Kopf und ist um 90° gedreht.

ALso folgendes ergänzt:

    if(x_coord<(768/2))
    {x_coord=(768/2-1)-x_coord;}

Damit habe ich den Text der so erzeugt wird:

  dma_display->setCursor(2, 1);
  dma_display->setTextColor(dma_display->color444(2,2,15));
  dma_display->println("0123456789ABCD");

Oben links auf meinem Großdisplay Testaufbau lesbar stehen. Zwei Pixel 
von links, einen von oben Abstand, wie erwartet. Also quer zur 
ursprünglichen Ausrichtung.

Natürlich komme ich nun in beide Richtungen (x und y) nicht über die 64 
Pixel hinaus. Im Hintergrund ist nach wie vor eine 768x64 (Breite x 
Höhe) Pixel Matrix. Ich würde ja nun entsprechend reagieren wollen, wenn 
also für y ein Wert größer 64 kommt, würde ich 64 abziehen und x so 
verändern dass ich auf dem Panel oben rechts lande, das geht aber nicht. 
Ich gehe davon aus, dass die Koordinate Höhe>64 schon vorher irgendwo 
abgefangen wird...

Es ist zum greifen nah...

Am Rande noch:
Der gefüllte violette Kreis und die beiden "Boxen", Rechtecke bleiben wo 
sie sind, werden nicht beeinfluss, der blaue Kreis sowie die das "X" 
also die gekreuzten Linien wandern mit dem Text mit nach oben.

von Thorsten S. (whitejack)


Lesenswert?

Εrnst B. schrieb:
> Die Bibliothek organisiert ihre Framebuffer exakt so, wie die Displays
> angesprochen werden

Die Methode heißt ja Update...

Gibt es also noch einen Zwischenspeicher von dem aus in den DMA Bereich 
mit Update kopiert wird?

von Thorsten S. (whitejack)


Lesenswert?

Das Display läuft nun wie gewünscht.

Ich habe die Probleme mit den Koordinaten nun gelöst. Ich habe dazu 
weitere defines für Koordinaten eingefügt, sodass das physikalische 
Display von dem logischen getrennt wird.


Zudem habe ich die Koordinatenumrechnung in der von Ernst benannten 
Funktion so aufgebohrt dass die Pixêl zum einen um 90° gedreht aufs 
Display geschrieben und auf die eine Hälfte rückwärts und auf beiden 
gespiegelt geschrieben werden.

Nun habe ich das gewünschte hochkante Display von 6x2 Modulen mit einer 
Auflösung von 128x384 RGB Pixeln mit einer Farbtiefe von sogar 12 Bit 
RGB, mehr als erwartet.

Es lässt sich Text in verschiedenen Größen sowie freie Linien und Kreise 
zeichnen, alles was ich für mein Projekt brauche.

Das einzige was nicht koordinaten-richtig ist, sind diese Funktionen:

dma_display->fillCircle()
dma_display->drawRect()

Warum auch immer, mein C++ ist über zwei Jahrzehnte her, ich kann den 
beim besten Willen nicht komplett lesen, manche Notationen sind mir 
wirklich entfallen :-) oder nicht bekannt.

Danke Ernst, du hast mir mit deinem kleinen Kommentar sehr geholfen!

Ps.: Die zweite entscheidende Stelle, neben der von Ernst erwähnten, ist 
im Headerfile:

ESP32-HUB75-MatrixPanel-I2S-DMA.h

Zeile:

677 const uint8_t   ROWS_PER_FRAME =
678 const uint16_t  PIXELS_PER_ROW =

Dort werden aus den festen Eigenschaften der verwendeten Module und der 
Anzahl der Module diese Beiden "Konstanten" erzeugt, die die 
Hardwarenahen Routinen nutzen um den Datenstrom für die Panel zu 
erzeugen.

: Bearbeitet durch User
von Thorsten S. (whitejack)


Lesenswert?

Ich kämpfe gerade doch noch mit den Adafruit Anteilen, denn anscheinend 
durchlaufen nicht alle Routinen den von Ernst genannten Punkt auch nicht 
die drawLine Funktionen.

Ich bin bei Adafruit_GFX::writePixel(), die wiederum drawPixel aufruft, 
drawPixel scheint eine überladene (ich meine so nennt sich das doch) 
Funktion zu sein.

Wenn ich an der Übergabestelle zu drawPixel x und y tausche, dann 
betrifft es wieder den Text, aber nicht die dma_display->drawLine() 
Funktionen, was mich wirklich wundert als Cpp Laien.

Eine mit dma_display->drawLine() gemachte Linie, bleibt bis jetzt immer 
an Ihrer Stelle, wie landet die im Speicher? Jedenfalls nicht über die

Adafruit_GFX::writePixel()

Funktion, die die drawPixel() aufruft

Hat das was mit den Fast-Geschichten und dem NO_FAST_FUNCTIONS zu tun? 
Alles sehr verworren für mich, ich verliere dort die "Spur" bei virtual 
und inline Funktionen ... die Stelle zu finden wo ::drawPixel zum 
Speicher kommt.

Ich rufe sie so auf:

dma_display->drawLine(0,0,0,63,dma_display->color444(15, 0, 0));

Da ich hier sehr viel überladerei bei den Farbwerten sehe, wenn ich das 
richtig interpretiere...

Danke

Nachtrag
Ich habe nun diesen Schalter:

#define NO_FAST_FUNCTIONS

aktiviert, nun geht alles wie es soll - hoffe ich.

: Bearbeitet durch User
von Thorsten S. (whitejack)


Angehängte Dateien:

Lesenswert?

Hier noch ein Bild dazu (von vor einem Monat).

Meine Applikation läuft.

Danke nochmal!

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.