Moin! Ich suche einen passenden Font für die Displays, die oben gelb und unten blau sind. Da ich einen 32 Bitter nutze sind die bestehenden als 16 Bit Werte hinterlegt, 8 Bit nützt mir also leider wenig, das wäre zu viel Tipparbeit. Problem beim bestehenden ist, dass bei manchen Buchstaben g,j, etc unten ein paar Pixel blau sind. Da die Hersteller sicher für mich keine extra gelben Zeilen einfügen bleibt nur der Font Wechsel. Hat da vielleicht jemand einen? 11x18 sollte es aber sein, für den drunter braucht man schon ne Lupe.
Wie viele Pixel misst denn der gelbe Rand? Das wäre vielleicht die wichtigste Info.
u8g2 schrieb: > u8g2 hat viele fonts Ja, da habe ich auch schon dran gedacht, die habe ich im Arduino irgendwo gesehen. Ok, ich dachte jemand hätte das zufällig schon mal gehabt. Der gelbe Rand misst 10 Pixel glaube ich. Genau weiss ich das nicht.
Kannst ja mal fotografieren, vergrößern und auszählen. Die Gesamthöhe ist 32 oder 64?
Christian J. schrieb: Da ich einen 32 Bitter nutze sind die bestehenden als 16 Bit > Werte hinterlegt das verstehe ich nicht, was hat die Wortbreite des Prozessors mit den Fonts zu tun? Ob ein Font als Bit-, Byte oder 16/32 Bit breites Wort abgelegt ist, das interessiert doch nur die Routine die Zeichen vom Fontspeicher in den Grafikspeicher überträgt. Und da gibt es viele verschiedene Formate und Speichermöglichkeiten. Und ich habe eine Fontdefinition auch noch nie abgetippt, vorhandene kann man kopieren oder lässt einen Fontgenerator das include erzeugen. Ein guter Ansatz ist in der Adafruit GFX Library, da können alternativ zu den fixed size auch custom fonts benutzt werden. Da werden GNU Free Type Fonts genutzt, von denen es jede Menge gibt. https://learn.adafruit.com/adafruit-gfx-graphics-library/using-fonts Ein Generator wird mitgeliefert, es gibt aber auch einen netten Online Generator: http://oleddisplay.squix.ch/#/home Diese Fonts sollten aber in einem Buffer generiert werden und dann am Stück zum Display geschickt werden. Kostet etwas mehr Speicher, sollte für deine 32 Bitter aber kein Problem sein.
Johannes S. schrieb: > Ein Generator wird mitgeliefert, es gibt aber auch einen netten Online > Generator: > http://oleddisplay.squix.ch/#/home Das ist ja ein nettes Teil! Da muss ich aber meine Pixelroutine umschreiben. Ist ein anderes Prinzip. Und halt etwas mehr Denkarbeit..
Johannes S. schrieb: > das verstehe ich nicht, was hat die Wortbreite des Prozessors mit den > Fonts zu tun? Er ist zu bequem, jedesmal 0x hinzuschreiben, das will er auf die Hälfte reduzieren. Abgesehen davon gibt es hier im Forum bereits ausreichend an Software dafür, so daß man sich das manuelle Schreiben der Glyphen als Quelltext ersparen kann. Siehe z.B. FM.EXE W.S.
Christian J. schrieb: > Da muss ich aber meine Pixelroutine > umschreiben. Wenn man die Adafruit GFX nicht komplett nutzen will, dann kann man den Part mit dem Zeichen Ausgeben schon rausoperieren, das hat nicht viele Abhängigkeiten. Die Lib ist C++, Vorteile sind das diese damit für viele verschiedene Displays incl. LED Matrizen verwendet werden kann und auch mehrere Displays sind einfach mehrere Instanzen.
Johannes S. schrieb: > das verstehe ich nicht, was hat die Wortbreite des Prozessors mit den > Fonts zu tun? Ob ein Font als Bit-, Byte oder 16/32 Bit breites Wort > abgelegt ist, das interessiert doch nur die Routine die Zeichen vom > Fontspeicher in den Grafikspeicher überträgt. Jojo, kläre mich doch mal auf. Dieser Font Generator erzeugt ja allerhand kryptisches Zeugs. Meine Lösung, irgendwo abgeschrieben: Die Fonts werden stur pixelweise kodiert, pfeif auf Platz, davon habe ich 512kb. Die Routine zieht sich Breite unf Höhe und liest einfach soviel Bytes, wie ein Buchstabe hat. Bei diesem Generator aber steckt mehr Hirnschmalz drin, da wird wohl optimiert und damit wird das Ganze komplizierter. Ich nutze weder Arduino, noch irgendwas aus diesem Universum, auch kein C++, nur die Standard C Libs. Mehr ist das nicht. Schaue ich mir eben die GFX Ada LIb an sprengt der Source Code ja schon alle Grenzen.....
1 | /
|
2 | // Draw 1 char to the screen buffer
|
3 | // ch => Character to write
|
4 | // Font => Font to use
|
5 | // color => Black or White
|
6 | //
|
7 | char ssd1306_WriteChar(char ch, FontDef Font, SSD1306_COLOR color) |
8 | {
|
9 | uint32_t i, b, j; |
10 | |
11 | // Check remaining space on current line
|
12 | if (SSD1306_WIDTH <= (SSD1306.CurrentX + Font.FontWidth) || |
13 | SSD1306_HEIGHT <= (SSD1306.CurrentY + Font.FontHeight)) |
14 | // Not enough space on current line
|
15 | return 0; |
16 | |
17 | // Translate font to screenbuffer
|
18 | for (i = 0; i < Font.FontHeight; i++) { |
19 | b = Font.data[(ch - 32) * Font.FontHeight + i]; |
20 | for (j = 0; j < Font.FontWidth; j++) { |
21 | if ((b << j) & 0x8000) |
22 | ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR) color); |
23 | else
|
24 | ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); |
25 | }
|
26 | }
|
27 | |
28 | // The current space is now taken
|
29 | SSD1306.CurrentX += Font.FontWidth; |
30 | |
31 | // Return written char for validation
|
32 | return ch; |
33 | }
|
Na gut, das kriegen wir noch hin... ich muss ja nicht jede Zeile verstehen, dieses PROGMEM gibt es nicht. Hauptsache es funktioniert....
1 | // Draw a character
|
2 | /**************************************************************************/
|
3 | /*!
|
4 | @brief Draw a single character
|
5 | @param x Bottom left corner x coordinate
|
6 | @param y Bottom left corner y coordinate
|
7 | @param c The 8-bit font-indexed character (likely ascii)
|
8 | @param color 16-bit 5-6-5 Color to draw chraracter with
|
9 | @param bg 16-bit 5-6-5 Color to fill background with (if same as color,
|
10 | no background)
|
11 | @param size_x Font magnification level in X-axis, 1 is 'original' size
|
12 | @param size_y Font magnification level in Y-axis, 1 is 'original' size
|
13 | */
|
14 | /**************************************************************************/
|
15 | void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, |
16 | uint16_t color, uint16_t bg, uint8_t size_x, |
17 | uint8_t size_y) { |
18 | |
19 | if (!gfxFont) { // 'Classic' built-in font |
20 | |
21 | if ((x >= _width) || // Clip right |
22 | (y >= _height) || // Clip bottom |
23 | ((x + 6 * size_x - 1) < 0) || // Clip left |
24 | ((y + 8 * size_y - 1) < 0)) // Clip top |
25 | return; |
26 | |
27 | if (!_cp437 && (c >= 176)) |
28 | c++; // Handle 'classic' charset behavior |
29 | |
30 | startWrite(); |
31 | for (int8_t i = 0; i < 5; i++) { // Char bitmap = 5 columns |
32 | uint8_t line = pgm_read_byte(&font[c * 5 + i]); |
33 | for (int8_t j = 0; j < 8; j++, line >>= 1) { |
34 | if (line & 1) { |
35 | if (size_x == 1 && size_y == 1) |
36 | writePixel(x + i, y + j, color); |
37 | else
|
38 | writeFillRect(x + i * size_x, y + j * size_y, size_x, size_y, |
39 | color); |
40 | } else if (bg != color) { |
41 | if (size_x == 1 && size_y == 1) |
42 | writePixel(x + i, y + j, bg); |
43 | else
|
44 | writeFillRect(x + i * size_x, y + j * size_y, size_x, size_y, bg); |
45 | }
|
46 | }
|
47 | }
|
48 | if (bg != color) { // If opaque, draw vertical line for last column |
49 | if (size_x == 1 && size_y == 1) |
50 | writeFastVLine(x + 5, y, 8, bg); |
51 | else
|
52 | writeFillRect(x + 5 * size_x, y, size_x, 8 * size_y, bg); |
53 | }
|
54 | endWrite(); |
das PROGMEM ist für die Kompatibilität mit AVR und dem getrennten Adressraum für RAM und Flash, kann man per define als nichts wegmachen. Die Fonts können Ligaturen und die Zeichen sind nicht alle gleich breit, damit die Beschreibung eines Zeichens aufwändiger. Das macht eben das Löschen eines Zeichens schwieriger, man kann keine Dummyfläche löschen bzw. muss Wissen wie groß das Zeichen war das da Stand. Und durch die Ligaturen (übergreifende Zeichen) kann man das vorhergehende Zeichen teilweise kaputtschreiben. Deshalb ist einfacher in einen Buffer zu rendern und den dann am Block an das Display zu schicken. Was bei den OLED mit SSD1306 und seinen max. 1 kB ja nicht weh tut. Adafruit unterstützt das mit den 'Canvas', also eine Leinwand auf die erst gemalt wird und diese wird dann übertragen. Das kann auch ein Teilausschnitt wie der gelbe Bereich im Display sein. ein paar defines die man häufig braucht um AVR/Arduino portabel zu machen:
1 | #ifndef PROGMEM
|
2 | #define PROGMEM
|
3 | #endif
|
4 | #ifndef boolean
|
5 | #define boolean bool
|
6 | #endif
|
7 | #ifndef bitRead
|
8 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
9 | #endif
|
10 | #ifndef bitSet
|
11 | #define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
12 | #endif
|
13 | #ifndef bitClear
|
14 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
15 | #endif
|
16 | #ifndef bitWrite
|
17 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
18 | #endif
|
19 | #ifndef pgm_read_byte
|
20 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
21 | #endif
|
und startWrite() / endWrite() ist eine Optimierung die man hier auch weglassen kann wenn man in einen Buffer rendert.
Christian J. schrieb: > if (!gfxFont) { // 'Classic' built-in font das ist allerdings noch die einfache Zeichenroutine für die groben Fonts, für die Free Type ist es noch etwas aufwändiger.
Christian J. schrieb:
1 | void Adafruit_GFX::drawChar |
2 | (int16_t x, |
3 | int16_t y, |
4 | unsigned char c, |
5 | uint16_t color, |
6 | uint16_t bg, |
7 | uint8_t size_x, |
8 | uint8_t size_y) |
Grr..igitt. Viel zu viele Parameter für ein Grafik-Charout. Eigentlich wären hier nur die ersten 3 Parameter erforderlich, der Rest sollte zum Teil im Font stecken (size_x und size_y) und zum anderen Teil in einem Grafik-Device-Kontext (Textcolor und Background-Color). W.S.
W.S. schrieb: > Grr..igitt. Viel zu viele Parameter für ein Grafik-Charout. tja, wenn man Quelltext nicht lesen kann und sogar die Kommentare ignoriert. Gründe warum ich niemals Quelltext von dir benutzen werde, andere haben es einfach wesentlich besser drauf. PS: in der einfachen Form reicht sogar ein 'uint8_t c' als Argument für write() und damit eine Streamausgabe direkt auf das Display arbeiten. PSS: backcolor und forecolor sind auch etwas tricky: wenn gleich, dann ist der Hintergrund transparent (wird nicht gezeichnet). Das sieht man nicht sofort weil das default ist und die Zeichen dann erstmal übereinander liegen. Wenn die Zeichen den Hintergrund löschen sollen, dann muss den entsprechend setzen.
Christian J. schrieb: > Ich suche einen passenden Font für die Displays, die oben gelb und unten > blau sind. Da ich einen 32 Bitter nutze sind die bestehenden als 16 Bit > Werte hinterlegt, 8 Bit nützt mir also leider wenig, das wäre zu viel > Tipparbeit Warum kaufst Du Dir so etwas?
Also, wenn es so eines ist, dann sind die ersten 16 (von 64) Zeilen gelb: https://www.buydisplay.com/media/catalog/product/cache/8d4d2075b1a30681853bef5bdc41b164/y/e/yellow-blue_0.96_inch_oled_display_breakout_board_library_for_arduino_1.jpg Hätte mich auch gewundert, wenn es irgendeine krumme (!=2^n) Zahl gewesen wäre.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.