ArduiTouch 2 -Touch screen as input keyboard

Sometimes it is necessary to make some entries. This blog post should show how to use the touchscreen of the ArduiTouch  and one ESP32  can implement a simple input keyboard.

The keyboard has 41 keys and three levels (lowercase, uppercase as well as numbers and characters). The input line is located above the keys. In addition to the space key, the bottom row contains a key for switching to numbers and characters, a key for switching between upper and lower case letters, a key for deleting and the enter key for ending the input. This keyboard function will also be part of a library with which you can create a comfortable graphic interface with the TFT touchscreen.

Code:

#include <SPI.H>
#include "Adafruit_GFX.h" // Graphics library
#include "Adafruit_ILI9341.h" // display driver
#include <XPT2046_Touchscreen.H> // Touchscreen driver
#include "KbdBold12pt7b.h"  // Extended script with German umlauts and                            // special button icons for operation


#define _debug 1 // Turns messages on the serial monitor on or off

// Pins for the display and the 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 for the touchscreen
#define MINPRESSURE 10
#define MAXPRESSURE 2000
#define TS_MINX 370
#define TS_MINY 470
#define TS_MAXX 3700
#define TS_MAXY 3600

// color definition 
#define ILI9341_LIGHT_GRAY 0B1101011010011010

// Instances for display and touch screen
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
XPT2046_Touchscreen touch(TOUCH_CS, TOUCH_IRQ);

/*
  * Keyboard layout
  * Level 0 = lowercase letters
  * Level 1 = capital letters
  * Level 2 = numbers and characters
 * 
  * The special character set contains the following extra characters:
  * 0x18 24 right arrow
  * 0x19 25 left arrow
  * 0x1A 26 up arrow
  * 0x1B 27 Filled up arrow
  * 0x1C 28 Enter key
  * 0x1D 29 Switch letters
  * 0x1E 30 switching digits
  * 0x1F 31 delete key
  * and at the top
  * 0x7F 127 Ä
  * 0x80 128 Ö
  * 0x81 129 nights
  * 0x82 130 ä
  * 0x83 131 ö
  * 0x84 132 g
  * 0x85 133 ß
  * 0x86 134 °
 */
const char keys[3][42] = {   {'a','b','c','d','e','f',    'G','H','i','j','k','l',    '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','I','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}
};

//Global variables
uint8_t level = 0; // current level
bool clicked = false; // touch detected
bool kb; // flag if keyboard is active
String text = ""; // input text
TS_Point p; // Dot structure for touchscreen

void set up() {   #ifdef _debug   Serial.begin(115200);   #endif   pinMode(TFT_LED, OUTPUT);   digitalWrite(TFT_LED, HIGH);    // Display lighting on   // Start the display and touch screen   tft.begin();   touch.begin();   #ifdef _debug   Serial.print("tftx ="); Serial.print(tft.width()); Serial.print("tfty ="); Serial.println(tft.height());   #endif   // output keyboard   draw_screen();   kb = true;

}



void loop() {   uint8_t r,c,index;   char ch;   // Query touchscreen returns true if the screen is touched   // the global variable p contains the position   if (kb && Touch_Event()) {     if (!clicked) {       // we haven't recognized a touch yet       // So we determine the key touched       if (p.x>40) { // only below the entry line         // we determine the row and column of the key         r = (p.x-40) / 40;         c = (p.y) / 40;         // Calculate the index in the keyboard array         index = r*6+c;         // Value of the key touched         ch = keys[level][index];         if (ch > 31) {           // greater than 31 = valid character           // we append it to the input text           text = text + ch; // and output the new text           draw_text();         } else {           // a control key was touched           switch (ch) {             case 26: level = 1; // In capital letters               draw_screen();               break;             case 27: level = 0; // From uppercase to lowercase               draw_screen();               break;             case 29: level = 0; // From zigzers to lowercase               draw_screen();               break;             case 30: level = 2; // On numbers               draw_screen();               break;             case 31: text.remove(text.length()-1); // delete last character               draw_text();               break;             case 28: draw_result(text); // finish input               break;                          }         }                }       clicked = true; // clicked is set to true with a long touch                       // the button is triggered only once     }   } else {     clicked = false; // The touch has ended we are ready for the next key   }

}

// The touchscreen is queried. The global variable p receives the position
// the return value is true when the touchscreen is touched.
// Attention due to the screen orientation, x and y are interchanged!
bool Touch_Event() {   p = touch.getPoint();   delay(1);   p.x = map(p.x, TS_MINX, TS_MAXX, 0, 320);   p.y = map(p.y, TS_MINY, TS_MAXY, 240, 0);   if (p.e.g. > MINPRESSURE) return true;   return false;
}

// Clear the input screen and display the input text
void draw_result( String res) {   kb = false;   #ifdef _debug     // Output of the input text to the serial monitor     // Umlauts must be converted to UTF8     Serial.println(fromKeyboard(res));   #endif   tft.fillScreen(ILI9341_BLACK);   tft.setTextColor(ILI9341_WHITE, ILI9341_BLUE);   tft.setCursor(3,160);   tft.print(res);   }

// redisplay input text
void draw_text() {   uint16_t w,H;   int16_t x1,y1;   // we have to delete the old text on the display first   tft.getTextBounds(text, 0, 0, &x1, &y1, &w, &H);   tft.fillRect(1,1,238,38,ILI9341_LIGHT_GRAY);   tft.setCursor(3,28);   // output new text   tft.print(text);   // output blue cursor   if (text.length() > 0) {     tft.fillRect(7+w,10,3,20,ILI9341_BLUE);   } else {     tft.fillRect(7,10,3,20,ILI9341_BLUE);   }      }

// Show keyboard
void draw_screen() {   uint8_t ix = 0;   uint16_t w,H;   int16_t x1,y1;   char tmp[2];   // Clear display and display input text   tft.fillScreen(ILI9341_BLACK);   tft.setTextColor(ILI9341_BLACK, ILI9341_LIGHT_GRAY);   tft.setFont(&KbdBold12pt7b);   draw_text();   for (uint8_t i = 1; i<8; i++) {     for (uint8_t j = 0; j<6; j++) {       if ((i==7) && ((j==2) || (j == 3))) {         if (j==2) {           // Special case for the space key           tft.fillRoundRect(j*40+1,i*40+1,78,38,9,ILI9341_LIGHT_GRAY);           tft.drawRoundRect(j*40+1,i*40+1,78,38,9,ILI9341_BLUE);           tft.drawRoundRect(j*40+2,i*40+2,76,36,7,ILI9341_BLUE);         }       } else {         // Show normal buttons         tft.fillRoundRect(j*40+1,i*40+1,38,38,9,ILI9341_LIGHT_GRAY);         tft.drawRoundRect(j*40+1,i*40+1,38,38,9,ILI9341_BLUE);         tft.drawRoundRect(j*40+2,i*40+2,36,36,7,ILI9341_BLUE);         // Show key value centered         ix = (i-1)*6+j;         if (ix < 42) {           tmp[0] = keys[level][ix];           tmp[1] = 0;           tft.getTextBounds(tmp, 0, 0, &x1, &y1, &w, &H);           tft.setCursor(j*40+20-w/2,i*40+20+H/2);           tft.print(tmp);         }       }            }   }
}

// Convert a UTF8 string to 8-bit keyboard code
String toKeyboard(String text) {   String res = "";   uint8_t i = 0;   char c;   while (i<text.length()) {     c=text[i];     if (c==195) { // UTF8 characters umlauts       i++;       switch (text[i]) {         case 164: c=130; break;         case 182: c=130; break;         case 188: c=130; break;         case 159: c=133; break;         case 132: c=127; break;         case 150: c=128; break;         case 156: c=129; break;         default: c=0;       }     } else if (c == 194) { // UTF8 character degree symbol       i++;       if (text[i] == 176) c=134; else c=0;     } else if (c > 128) { // normal characters remain unchanged       c=0;     }     if (c>0) res.concat(c);     i++;   }   return res;
}

// Convert input text from 8-bit keyboard code to UTF8
String fromKeyboard(String text) {   String res = "";   char c;   for (uint8_t i=0; i<text.length(); i++) {     c = text[i];     if (c > 126){ // we have special characters       if (c==134) {         res.concat("°");       } else {         switch (c) {           case 130: res.concat("ä"); break;           case 131: res.concat("ö"); break;           case 132: res.concat("ü"); break;           case 133: res.concat("ß"); break;           case 127: res.concat("Ä"); break;           case 128: res.concat("Ö"); break;           case 129: res.concat("Ü"); break;         }       }     } else { // normal character       res.concat(c);     }   }   return res;
}
The code is commented in detail. It should form the basis for your own experiments.

And here is the font:
 Simply save it as a KbdBold12pt7b.h file in the same folder as the sketch.

 

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 }   // 'A'
 ,{   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 }   // 'I'
 ,{  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 }   // 'a'
 ,{  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 };

// Approx. 2858 bytes

 

Happy Coding.

DisplaysEsp-32Projects for beginnersSmart home

6 comments

Gerald Lechner

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, ILI9341
BLUE);
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

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

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

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

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

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

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN