C OLED - Grafikdisplay -> Denkanstöße

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Moin moin,

ich habe da glaube ich ein großes logisches Problem.
Möchte gerne in mein "Virtuelles Display RAM", die Fonts kopieren..
Sprich aus der "Headerdatei" das entsprechende Zeichen.
Das Zeichen zu suchen ist auch nicht das Thema.

Es geht jetzt viel mehr darum, es in den "Virtuellen Display RAM" zu schreiben..
Da der "Virtuelle RAM" ein "Längsspeicher" ist und nicht "128 Pixel" in der Breite
und "64 Pixel" in der Höhe ist, sondern komplett "Längs" (Eindimensional) "SSD1306_LCD_WIDTH * SSD1306_LCD_HEIGHT ) / 8" Bytes groß.

Hier mal ein Ausschnitt aus meinem "Pseudocode"..



CodeBox C
#define SSD1306_LCD_WIDTH 128
#define SSD1306_LCD_HEIGHT 64

static uint8_t DisplayRam[ ( SSD1306_LCD_WIDTH * SSD1306_LCD_HEIGHT ) / 8 ] = "0xFF";

// Zeichen 51 Dez. , 14 Pixel hoch
// 0x0C, 0x02, 0x22, 0x22, 0x22, 0xDC, 0x0C, 0x10, 0x10, 0x10, 0x10, 0x0C,

Da das Zeichen jetzt höher als 8 Pixel ist, würde ein Teil von dem Zeichen
direkt neben den Zeichen in den "Virtuellen RAM" landen anstatt dort drunter, wenn ich es so in den „Virtuellen RAM“ schreiben würde.
Nun weiß ich nicht weiter.. Wie bekomme ich die unteren Pixel auch dort hin, wo sie hingehören?
Wie muss der "Längsspeicher" beschrieben werden ( wie müsste die Funktion aussehen? )..
 
Die Displays haben (wenn ich das richtig in Erinnerung habe) quasi mehrere Pages, die je acht Punkte hoch sind (durch je ein Byte repräsentiert).
Bei Deinem Beispieldisplay hast Du also acht Pages je acht Punkte in der Höhe und 128 Punkte (Bytes pro Page) in der Breite.
Der Speicher ist Deinen Worten nach eindimensional, also 1024 Bytes.
die erste Page wäre von 0..127
die zweite 128..255
dritte 256..383
vierte 384..511
fünf 512..639
sechs 640..767
sieben 768..895
acht 896..1024
Und jetzt mach mal binäre oder Hexadezimale Zahlen draus...

Was'n das für'n komisches Zeichen in Deinem Code-Schnipsel bzw wie ist das zu verstehen?
wenn man die 14 Bytes untereinanderschreibt kommt man auf:
Code:
°°°°██°°
°°°°°°█°
°°█°°°█°
°°█°°°█°
°°█°°°█°
██°███°°
°°°°██°°
°°°█°°°°
°°°█°°°°
°°°█°°°°
°°°█°°°°
°°°°██°°
 
Was'n das für'n komisches Zeichen in Deinem Code-Schnipsel bzw wie ist das zu verstehen?
wenn man die 14 Bytes untereinanderschreibt kommt man auf:
Wie hast du denn die schöne Zeichnung gemacht? Gibt es da ein Tool für?
Wenn ich das rekonstruieren möchte, fummele ich mir immer ein mit "Excel" ab.. :/

Richtig, die ganzen Zeichen sind in dem Array auf dem Kopf also gespiegelt.
Ich habe bereits eine Funktion geschrieben die mir die Bytes direkt auf das Display
zeichnen. Nun würde ich es aber gerne so umbauen, dass es erst in einem internen RAM
landet und dann komplett der ganze Frame auf einmal gesendet wird..
 
Wie hast du denn die schöne Zeichnung gemacht?
ASCII-Codes...
█ = 219
° = 248 (hätte man vielleicht auch ░ = 176 nehmen können)
Und das ganze in 'ner Code-Box, damit die Maße der Zeichen stimmen...

Warum drehst Du den Text um 90°?

Also mal grundsätzliches zum SSD1306:
Sofern ich den richtig in Erinnerung hab(!!), kann der wahlweise parallel, via 4wire-SPI, 3wire-SPI und 2wire-I²C angebunden werden. Von den parallelen Modi hab ich keine weitere Ahnung, die SPI-Modi erlauben aber kein Zurücklesen des internen Speichers. Beim I²C wird der Speicher über einen anderen Pin (D2) ausgegeben als eingelesen (D1), es müssen beide verbunden werden um lesen zu können. Inwiefern bei fertigen Displays diese Verdrahtung angewendet wurde, kann nicht immer beantwortet werden.

Da Deine Fonts eine andere Höhe als eine Page (8) aufweisen, muß ein Zeichen über mehrere Pages geschrieben werden, bzw in Pages unterschiedliche Zeichen gemischt werden können. Dazu ist es im allgemeinen nötig, den Inhalt der Page lesen zu können. Wenn das nicht aus dem tatsächlichen Display geht, kannst Du stattdessen ein Abbild im Controller erzeugen.

Daß muß nicht zwingend ein Pixel-Abbild sein - wenn nur irgendwelche Fonts in zB 14 Pixel hohen Zeilen dargestellt werden sollen, kannst Du auch die Zeichen des Fonts festlegen, und im Abbild dann nur noch die Codes (ASCII) Deiner Fonts (also ein Byte pro Zeichen auf dem Display statt 128*8=1024 Bytes für das ganze Display).

Wenn Du hingegen zusätzlich auf dem Display irgendwas "zeichnen" lassen willst, reicht das nicht.

Generell ist es einfacher, die Fonts so zu orientieren, wie sie auf dem Display erscheinen...

Versuchs erstmal mit acht Pixel hohen Fonts, bevor Du höhere Fonts in den Pages zusammenmischst...
 
Warum drehst Du den Text um 90°?
Diese Fonts habe ich schon fertig aus dem Netz gezogen. Mit meiner Funktion die ich mir geschrieben habe, kann man diese Fonts auch darstellen.
Da das Display wie Du schon sagtest in "Pages" unterteilt ist, ist ein "5x8" Zeichensatz dafür ideal.

EDIT: Das Font drehe ich in meiner Software nicht. Diese sind schon so angelegt.

Nur besteht das Problem weiterhin, dass mein Zeichensatz (Font) nicht richtig in den "Virtuellen RAM" geschrieben wird.
Dafür muss ich mir eine Routine überlegen, die genau dies macht. Da ist aber schon das Problem.



Versuchs erstmal mit acht Pixel hohen Fonts, bevor Du höhere Fonts in den Pages zusammenmischst...
Das klappt auch.
 
Zuletzt bearbeitet:
Anbei mal ein Beispiel Font.
Hiermit schreibe ich meine Zeichen auf das Display ( bis jetzt noch direkt.. ).


CodeBox C
void glcdPutc(char c, uint8_t y, uint8_t x)
{
 uint16_t index = 0;
 uint8_t  page = 0;
 
 font = calcFontStart( c , font , font.fontPtr );
 
 #define FONT_IS_FIXED   0x01
 #define FONT_IS_NOT_FIXED  (!(FONT_IS_FIXED))
 /*
 * Ist wichtig für den Abstand der Zeichen!
 */
 if (font.fontPtr[7] == FONT_IS_FIXED)
 {
  font.width = font.fontPtr[2];
 }
 
 glcdGoto( y / 8 , x );
 for ( page = 0 ; page < ((font.fontPtr[3] / 8 ) + 2 ) ; page++ ) // Berechne die Anzahl der benötigten Reihen
 {
  /*
  * Bei Fonts die höher als 8 Pixel sind, müssen die letzten Zeilen dementprechend behandelt werden.
  * Es entsteht eine Lücke, weil das Font nicht kompatibel zu einem senkrecht zeichnenden Display ist
  */
  if ( ( page == ( ( ( font.fontPtr[3] / 8 ) + 2 ) - 1 ) ) && font.fontPtr[3] > 8 )
  {
   for ( ; index < ( font.width * page ) ; index++)
   {
    ssd1306SendData( ( font.fontPtr[ font.indexNum+index ] ) << ( ( page * 8 ) - ( font.fontPtr[3] ) -1 )  );
   }
   break;
  }
 
   for ( ; index < ( font.width * page ) ; index++ )
   {
    ssd1306SendData( ( font.fontPtr[ font.indexNum + index ] ) );
   }
  glcdGoto( (( y / 8 )  + page) , x );
 }
}
 

Anhänge

  • Arial_14.h
    9,7 KB · Aufrufe: 1
Hier mal ohne VRAM.

8049

Die Uhrzeit wird mit einem 14 Pixel Font auf das Display geschrieben, die anderen Parameter sind in einem 5 x 8 Font hinterlegt.
 
Danke für die Hilfe.. Hab es jetzt nach endlichen "Minuten" lösen können.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)