Da ich faul bin, suche ich zunächst nach fertigen Lösungen.
Oli als Europäer ist diesbezüglich sensibler als der durchschnittliche Nordamerikaner, behaupte ich einfach mal. Seine Bibliothek U8x8 habe ich mit Max7219 leider nicht zum Laufen gebracht. U8g2 geht dafür mit einer großen Fontauswahl, leider steht die Schrift auf dem Kopf:
#include <Arduino.h>
#include <U8g2lib.h> // Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
#include <SPI.h>
U8G2_MAX7219_32X8_F_4W_HW_SPI u8g2(U8G2_R0, /* clock= 13, data= 11, cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE);
void setup(void) {
u8g2.begin();
u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() function
u8g2.setFont(u8g2_font_pxplusibmcgathin_8f);
}
void loop(void) {
u8g2.clearBuffer();
u8g2.setCursor(0, 7);
u8g2.print("äöüßÄÖÜ");
u8g2.sendBuffer();
delay(1000);
}
Außerdem hat Oli noch U8g2_for_Adafruit_GFX im Angebot, das zusammen mit Max72xxPanel richtigherum die Fonts von Oli ermöglicht:
#include <SPI.h>
#include <U8g2_for_Adafruit_GFX.h>
#include <Max72xxPanel.h>
Max72xxPanel matrix = Max72xxPanel(10, 4, 1); // CS, Elemente, Zeilen
U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;
void setup()
{
for (uint8_t i = 0; i < 4 ; i++)
{
matrix.setRotation(i, 1); // The Display is Position
}
matrix.setIntensity(2); // Helligkeit Matrix 0 und 15 0=schwach, 15=sehr hell
u8g2_for_adafruit_gfx.begin(matrix); // connect u8g2 procedures to Adafruit GFX
u8g2_for_adafruit_gfx.setFont(u8g2_font_pxplusibmcgathin_8f);
}
void loop()
{
matrix.fillScreen(LOW);
u8g2_for_adafruit_gfx.setCursor(0, 7); // start writing at this position
u8g2_for_adafruit_gfx.print("ÄäöüX"); // UTF-8 string
matrix.write();
delay(2000);
}
Man muß bedenken, daß UTF-8-Zeichen aus bis zu vier Byte bestehen können. Daher funktioniert kein 1 zu 1 Tausch. Aber @noiasca hat eine Steilvorlage geliefert, um in Grundbuchstaben zu tauschen. Da der Font von Max72xxPanel durchaus Umlaute im Angebot hat, kann man anstelle der Grundbuchstaben auch Umlaute anzeigen.
Fummelt man schon an der Tabelle, kann man auch den Rest aus der Bibliothek in das eigene Programm kopieren:
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
Max72xxPanel matrix = Max72xxPanel(10, 4, 1); // CS (DIN 11, CLK 13), Anzahl Displays horizontal, vertikal
const uint8_t charNum = 26; // max Anzahl Zeichen (derzeit Fahrername (25+1))
char f[charNum] = {0}; // Fahrername
char n[charNum] = {0}; // a new variable for the converted plain ASCII name
uint32_t special = 0; // temp storage for UTF-8 bytes
// -- Anfang --------------
// Quelle: https://werner.rothschopf.net/202009_arduino_liquid_crystal_intro.htm
// utility/NoiascaUTF8.h
// the structure of the UTF8 -> single character (mapping)
struct Mapping {
uint16_t utf8; // the 2 least significant bytes of the 4 byte UTF-8 character
uint8_t c; // the final 1 byte charactter to print
};
constexpr byte NOPRINT = 0;
constexpr byte PRINT = 1;
// West Germanic - gmw
// de en nl (sco fy)
const Mapping lang_max72xxpanel[] PROGMEM = {
{0xc386, 'A'}, // Æ LATIN CAPITAL LETTER AE
{0xc384, 0x8E}, // Ä LATIN CAPITAL LETTER A WITH DIAERESIS
{0xc38b, 'E'}, // Ë LATIN CAPITAL LETTER E WITH DIAERESIS
{0xc38f, 'I'}, // Ï LATIN CAPITAL LETTER I WITH DIAERESIS
{0xc396, 0x99}, // Ö LATIN CAPITAL LETTER O WITH DIAERESIS
{0xc39c, 0x9A}, // Ü LATIN CAPITAL LETTER U WITH DIAERESIS
{0xC39F, 0xE0}, // ß
{0xc3a4, 0x84}, // ä LATIN SMALL LETTER A WITH DIAERESIS
{0xc3a6, 'a'}, // æ LATIN SMALL LETTER AE
{0xc3af, 'i'}, // ï LATIN SMALL LETTER I WITH DIAERESIS
{0xc3ab, 'e'}, // ë LATIN SMALL LETTER E WITH DIAERESIS
{0xc3b6, 0x94}, // ö LATIN SMALL LETTER O WITH DIAERESIS
{0xc3bc, 0x81}, // ü LATIN SMALL LETTER U WITH DIAERESIS
{0xc4b2, 'I'}, // IJ LATIN CAPITAL LIGATURE IJ - somehow - J should be added for Dutch
{0xc4b3, 'i'} // ij LATIN SMALL LIGATURE IJ - somehow - J should be added for Dutch
};
uint8_t convert_generic(uint32_t &special, uint8_t &value, const Mapping *language, size_t lang_len) {
//Serial.print("D521 convert_SPLC780D1_003A 0x"); Serial.println(value, HEX);
uint8_t isWriteable = NOPRINT;
if ((value & 0b11000000) == 0b11000000) // start byte
{
special = value;
}
else if ((value & 0b11000000) == 0b10000000) // sequence byte (Folgebyte)
{
special = special << 8; // MISSING should get improvement to check on 3rd sequence byte
special += value;
if (special > 0xC000 && special < 0xE000) // if 2 byte character
{
isWriteable = PRINT;
}
else if (special > 0xE00000 && special < 0xF0000000) // 3 byte character: 0b11100000 00000000 00000000 im dritten byte von hinten
{
isWriteable = PRINT;
}
else if (special > 0xF0000000) // 4 byte character: 0b11110000 ganz vorne
{
isWriteable = PRINT;
}
}
else // not a sequence byte - reset special
{
special = 0;
}
if (special == 0) // Single Character
{
// no difference mapping to ASCII needed
isWriteable = PRINT; // any other character just send to display
}
else if (isWriteable) // was UTF-8 2 bytes or more
{
// Step 1: general ROM Mapping
// Lookup with in UTF8->ROM Mapping overrides the character to be send to the LCD
uint16_t index = 0;
for (size_t i = 0; i < lang_len; i++)
{
index = pgm_read_dword_near(&language[i].utf8);
if (index == (special & 0xFFFF))
{
memcpy_P(&value, &language[i].c, 1);
break;
}
}
// Step 2: Ä Ö Ü overruleUml
// not in this converter
// Step 3: Send
// any other character just send to display
special = 0;
// Step 4: only in Ae Variant to add the e
}
return isWriteable;
}
// -- Ende ---------------
// convert UTF-8 characters to ASCII
void convert(char * in, char * out)
{
size_t j = 0;
for (size_t i = 0; i < charNum; i++)
{
uint8_t value = in[i];
// überschreibe gegebenenfalls value mit dem gemappten ASCII character
uint8_t printable = convert_generic(special, value, lang_max72xxpanel, sizeof(lang_max72xxpanel) / sizeof(lang_max72xxpanel[0])); // west germanic languages
if (printable)
{
out[j] = value;
j++;
}
if (value == 0) break;
}
}
void setup() {
delay(1000);
for (uint8_t i = 0; i < 4 ; i++) matrix.setRotation(i, 1);
matrix.setIntensity(2); // Helligkeit Matrix 0 und 15 0=schwach, 15=sehr hell
strcpy(f, "äöüßÄ"); // einlesen
convert (f, n);
matrix.fillScreen(LOW);
matrix.setCursor(0, 0);
matrix.print(n);
matrix.write();
delay(10000);
}
void loop() {
/* Zur Anzeige weiterer Zeichen
static uint8_t z = 0x80;
if(z<255){
matrix.fillScreen(LOW);
matrix.setCursor(0, 0);
matrix.print(z, HEX);
matrix.print(' ');
matrix.print(char(z));
matrix.write();
z++;
}
*/
delay(1000);
}
Mir gefällt das Ergebnis, Dir auch?
