Soms is het nodig om enkele gegevens in te voeren. Deze blogpost moet laten zien hoe het touchscreen van de ArduiTouch en een ESP32 kan een eenvoudig invoertoetsenbord implementeren.
Het toetsenbord heeft 41 toetsen en drie niveaus (kleine letters, hoofdletters, cijfers en tekens). De invoerregel bevindt zich boven de toetsen. Naast de spatiebalk bevat de onderste rij een toets om naar cijfers en tekens te schakelen, een toets om te schakelen tussen hoofdletters en kleine letters, een toets om te wissen en de enter-toets om de invoer te beëindigen. Deze toetsenbordfunctie maakt ook deel uit van een bibliotheek waarmee u een comfortabele grafische interface met het TFT-touchscreen kunt maken.
Code:
# opnemen <SPI.h> # opnemen "Adafruit_GFX.h" // Grafische bibliotheek # opnemen "Adafruit_ILI9341.h" // stuurprogramma weergeven # opnemen <XPT2046_Touchscreen.h> // Touchscreen-stuurprogramma # opnemen "KbdBold12pt7b.h" // Uitgebreid script met Duitse umlauts en // speciale knoppictogrammen voor bediening #define _debug 1 // Schakelt berichten op de seriële monitor in of uit // Pinnen voor het display en het touchscreen #define TFT_CS 5 #define TFT_DC 4 #define TFT_MOSI 23 #define TFT_CLK 18 #define TFT_RST 22 #define TFT_MISO 19 #define TFT_LED 15 #define HAVE_TOUCHPAD #define TOUCH_CS 14 #define TOUCH_IRQ 2 // Parameters voor het touchscreen #define MINPRESSUUR 10 #define MAXPRESSUUR 2000 #define TS_MINX 370 #define TS_MINY 470 #define TS_MAXX 3700 #define TS_MAXY 3600 // kleurdefinitie #define ILI9341_LIGHT_GRAY 0B1101011010011010 // Instanties voor weergave en aanraakscherm Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); XPT2046_Touchscreen aanraken(TOUCH_CS, TOUCH_IRQ); /* * Toetsenbordindeling * Niveau 0 = kleine letters * Niveau 1 = hoofdletters * Niveau 2 = cijfers en tekens * * De speciale tekenset bevat de volgende extra tekens: * 0x18 24 pijl naar rechts * 0x19 25 pijl naar links * 0x1A 26 pijl-omhoog * 0x1B 27 Opgevulde pijl * 0x1C 28 Enter-toets * 0x1D 29 Schakelaarletters * 0x1E 30 schakelcijfers * 0x1F 31 sleutel verwijderen * en bovenaan * 0x7F 127 Ä * 0x80 128 Ö * 0x81 129 nachten * 0x82 130 ä * 0x83 131 ö * 0x84 132 g * 0x85 133 ß * 0x86 134 ° */ const char sleutels[3][42] = { {'a','b','c','d','e','f', 'g','h','ik','j','k',ik, 'm','n','o','p','q','r', 's','t','u','v','w','x', 'y','z',130,131,132,133, ',','.','-','_','/','@', 30,26,' ',' ',31,28}, {'A','B','C','D','E','F', 'G','H','Ik','J','K','L', 'M','N','O','P','Q','R', 'S','T','U','V','W','X', 'Y','Z',127,128,129,133, ',','.','-','_','/','@', 30,27,' ',' ',31,28}, {'0','1','2','3','4','5', '6','7','8','9',';',':', '!','?','#',34,39,92, '(','[','{','}',']',')', '+','*','=','$','%','@', '|',134,'^','&','<','>', 29,26,' ',' ',31,28} }; // Globale variabelen uint8_t niveau = 0; // huidig niveau dwaas geklikt = fout; // aanraking gedetecteerd dwaas kb; // vlag als toetsenbord actief is String tekst = ""; // invoertekst TS_Point p; // Puntstructuur voor touchscreen nietig instellen() { #ifdef _debug Serie.beginnen(115200); #endif pinMode(TFT_LED, UITGANG); digitalWrite(TFT_LED, HOOG); // Displayverlichting aan // Start het display en touchscreen tft.beginnen(); aanraken.beginnen(); #ifdef _debug Serie.afdrukken("tftx ="); Serie.afdrukken(tft.breedte()); Serie.afdrukken("tfty ="); Serie.println(tft.hoogte()); #endif // output toetsenbord teken_scherm(); kb = waar; } nietig lus() { uint8_t r,c,index; char ch; // Query-touchscreen keert terug als het scherm wordt aangeraakt // de globale variabele p bevat de positie als (kb && Touch_Event()) { als (!geklikt) { // we hebben nog geen aanraking herkend // Dus bepalen we de aangeraakte toets als (p.x>40) { // alleen onder de invoerregel // we bepalen de rij en kolom van de sleutel r = (p.x-40) / 40; c = (p.y) / 40; // Bereken de index in de toetsenbordmatrix index = r*6+c; // Waarde van de aangeraakte toets ch = sleutels[niveau][index]; als (ch > 31) { // groter dan 31 = geldig karakter // we voegen het toe aan de invoertekst tekst = tekst + ch; // en voer de nieuwe tekst uit teken_tekst(); } anders { // een bedieningstoets werd aangeraakt schakelaar (ch) { geval 26: niveau = 1; // In hoofdletters teken_scherm(); pauze; geval 27: niveau = 0; // Van hoofdletters naar kleine letters teken_scherm(); pauze; geval 29: niveau = 0; // Van zigzers tot kleine letters teken_scherm(); pauze; geval 30: niveau = 2; // Op nummers teken_scherm(); pauze; geval 31: tekst.verwijderen(tekst.lengte()-1); // laatste teken verwijderen teken_tekst(); pauze; geval 28: teken_resultaat(tekst); // invoer voltooien pauze; } } } geklikt = waar; // geklikt wordt ingesteld op true met een lange aanraking // de knop wordt slechts eenmaal geactiveerd } } anders { geklikt = fout; // De aanraking is beëindigd, we zijn klaar voor de volgende toets } } // Het touchscreen wordt opgevraagd. De globale variabele p ontvangt de positie // de retourwaarde is waar wanneer het touchscreen wordt aangeraakt. // Aandacht vanwege de schermoriëntatie, zijn x en y verwisseld! dwaas Touch_Event() { p = aanraken.getPoint(); vertraging(1); p.x = kaart(p.x, TS_MINX, TS_MAXX, 0, 320); p.y = kaart(p.y, TS_MINY, TS_MAXY, 240, 0); als (p.bijv. > MINPRESSUUR) terug waar; terug fout; } // Wis het invoerscherm en geef de invoertekst weer nietig teken_resultaat( String res) { kb = fout; #ifdef _debug // Uitvoer van de invoertekst naar de seriële monitor // Umlauts moeten worden geconverteerd naar UTF8 Serie.println(vanKeyboard(res)); #endif tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLUE); tft.setCursor(3,160); tft.afdrukken(res); } // voer invoertekst opnieuw in nietig teken_tekst() { uint16_t w,h; int16_t x1,y1; // we moeten eerst de oude tekst op het display verwijderen tft.getTextBounds(tekst, 0, 0, &x1, &y1, &w, &h); tft.fillRect(1,1,238,38,ILI9341_LIGHT_GRAY); tft.setCursor(3,28); // voer nieuwe tekst uit tft.afdrukken(tekst); // voer blauwe cursor uit als (tekst.lengte() > 0) { tft.fillRect(7+w,10,3,20,ILI9341_BLUE); } anders { tft.fillRect(7,10,3,20,ILI9341_BLUE); } } // Toon toetsenbord nietig teken_scherm() { uint8_t ix = 0; uint16_t w,h; int16_t x1,y1; char tmp[2]; // Display wissen en invoertekst weergeven tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_BLACK, ILI9341_LIGHT_GRAY); tft.setFont(&KbdBold12pt7b); teken_tekst(); voor (uint8_t ik = 1; ik<8; ik++) { voor (uint8_t j = 0; j<6; j++) { als ((ik==7) && ((j==2) || (j == 3))) { als (j==2) { // Speciaal geval voor de spatiebalk tft.fillRoundRect(j*40+1,ik*40+1,78,38,9,ILI9341_LIGHT_GRAY); tft.drawRoundRect(j*40+1,ik*40+1,78,38,9,ILI9341_BLUE); tft.drawRoundRect(j*40+2,ik*40+2,76,36,7,ILI9341_BLUE); } } anders { // Toon normale knoppen tft.fillRoundRect(j*40+1,ik*40+1,38,38,9,ILI9341_LIGHT_GRAY); tft.drawRoundRect(j*40+1,ik*40+1,38,38,9,ILI9341_BLUE); tft.drawRoundRect(j*40+2,ik*40+2,36,36,7,ILI9341_BLUE); // Toon sleutelwaarde gecentreerd ix = (ik-1)*6+j; als (ix < 42) { tmp[0] = sleutels[niveau][ix]; tmp[1] = 0; tft.getTextBounds(tmp, 0, 0, &x1, &y1, &w, &h); tft.setCursor(j*40+20-w/2,ik*40+20+h/2); tft.afdrukken(tmp); } } } } } // Converteer een UTF8-string naar 8-bit toetsenbordcode String Toetsenbord(String tekst) { String res = ""; uint8_t ik = 0; char c; terwijl (ik<tekst.lengte()) { c=tekst[ik]; als (c==195) { // UTF8 tekens umlauts ik++; schakelaar (tekst[ik]) { geval 164: c=130; pauze; geval 182: c=130; pauze; geval 188: c=130; pauze; geval 159: c=133; pauze; geval 132: c=127; pauze; geval 150: c=128; pauze; geval 156: c=129; pauze; standaard: c=0; } } anders als (c == 194) { // UTF8 teken graadsymbool ik++; als (tekst[ik] == 176) c=134; anders c=0; } anders als (c > 128) { // normale tekens blijven ongewijzigd c=0; } als (c>0) res.concat(c); ik++; } terug res; } // Converteer invoertekst van 8-bits toetsenbordcode naar UTF8 String vanKeyboard(String tekst) { String res = ""; char c; voor (uint8_t ik=0; ik<tekst.lengte(); ik++) { c = tekst[ik]; als (c > 126){ // we hebben speciale karakters als (c==134) { res.concat("°"); } anders { schakelaar (c) { geval 130: res.concat("ä"); pauze; geval 131: res.concat("ö"); pauze; geval 132: res.concat("ü"); pauze; geval 133: res.concat("ß"); pauze; geval 127: res.concat("Ä"); pauze; geval 128: res.concat("Ö"); pauze; geval 129: res.concat("Ü"); pauze; } } } anders { // normaal karakter res.concat(c); } } terug res; }
De code wordt gedetailleerd besproken. Het moet de basis vormen voor je eigen experimenten.
En hier is het lettertype:
Sla het eenvoudig op als een KbdBold12pt7b.h-bestand in dezelfde map als de schets.
const uint8_t KbdBold12pt7bBitmaps[] PROGMEM = { 0x10, 0x03, 0x00, 0x70, 0x0F, 0xFF, 0xFF, 0xF7, 0x00, 0x30, 0x01, 0x00, 0x00, 0x80, 0x0C, 0x00, 0xEF, 0xFF, 0xFF, 0xF0, 0x0E, 0x00, 0xC0, 0x08, 0x02, 0x00, 0x38, 0x03, 0x60, 0x31, 0x83, 0x06, 0x30, 0x1B, 0x00, 0x7F, 0x1F, 0xF8, 0xF8, 0xC6, 0x06, 0x30, 0x31, 0x81, 0x8C, 0x0C, 0x60, 0x63, 0x03, 0xF8, 0x1F, 0xC0, 0x00, 0x02, 0x00, 0x38, 0x03, 0xE0, 0x3F, 0x83, 0xFE, 0x3F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFE, 0x07, 0xF0, 0x3F, 0x81, 0xFC, 0x0F, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0x00, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x30, 0x00, 0x62, 0x00, 0xCC, 0x01, 0xB8, 0x03, 0xFF, 0xFF, 0xFF, 0xFD, 0xC0, 0x01, 0x80, 0x01, 0x00, 0x00, 0x10, 0xE0, 0x87, 0x1E, 0x38, 0xE3, 0x6D, 0x94, 0x6D, 0xB6, 0xCD, 0xB6, 0xD9, 0xB6, 0x1B, 0x36, 0xC6, 0x37, 0x98, 0xC6, 0xE3, 0x18, 0xDC, 0x63, 0xFB, 0xCC, 0x7F, 0x6D, 0x8C, 0x6D, 0xB1, 0x8D, 0xB6, 0xF1, 0xB6, 0xDE, 0x36, 0xDB, 0xC6, 0xF1, 0xD8, 0xDC, 0x10, 0x00, 0x30, 0x22, 0x3C, 0x33, 0xB3, 0x3B, 0x79, 0xBD, 0xBC, 0xDE, 0xD8, 0x63, 0x0C, 0x31, 0x86, 0x18, 0xC3, 0x18, 0x63, 0x18, 0x31, 0x8C, 0x19, 0x86, 0x0C, 0xC3, 0x06, 0xC1, 0x83, 0x60, 0x01, 0xB0, 0x00, 0xD8, 0x30, 0x6F, 0x98, 0x37, 0xC0, 0x07, 0xFF, 0xC3, 0xFF, 0xF1, 0x80, 0x0C, 0xC6, 0x33, 0x60, 0xD8, 0xF0, 0x1C, 0x3C, 0x07, 0x0D, 0x83, 0x63, 0x31, 0x8C, 0xC6, 0x00, 0x30, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x76, 0x66, 0x60, 0xFF, 0xF0, 0xF3, 0xFC, 0xFF, 0x3F, 0xCF, 0x61, 0x98, 0x60, 0x0E, 0x70, 0x73, 0x83, 0x18, 0xFF, 0xF7, 0xFF, 0xBF, 0xFC, 0x73, 0x83, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFD, 0xFF, 0xE3, 0x18, 0x39, 0xC1, 0xCE, 0x0E, 0x70, 0x02, 0x00, 0x7E, 0x0F, 0xF8, 0x7F, 0xE7, 0xAF, 0xB9, 0x3D, 0xC8, 0x0F, 0x40, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x05, 0xFF, 0x27, 0xF9, 0x3F, 0xEB, 0xEF, 0xFE, 0x3F, 0xE0, 0x7C, 0x00, 0x80, 0x04, 0x00, 0x3C, 0x06, 0x0F, 0xC1, 0x81, 0xFC, 0x30, 0x73, 0x8C, 0x0C, 0x31, 0x81, 0xCE, 0x60, 0x1F, 0xCC, 0x03, 0xF3, 0x00, 0x3C, 0x67, 0x80, 0x19, 0xF8, 0x02, 0x7F, 0x80, 0xCE, 0x70, 0x11, 0x86, 0x06, 0x39, 0xC1, 0x87, 0xF8, 0x30, 0x7E, 0x0C, 0x07, 0x80, 0x07, 0x80, 0x1F, 0xC0, 0x3F, 0xE0, 0x3C, 0xE0, 0x3C, 0xE0, 0x3E, 0xE0, 0x0F, 0xC0, 0x07, 0x00, 0x3F, 0x8C, 0x7F, 0xCC, 0xF1, 0xFC, 0xF0, 0xF8, 0xF0, 0x78, 0xF8, 0xF8, 0x7F, 0xFC, 0x3F, 0xDE, 0x1F, 0x8E, 0xFF, 0xFF, 0x66, 0x0C, 0x73, 0x8E, 0x71, 0xC7, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x1C, 0x71, 0xC3, 0x8E, 0x18, 0x70, 0xC3, 0x87, 0x1C, 0x38, 0xE3, 0x87, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xCE, 0x38, 0xE7, 0x1C, 0x63, 0x80, 0x10, 0x23, 0x5F, 0xF3, 0x87, 0x1B, 0x14, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x00, 0xFF, 0xF3, 0x36, 0xC0, 0xFF, 0xFF, 0xC0, 0xFF, 0xF0, 0x0C, 0x30, 0x86, 0x18, 0x61, 0x0C, 0x30, 0xC2, 0x18, 0x61, 0x84, 0x30, 0xC0, 0x1F, 0x83, 0xFC, 0x7F, 0xE7, 0x9E, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xF7, 0x9E, 0x7F, 0xE3, 0xFC, 0x0F, 0x00, 0x06, 0x1C, 0x7F, 0xFF, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x1F, 0x83, 0xFC, 0x7F, 0xEF, 0x9F, 0xF0, 0xFF, 0x0F, 0x00, 0xF0, 0x0F, 0x01, 0xE0, 0x3C, 0x0F, 0x81, 0xE0, 0x3C, 0x03, 0x80, 0x7F, 0xF7, 0xFF, 0x7F, 0xF0, 0x1F, 0x07, 0xFC, 0xFF, 0xEF, 0x1E, 0xF1, 0xE0, 0x1E, 0x03, 0xC0, 0x78, 0x07, 0xC0, 0x1E, 0x00, 0xF0, 0x0F, 0xF0, 0xFF, 0x1F, 0x7F, 0xE7, 0xFC, 0x1F, 0x80, 0x03, 0xC0, 0xF8, 0x1F, 0x07, 0xE1, 0xBC, 0x27, 0x8C, 0xF3, 0x1E, 0x63, 0xD8, 0x7B, 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x3F, 0xE7, 0xFE, 0x7F, 0xE7, 0x00, 0x60, 0x06, 0xF8, 0x7F, 0xCF, 0xFE, 0xF1, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xFE, 0x1E, 0xFF, 0xE7, 0xFC, 0x3F, 0x00, 0x0F, 0x83, 0xFC, 0x7F, 0xE7, 0x9F, 0xF0, 0x0F, 0x78, 0xFF, 0xCF, 0xFE, 0xF9, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xF7, 0x9F, 0x7F, 0xE3, 0xFC, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xE0, 0x1C, 0x07, 0x01, 0xE0, 0x38, 0x0F, 0x01, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x38, 0x0F, 0x01, 0xE0, 0x3C, 0x00, 0x0F, 0x03, 0xFC, 0x7F, 0xC7, 0x9E, 0x70, 0xE7, 0x0E, 0x39, 0xC1, 0xF8, 0x3F, 0xC7, 0x9E, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x9F, 0x7F, 0xE3, 0xFC, 0x1F, 0x80, 0x1F, 0x03, 0xFC, 0x7F, 0xEF, 0x9E, 0xF0, 0xEF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF9, 0xF7, 0xFF, 0x3F, 0xF1, 0xEF, 0x00, 0xEF, 0x1E, 0x7F, 0xE7, 0xFC, 0x1F, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0x11, 0x6C, 0x00, 0x10, 0x07, 0x03, 0xF1, 0xFC, 0x7E, 0x0F, 0x80, 0xE0, 0x0F, 0xC0, 0x3F, 0x80, 0x7F, 0x00, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0E, 0x00, 0xFC, 0x07, 0xF0, 0x0F, 0xE0, 0x1F, 0x00, 0xF0, 0x7F, 0x1F, 0x8F, 0xE0, 0xF0, 0x08, 0x00, 0x1F, 0x07, 0xFC, 0x7F, 0xEF, 0x9F, 0xF0, 0xFF, 0x0F, 0x00, 0xF0, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x0E, 0x00, 0xE0, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x00, 0xFE, 0x00, 0x1F, 0xFC, 0x03, 0xC0, 0xF0, 0x38, 0x01, 0xC3, 0x80, 0x07, 0x18, 0x3D, 0x99, 0x87, 0xEC, 0x6C, 0x71, 0xC3, 0xC3, 0x06, 0x1E, 0x18, 0x30, 0xF1, 0x81, 0x87, 0x8C, 0x18, 0x7C, 0x60, 0xC3, 0x63, 0x8E, 0x3B, 0x8F, 0xDF, 0x8C, 0x3C, 0xF0, 0x70, 0x00, 0x01, 0xC0, 0x00, 0x07, 0x80, 0x80, 0x1F, 0xFE, 0x00, 0x1F, 0xC0, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0x70, 0x0F, 0x78, 0x0E, 0x78, 0x0E, 0x38, 0x1E, 0x3C, 0x1C, 0x3C, 0x3F, 0xFC, 0x3F, 0xFE, 0x3F, 0xFE, 0x78, 0x0E, 0x78, 0x0F, 0x70, 0x0F, 0xF0, 0x07, 0xFF, 0xC3, 0xFF, 0xCF, 0xFF, 0x3C, 0x3E, 0xF0, 0x7B, 0xC1, 0xEF, 0x0F, 0xBF, 0xFC, 0xFF, 0xE3, 0xFF, 0xCF, 0x07, 0xBC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x07, 0xFF, 0xFE, 0xFF, 0xFB, 0xFF, 0x80, 0x07, 0xE0, 0x1F, 0xF8, 0x3F, 0xFC, 0x7C, 0x3E, 0x78, 0x1F, 0xF8, 0x0F, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF8, 0x0F, 0x78, 0x1F, 0x7C, 0x3E, 0x3F, 0xFE, 0x1F, 0xFC, 0x07, 0xF0, 0xFF, 0xE1, 0xFF, 0xE3, 0xFF, 0xE7, 0x83, 0xEF, 0x03, 0xDE, 0x07, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x03, 0xFE, 0x07, 0xBC, 0x1F, 0x7F, 0xFC, 0xFF, 0xF1, 0xFF, 0x80, 0xFF, 0xF7, 0xFF, 0xBF, 0xFD, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1F, 0xFC, 0xFF, 0xE7, 0xFF, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0xFE, 0xFF, 0xEF, 0xFE, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0x03, 0xF0, 0x0F, 0xFC, 0x3F, 0xFE, 0x3E, 0x1F, 0x78, 0x07, 0x78, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x7F, 0xF0, 0x7F, 0xF0, 0x7F, 0xF0, 0x07, 0x78, 0x07, 0x7C, 0x0F, 0x3E, 0x1F, 0x3F, 0xFB, 0x0F, 0xFB, 0x03, 0xE3, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xF8, 0xFF, 0x1F, 0xE3, 0xFC, 0x7B, 0xFE, 0x7F, 0xC3, 0xE0, 0xF0, 0x3E, 0xF0, 0x3C, 0xF0, 0x78, 0xF0, 0xF0, 0xF1, 0xE0, 0xF3, 0xC0, 0xF7, 0x80, 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0x80, 0xFB, 0xC0, 0xF1, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x78, 0xF0, 0x3C, 0xF0, 0x3E, 0xF0, 0x1E, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0x1F, 0xFE, 0x0F, 0xFF, 0x0F, 0xFF, 0x87, 0xFF, 0xC3, 0xFF, 0xE1, 0xFF, 0xF9, 0xFF, 0xFC, 0xEF, 0xFE, 0x77, 0xFB, 0x3B, 0xFD, 0xDD, 0xFE, 0xFC, 0xFF, 0x7E, 0x7F, 0x9F, 0x3F, 0xCF, 0x9F, 0xE7, 0x8F, 0xF3, 0xC7, 0xF8, 0xE3, 0xC0, 0xF0, 0x1F, 0xF0, 0x3F, 0xF0, 0x7F, 0xE0, 0xFF, 0xE1, 0xFF, 0xC3, 0xFD, 0xC7, 0xFB, 0x8F, 0xF3, 0x9F, 0xE7, 0x3F, 0xC7, 0x7F, 0x8F, 0xFF, 0x0F, 0xFE, 0x1F, 0xFC, 0x1F, 0xF8, 0x1F, 0xF0, 0x3F, 0xE0, 0x3C, 0x03, 0xE0, 0x0F, 0xFC, 0x0F, 0xFF, 0x87, 0xC7, 0xC7, 0x80, 0xF3, 0xC0, 0x7B, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE, 0x00, 0xF7, 0x80, 0xF3, 0xC0, 0x78, 0xF0, 0xF8, 0x7F, 0xFC, 0x1F, 0xFC, 0x03, 0xF8, 0x00, 0xFF, 0xE3, 0xFF, 0xEF, 0xFF, 0xBC, 0x1F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x1F, 0xFF, 0xFB, 0xFF, 0xCF, 0xFE, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x00, 0x03, 0xE0, 0x0F, 0xFC, 0x0F, 0xFF, 0x87, 0xC7, 0xC7, 0x80, 0xF3, 0xC0, 0x7B, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE, 0x04, 0xF7, 0x87, 0xF3, 0xC3, 0xF8, 0xF0, 0xF8, 0x7F, 0xFC, 0x1F, 0xFF, 0x83, 0xF1, 0x80, 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xFC, 0xFF, 0xFC, 0xF0, 0x3E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x3C, 0xFF, 0xF8, 0xFF, 0xF0, 0xFF, 0xF8, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x1F, 0x0F, 0xC0, 0x7F, 0xE1, 0xFF, 0xE7, 0xC3, 0xEF, 0x03, 0xDE, 0x00, 0x3C, 0x00, 0x7F, 0x00, 0x7F, 0xF0, 0x3F, 0xF8, 0x0F, 0xF8, 0x01, 0xF0, 0x01, 0xFE, 0x03, 0xDE, 0x0F, 0xBF, 0xFE, 0x3F, 0xF8, 0x1F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xF7, 0x87, 0x9F, 0xFE, 0x3F, 0xF0, 0x3F, 0x00, 0x70, 0x0E, 0xF0, 0x3D, 0xE0, 0x79, 0xC0, 0xE3, 0x81, 0xC7, 0x87, 0x87, 0x0E, 0x0E, 0x1C, 0x1E, 0x78, 0x1C, 0xE0, 0x39, 0xC0, 0x73, 0x80, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80, 0x70, 0x38, 0x1C, 0xE0, 0xF0, 0x79, 0xE1, 0xF0, 0xF3, 0xC3, 0xE1, 0xE3, 0x87, 0xC3, 0x87, 0x0F, 0x87, 0x0E, 0x3B, 0x9E, 0x1E, 0x77, 0x38, 0x1C, 0xEE, 0x70, 0x39, 0xCC, 0xE0, 0x73, 0x99, 0xC0, 0x6E, 0x3F, 0x00, 0xFC, 0x7E, 0x01, 0xF8, 0xFC, 0x03, 0xF0, 0xF8, 0x03, 0xE1, 0xE0, 0x07, 0x83, 0xC0, 0x0F, 0x07, 0x80, 0xF0, 0x3C, 0xF0, 0xF9, 0xE1, 0xE1, 0xE7, 0x83, 0xCF, 0x03, 0xFC, 0x03, 0xF0, 0x07, 0xE0, 0x07, 0x80, 0x0F, 0x00, 0x3F, 0x00, 0xFF, 0x01, 0xFE, 0x07, 0x9E, 0x0F, 0x1E, 0x3C, 0x3C, 0xF8, 0x3D, 0xE0, 0x78, 0xF0, 0x1E, 0x78, 0x1E, 0x78, 0x3C, 0x3C, 0x3C, 0x3C, 0x78, 0x1E, 0x78, 0x0E, 0x70, 0x0F, 0xF0, 0x07, 0xE0, 0x07, 0xE0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF8, 0x07, 0x80, 0x78, 0x07, 0x80, 0x7C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xFF, 0xFF, 0xC0, 0xC1, 0x81, 0x03, 0x06, 0x04, 0x0C, 0x18, 0x10, 0x30, 0x60, 0x40, 0xC1, 0x81, 0x03, 0x06, 0xFF, 0xFF, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0xFF, 0xFF, 0xC0, 0x0F, 0x00, 0xF0, 0x0F, 0x01, 0xF8, 0x1B, 0x83, 0x9C, 0x39, 0xC3, 0x0C, 0x70, 0xE7, 0x0E, 0xE0, 0x70, 0xFF, 0xFF, 0xFF, 0xFC, 0xE6, 0x30, 0x1F, 0x83, 0xFF, 0x1F, 0xFD, 0xE1, 0xE0, 0x0F, 0x03, 0xF9, 0xFF, 0xDF, 0x1E, 0xF0, 0xF7, 0x8F, 0xBF, 0xFC, 0xFF, 0xE3, 0xCF, 0x80, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x7B, 0xC3, 0xFF, 0x9F, 0xFE, 0xF8, 0xF7, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xE3, 0xDF, 0xFE, 0xFF, 0xE7, 0xBE, 0x00, 0x0F, 0x83, 0xFE, 0x7F, 0xF7, 0x8F, 0xF0, 0x7F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x77, 0x8F, 0x7F, 0xF3, 0xFE, 0x0F, 0x80, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x8F, 0xBC, 0xFF, 0xEF, 0xFF, 0x78, 0xFF, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3D, 0xE3, 0xEF, 0xFF, 0x3F, 0xF8, 0xFB, 0xC0, 0x1F, 0x81, 0xFE, 0x1F, 0xF9, 0xF1, 0xCF, 0x07, 0x7F, 0xFB, 0xFF, 0xDE, 0x00, 0xF0, 0x03, 0xC3, 0x9F, 0xFC, 0x7F, 0xC0, 0xF8, 0x00, 0x3E, 0xFD, 0xFB, 0xC7, 0x9F, 0xBF, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF0, 0x1E, 0x79, 0xFB, 0xDF, 0xFE, 0xF1, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0xC7, 0xDF, 0xFE, 0x7F, 0xF1, 0xF7, 0x80, 0x3C, 0x01, 0xFF, 0x1E, 0x7F, 0xF0, 0xFE, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x7C, 0xFF, 0xEF, 0xFF, 0xF9, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xF3, 0xC0, 0x00, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0xFF, 0xFF, 0x80, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x0F, 0xF1, 0xEF, 0x3C, 0xF7, 0x8F, 0xF0, 0xFF, 0x0F, 0xF8, 0xFF, 0x8F, 0x3C, 0xF1, 0xCF, 0x1E, 0xF0, 0xEF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x8F, 0x9F, 0xFB, 0xFB, 0xFF, 0xFF, 0xFC, 0xF8, 0xFF, 0x1E, 0x1F, 0xE3, 0xC3, 0xFC, 0x78, 0x7F, 0x8F, 0x0F, 0xF1, 0xE1, 0xFE, 0x3C, 0x3F, 0xC7, 0x87, 0xF8, 0xF0, 0xFF, 0x1E, 0x1E, 0xF7, 0xCF, 0xFE, 0xFF, 0xFF, 0x9F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xF0, 0x0F, 0x81, 0xFF, 0x1F, 0xFC, 0xF1, 0xEF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7B, 0xC7, 0x9F, 0xFC, 0x7F, 0xC0, 0xF8, 0x00, 0xF7, 0xC7, 0xFF, 0x3F, 0xFD, 0xF1, 0xEF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0xC7, 0xBF, 0xFD, 0xFF, 0xCF, 0x78, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x00, 0x0F, 0x79, 0xFF, 0xDF, 0xFE, 0xF1, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7B, 0xC7, 0xDF, 0xFE, 0x7F, 0xF1, 0xF7, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0xF3, 0xF7, 0xFF, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x1F, 0x87, 0xFC, 0xFF, 0xEF, 0x0F, 0xF8, 0x0F, 0xF0, 0x7F, 0xE0, 0xFF, 0x01, 0xFF, 0x0F, 0xFF, 0xE7, 0xFE, 0x1F, 0x80, 0x79, 0xE7, 0xBF, 0xFD, 0xE7, 0x9E, 0x79, 0xE7, 0x9E, 0x7D, 0xF3, 0xC0, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x1F, 0xFF, 0xF7, 0xFF, 0x3E, 0xF0, 0xF0, 0x7B, 0x83, 0x9E, 0x1C, 0xF1, 0xE3, 0x8E, 0x1C, 0x70, 0x77, 0x83, 0xB8, 0x1D, 0xC0, 0x7E, 0x03, 0xE0, 0x1F, 0x00, 0x70, 0x00, 0xF0, 0xE1, 0xDC, 0x78, 0x77, 0x1F, 0x3D, 0xE7, 0xCF, 0x79, 0xB3, 0x8E, 0x6C, 0xE3, 0xBB, 0x38, 0xEE, 0xFC, 0x1F, 0x3F, 0x07, 0xC7, 0xC1, 0xF1, 0xF0, 0x7C, 0x78, 0x0E, 0x1E, 0x00, 0x78, 0xF3, 0xC7, 0x8F, 0x78, 0x3B, 0x81, 0xFC, 0x07, 0xC0, 0x1E, 0x01, 0xF0, 0x1F, 0xC0, 0xEF, 0x0F, 0x78, 0xF1, 0xE7, 0x87, 0x00, 0xF0, 0x7B, 0x83, 0x9E, 0x1C, 0x71, 0xE3, 0x8E, 0x1E, 0x70, 0x73, 0x83, 0xB8, 0x1F, 0xC0, 0x7E, 0x03, 0xE0, 0x0F, 0x00, 0x70, 0x03, 0x80, 0x3C, 0x07, 0xC0, 0x3E, 0x01, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x1C, 0xF3, 0xCE, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0xBC, 0xF0, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x3C, 0xF1, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE3, 0x8F, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x0F, 0x3D, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0xF3, 0xCE, 0x00, 0x78, 0x0F, 0xE0, 0xCF, 0x30, 0x7F, 0x01, 0xE0, 0x61, 0xC6, 0xF1, 0xCF, 0xF1, 0xCF, 0x63, 0xE6, 0x03, 0xE0, 0x07, 0x60, 0x0F, 0x78, 0x0E, 0x78, 0x0E, 0x38, 0x1E, 0x3C, 0x1C, 0x3C, 0x3F, 0xFC, 0x3F, 0xFE, 0x3F, 0xFE, 0x78, 0x0E, 0x78, 0x0F, 0x70, 0x0F, 0xF0, 0x07, 0x60, 0x03, 0x78, 0x03, 0xFC, 0x01, 0xEC, 0x7C, 0x61, 0xFF, 0x81, 0xFF, 0xF0, 0xF8, 0xF8, 0xF0, 0x1E, 0x78, 0x0F, 0x78, 0x03, 0xFC, 0x01, 0xFE, 0x00, 0xF7, 0x80, 0xF3, 0xC0, 0x78, 0xF0, 0xF8, 0x7F, 0xFC, 0x1F, 0xFC, 0x03, 0xF8, 0x00, 0x60, 0x1B, 0xC0, 0xFF, 0x03, 0xD8, 0x06, 0x00, 0x03, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xF7, 0x87, 0x9F, 0xFE, 0x3F, 0xF0, 0x3F, 0x00, 0x60, 0x67, 0x87, 0xBC, 0x3C, 0xC0, 0xC0, 0x00, 0x0F, 0xC1, 0xFF, 0x8F, 0xFE, 0xF0, 0xF0, 0x07, 0x81, 0xFC, 0xFF, 0xEF, 0x8F, 0x78, 0x7B, 0xC7, 0xDF, 0xFE, 0x7F, 0xF1, 0xE7, 0xC0, 0x60, 0x37, 0x83, 0xFC, 0x1E, 0xC0, 0x60, 0x00, 0x07, 0xC0, 0xFF, 0x8F, 0xFE, 0x78, 0xF7, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3D, 0xE3, 0xCF, 0xFE, 0x3F, 0xE0, 0x7C, 0x00, 0x60, 0x6F, 0x0F, 0xF0, 0xF6, 0x06, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF1, 0xFF, 0xFF, 0x7F, 0xF3, 0xEF, 0x3F, 0x07, 0xFC, 0xFF, 0xEF, 0x1E, 0xF1, 0xEF, 0x1E, 0xF3, 0xCF, 0x78, 0xF7, 0xCF, 0x1E, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x1F, 0xF7, 0xEF, 0x7C, 0xF7, 0x80, 0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 }; const GFXglyph KbdBold12pt7bGlyphs[] PROGMEM = { { 0, 12, 8, 13, 0, -11 } // '' ,{ 12, 12, 8, 13, 0, -11 } // '' ,{ 24, 13, 17, 14, 0, -16 } // '' ,{ 53, 13, 17, 14, 0, -16 } // '' ,{ 82, 15, 13, 16, 0, -14 } // '' ,{ 107, 19, 18, 20, 0, -17 } // '' ,{ 151, 17, 18, 18, 0, -17 } // '' ,{ 190, 18, 12, 19, 0, -14 } // '' ,{ 217, 0, 0, 7, 0, 1 } // ' ' ,{ 217, 4, 17, 8, 3, -16 } // '!' ,{ 226, 10, 6, 11, 1, -17 } // '"' ,{ 234, 13, 16, 13, 0, -15 } // '#' ,{ 260, 13, 20, 13, 0, -17 } // '$' ,{ 293, 19, 17, 21, 1, -16 } // '%' ,{ 334, 16, 17, 17, 1, -16 } // '&' ,{ 368, 4, 6, 6, 1, -17 } // ''' ,{ 371, 6, 22, 8, 1, -17 } // '(' ,{ 388, 6, 22, 8, 1, -17 } // ')' ,{ 405, 7, 8, 9, 1, -17 } // '*' ,{ 412, 11, 11, 14, 2, -10 } // '+' ,{ 428, 4, 7, 6, 1, -2 } // ',' ,{ 432, 6, 3, 8, 1, -7 } // '-' ,{ 435, 4, 3, 6, 1, -2 } // '.' ,{ 437, 6, 17, 7, 0, -16 } // '/' ,{ 450, 12, 17, 13, 1, -16 } // '0' ,{ 476, 7, 17, 14, 3, -16 } // '1' ,{ 491, 12, 17, 13, 1, -16 } // '2' ,{ 517, 12, 17, 13, 1, -16 } // '3' ,{ 543, 11, 17, 13, 1, -16 } // '4' ,{ 567, 12, 17, 13, 1, -16 } // '5' ,{ 593, 12, 17, 13, 1, -16 } // '6' ,{ 619, 11, 17, 13, 1, -16 } // '7' ,{ 643, 12, 17, 13, 1, -16 } // '8' ,{ 669, 12, 17, 13, 1, -16 } // '9' ,{ 695, 4, 12, 6, 1, -11 } // ':' ,{ 701, 4, 16, 6, 1, -11 } // ';' ,{ 709, 12, 12, 14, 1, -11 } // '<' ,{ 727, 12, 9, 14, 1, -9 } // '=' ,{ 741, 12, 12, 14, 1, -11 } // '>' ,{ 759, 12, 18, 15, 2, -17 } // '?' ,{ 786, 21, 21, 23, 1, -17 } // '@' ,{ 842, 16, 18, 17, 0, -17 } // 'EEN' ,{ 878, 14, 18, 17, 2, -17 } // 'B' ,{ 910, 16, 18, 17, 1, -17 } // 'C' ,{ 946, 15, 18, 17, 2, -17 } // 'D' ,{ 980, 13, 18, 16, 2, -17 } // 'E' ,{ 1010, 12, 18, 15, 2, -17 } // 'F' ,{ 1037, 16, 18, 18, 1, -17 } // 'G' ,{ 1073, 14, 18, 18, 2, -17 } // 'H' ,{ 1105, 4, 18, 7, 2, -17 } // 'ik' ,{ 1114, 11, 18, 14, 1, -17 } // 'J' ,{ 1139, 16, 18, 17, 2, -17 } // 'K' ,{ 1175, 11, 18, 15, 2, -17 } // 'L' ,{ 1200, 17, 18, 21, 2, -17 } // 'M' ,{ 1239, 15, 18, 18, 2, -17 } // 'N' ,{ 1273, 17, 18, 19, 1, -17 } // 'O' ,{ 1312, 14, 18, 16, 2, -17 } // 'P' ,{ 1344, 17, 19, 19, 1, -17 } // 'Q' ,{ 1385, 16, 18, 17, 2, -17 } // 'R' ,{ 1421, 15, 18, 16, 1, -17 } // 'S' ,{ 1455, 12, 18, 15, 2, -17 } // 'T' ,{ 1482, 14, 18, 18, 2, -17 } // 'U' ,{ 1514, 15, 18, 16, 0, -17 } // 'V' ,{ 1548, 23, 18, 23, 0, -17 } // 'W' ,{ 1600, 15, 18, 16, 1, -17 } // 'X' ,{ 1634, 16, 18, 15, 0, -17 } // 'Y' ,{ 1670, 13, 18, 15, 1, -17 } // 'Z' ,{ 1700, 6, 23, 8, 2, -17 } // '[' ,{ 1718, 7, 17, 7, 0, -16 } // '\' ,{ 1733, 6, 23, 8, 0, -17 } // ']' ,{ 1751, 12, 11, 14, 1, -16 } // '^' ,{ 1768, 15, 2, 13, -1, 4 } // '_' ,{ 1772, 4, 3, 6, 0, -17 } // '`' ,{ 1774, 13, 13, 14, 1, -12 } // 'een' ,{ 1796, 13, 18, 15, 2, -17 } // 'b' ,{ 1826, 12, 13, 13, 1, -12 } // 'c' ,{ 1846, 13, 18, 15, 1, -17 } // 'd' ,{ 1876, 13, 13, 14, 1, -12 } // 'e' ,{ 1898, 7, 18, 8, 1, -17 } // 'f' ,{ 1914, 13, 18, 15, 1, -12 } // 'g' ,{ 1944, 12, 18, 14, 2, -17 } // 'h' ,{ 1971, 4, 18, 7, 2, -17 } // 'i' ,{ 1980, 6, 23, 7, 0, -17 } // 'j' ,{ 1998, 12, 18, 14, 2, -17 } // 'k' ,{ 2025, 4, 18, 6, 2, -17 } // 'l' ,{ 2034, 19, 13, 21, 2, -12 } // 'm' ,{ 2065, 12, 13, 15, 2, -12 } // 'n' ,{ 2085, 13, 13, 15, 1, -12 } // 'o' ,{ 2107, 13, 18, 15, 2, -12 } // 'p' ,{ 2137, 13, 18, 15, 1, -12 } // 'q' ,{ 2167, 8, 13, 9, 2, -12 } // 'r' ,{ 2180, 12, 13, 13, 1, -12 } // 's' ,{ 2200, 6, 15, 8, 1, -14 } // 't' ,{ 2212, 12, 13, 15, 2, -12 } // 'u' ,{ 2232, 13, 13, 13, 0, -12 } // 'v' ,{ 2254, 18, 13, 19, 0, -12 } // 'w' ,{ 2284, 13, 13, 13, 0, -12 } // 'x' ,{ 2306, 13, 18, 13, 0, -12 } // 'y' ,{ 2336, 10, 13, 12, 1, -12 } // 'z' ,{ 2353, 6, 23, 9, 1, -17 } // '{' ,{ 2371, 2, 22, 7, 2, -17 } // '|' ,{ 2377, 6, 23, 9, 3, -17 } // '}' ,{ 2395, 12, 5, 12, 0, -7 } // '~' ,{ 2403, 16, 18, 17, 0, -17 } // '' ,{ 2439, 17, 18, 19, 1, -17 } // '' ,{ 2478, 14, 18, 18, 2, -17 } // '' ,{ 2510, 13, 18, 14, 1, -17 } // '' ,{ 2540, 13, 18, 15, 1, -17 } // '' ,{ 2570, 12, 18, 15, 2, -17 } // '' ,{ 2597, 12, 17, 13, 1, -16 } // ' ' ,{ 2623, 8, 13, 12, 2, -17 } // '' }; const GFXfont KbdBold12pt7b PROGMEM = { (uint8_t *)KbdBold12pt7bBitmaps, (GFXglyph *)KbdBold12pt7bGlyphs, 0x18, 0x86, 29 }; // Ca. 2858 bytes
Gelukkig coderen.
8 Reacties
Rüdiger Schwarz
Hallo
/ COM 9600habe den Touchscreen jetzt als eigeständige Tastaur geändert
Info: RSW 01_2022
Benutze Seriellen Ausgang am ESP32 = PIN 5(RX)/PIN 4(TX)
so ändere folgende Zeilen.***RSW***
(Teil 1)
Void loop
case 28: draw_result(text);//Eingabe beenden
text.remove(0);
//setup();
draw_screen(); //Eingabe beenden
kb = true; //* RSW *
delay (300); //* RSW *
break;
************************************************************
(Teil 2) kompl. ersetzten
//Ende der Eingabe Bildschirm löschen und Eingabetext anzeigen
void draw_result( String res) {
kb = false;
#ifdef debug
//Ausgabe des Eingabetexts auf den seriellen Monitor
//Umlaute müssen nach UTF8 gewandelt werden
Serial.println(fromKeyboard(res));
delay (100);
draw_screen();
//wir müssen zuerst den alten Text am Display löschen
tft.fillRect(1, 1, 238, 38, ILI9341_LIGHTGRAY);
tft.setCursor(3, 28);
delay (500);
#endif
*****************************************************************
zum testen geht auch der USB am ESP32 und er Software Arduino
Siggi
Hallo Gerald,
danke für Dein Beispiel, es hat mir sehr geholfen.
Mein AZ-Touch mit 2,8" ist vom Dezember 2021, TFT mit gelber Stiftleiste.
Damit Sketch richtig funktioniert, musste ich folgende Änderungen vornehmen:
//Instanzen für Display und Touch-Screen
//XPT2046_Touchscreen touch(TOUCH_CS, TOUCH_IRQ);
XPT2046_Touchscreen touch(TOUCH_CS); // TOUCH_IRQ entfernt
Bei: void setup()
digitalWrite(TFT_LED, LOW); // Display Beleuchtung ein
Bei: bool Touch_Event() {
// p.x = map(p.x, TS_MINX, TS_MAXX, 0, 320);
// p.y = map(p.y, TS_MINY, TS_MAXY, 240, 0);
p.x = map(p.x, TS_MINX, TS_MAXX, 320, 0); // 320 und 0 getauscht
p.y = map(p.y, TS_MINY, TS_MAXY, 0, 240);// 240 und 0 getauscht
Der Lösung für den 2. Fehler ist von “mike” .
Der 3. Fehler war ähnlich bei “Andreas”.
Danke euch beiden, die Umsetzung war somit deutlich leichter.
Liebe Grüße
Siggi
Gerald Lechner
Hallo Andreas,
der ganze Sketch ist als Beispiel gedacht und zeigt daher den eingegeben Text nur an. Um mehr zu machen, musst du die Funktion drawResult ändern.
Zum Beispiel:
void draw_result( String res) {
kb = false;
#ifdef debug
//Ausgabe des Eingabetexts auf den seriellen Monitor
//Umlaute müssen nach UTF8 gewandelt werden
Serial.println(fromKeyboard(res));
#endif
//Ab hier wird der Bildschirm gelöscht und der eingegebene Text angezeigt
//diese Anzeige könnte man auch weglassen.
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE, ILI9341BLUE);
tft.setCursor(3,160);
tft.print(res);
delay(1000); //Eine Sekunde lang den eingegeben Text anzeigen
//Ende der Textanzeige
//Hier könnte man jetzt mit dem eingegeben Text irgend etwas machen
drawScreen(); //damit wird wieder die Tastatur angezeigt
}
Andreas Dürmuth
Hallo,
der SKetch funktioniert bei mir auf Anhieb. Allerdings bleibt nach der Bestätigung des eingegebenen Textes mit Enter immer angezeigt. Wie kann ich diesen löschen und zum Eingebefeld zurückkommen?
Ich nutze einen ESP32 NodeMCU.
Hat jemand einen Tip?
Danke für eine Antwort,
AndreasD
mike gh
Danke für die Anleitung.
Hinweis
Statt:
digitalWrite(TFT_LED, HIGH); // Display Beleuchtung ein
funktioniert bei mir nur
digitalWrite(TFT_LED, LOW); // low = Display Beleuchtung ein
zum Einschalten des displays
Andreas Bausewein
Hallo Herr Lechner,
Vielen Dank für die Rückmeldung.
Könnten Sie bitte einen Hinweis geben, an welcher Stelle für diese Displays mit anders aufgeklebter Widerstandsfolie die Anpassung bei Ihrer SmartHome Zentrale vorzunehmen ist?
Viele Grüße
Andreas
Gerald Lechner
Es gibt eine kleine Serie mit Displays eines anderen Herstellers (erkennbar an der gelben Stiftleiste) bei denen die Widerstandsfolie andersrum aufgeklebt wurde, sodass die x-Achse gespiegelt ist.
Andreas Bausewein
Hallo,
Sketch ArduTouch2 reagiert horizontal gespiegelt auf Tastatureingaben.
Fehler liegt in der Funktion bool Touch_Event(). Die Zuordnungsbeziehung muss lauten:
p.x = map(p.x, TS_MINX, TS_MAXX, 320, 0); // 320 und 0 haben die Position getauscht
p.y = map(p.y, TS_MINY, TS_MAXY, 240, 0);
Dann ordnet das Touch die auf dem TFT angezeigten Zeichen richtig zu.
Viele Grüße
Andreas