A veces es necesario hacer algunas entradas. Esta publicación de blog debe mostrar cómo usar la pantalla táctil del ArduiTouch y uno ESP32 puede implementar un teclado de entrada simple.
El teclado tiene 41 teclas y tres niveles (minúsculas, mayúsculas y números y caracteres). La línea de entrada se encuentra sobre las teclas. Además de la tecla de espacio, la fila inferior contiene una tecla para cambiar a números y caracteres, una tecla para cambiar entre mayúsculas y minúsculas, una tecla para eliminar y la tecla Intro para finalizar la entrada. Esta función de teclado también formará parte de una biblioteca con la que podrá crear una interfaz gráfica cómoda con la pantalla táctil TFT.
Código:
#include <SPI.h> #include "Adafruit_GFX.h" // Biblioteca de gráficos #include "Adafruit_ILI9341.h" // controlador de pantalla #include <XPT2046_Pantalla táctil.h> // controlador de pantalla táctil #include "KbdBold12pt7b.h" // Script extendido con diéresis alemanas y // iconos de botones especiales para la operación #definir _debug 1 // Activa o desactiva los mensajes en el monitor serie // Pines para la pantalla y la pantalla táctil #definir TFT_CS 5 #definir TFT_DC 4 #definir TFT_MOSI 23 #definir TFT_CLK 18 #definir TFT_RST 22 #definir TFT_MISO 19 #definir TFT_LED 15 #definir HAVE_TOUCHPAD #definir TOUCH_CS 14 #definir TOUCH_IRQ 2 // Parámetros para la pantalla táctil #definir MINPRESION 10 #definir PRESIÓN MÁXIMA 2000 #definir TS_MINX 370 #definir TS_MINY 470 #definir TS_MAXX 3700 #definir TS_MAXY 3600 // definición de color #definir ILI9341_LIGHT_GRAY 0B1101011010011010 // Instancias para visualización y pantalla táctil Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); XPT2046_Pantalla táctil tocar(TOUCH_CS, TOUCH_IRQ); /* * Distribución del teclado * Nivel 0 = letras minúsculas * Nivel 1 = mayúsculas * Nivel 2 = números y caracteres * * El conjunto de caracteres especiales contiene los siguientes caracteres adicionales: * 0x18 24 flecha derecha * 0x19 25 flecha izquierda * 0x1A 26 flecha arriba * 0x1B 27 Flecha llena * 0x1C 28 Tecla Enter * 0x1D 29 Cambiar letras * 0x1E 30 dígitos de conmutación * 0x1F 31 borrar clave * y en la parte superior * 0x7F 127 Ä * 0x80 128 Ö * 0x81 129 noches * 0x82 130 ä * 0x83 131 ö * 0x84 132 g * 0x85 133 ß * 0x86 134 ° */ const char llaves[3][42] = { {'a','b','c','d','e','f', 'g','h','i','j','k','l', 'm','n','o','p','q','r', 's','t','tu','v','w','x', 'y','z',130,131,132,133, ',','.','-','_','/','@', 30,26,' ',' ',31,28}, {'A','B','C','D','E','F', 'G','H','Yo','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} }; // Variables globales uint8_t nivel = 0; // nivel actual bool hecho clic = falso; // toque detectado bool kb; // marca si el teclado está activo Cadena texto = ""; // ingresar texto TS_Point p; // Estructura de puntos para pantalla táctil nulo configuración() { #ifdef _debug De serie.comenzar(115200); #endif pinMode(TFT_LED, SALIDA); digitalWrite(TFT_LED, ALTO); // Mostrar iluminación encendida // Inicia la visualización y la pantalla táctil tft.comenzar(); tocar.comenzar(); #ifdef _debug De serie.imprimir("tftx ="); De serie.imprimir(tft.ancho()); De serie.imprimir("tfty ="); De serie.println(tft.altura()); #endif // teclado de salida draw_screen(); kb = cierto; } nulo bucle() { uint8_t r,c,indice; char ch; // La pantalla táctil de consulta devuelve verdadero si se toca la pantalla // la variable global p contiene la posición si (kb && Touch_Event()) { si (!hecho clic) { // aún no hemos reconocido un toque // Entonces determinamos la tecla tocada si (p.x>40) { // solo debajo de la línea de entrada // determinamos la fila y columna de la clave r = (p.x-40) / 40; c = (p.y) / 40; // Calcular el índice en la matriz del teclado indice = r*6+c; // Valor de la tecla tocada ch = llaves[nivel][indice]; si (ch > 31) { // mayor que 31 = carácter válido // lo agregamos al texto de entrada texto = texto + ch; // y generar el nuevo texto draw_text(); } otra cosa { // se tocó una tecla de control cambiar (ch) { caso 26: nivel = 1; // en mayúsculas draw_screen(); romper; caso 27: nivel = 0; // De mayúsculas a minúsculas draw_screen(); romper; caso 29: nivel = 0; // De zigzers a minúsculas draw_screen(); romper; caso 30: nivel = 2; // En números draw_screen(); romper; caso 31: texto.quitar(texto.longitud()-1); // eliminar el último caracter draw_text(); romper; caso 28: resultado_dibujo(texto); // finalizar entrada romper; } } } hecho clic = cierto; // cliqueado se establece en verdadero con un toque largo // el botón se activa solo una vez } } otra cosa { hecho clic = falso; // El toque ha terminado, estamos listos para la siguiente tecla } } // Se consulta la pantalla táctil. La variable global p recibe la posición // el valor de retorno es verdadero cuando se toca la pantalla táctil. // ¡Atención debido a la orientación de la pantalla, x e y se intercambian! bool Touch_Event() { p = tocar.getPoint(); retrasar(1); p.x = mapa(p.x, TS_MINX, TS_MAXX, 0, 320); p.y = mapa(p.y, TS_MINY, TS_MAXY, 240, 0); si (p.p. > MINPRESION) volver cierto; volver falso; } // Borrar la pantalla de entrada y mostrar el texto de entrada nulo resultado_dibujo( Cadena res) { kb = falso; #ifdef _debug // Salida del texto de entrada al monitor serie // Umlauts se deben convertir a UTF8 De serie.println(fromKeyboard(res)); #endif tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLUE); tft.setCursor(3,160); tft.imprimir(res); } // volver a mostrar el texto de entrada nulo draw_text() { uint16_t w,h; int16_t x1,y1; // primero tenemos que eliminar el texto antiguo en la pantalla tft.getTextBounds(texto, 0, 0, &x1, &y1, &w, &h); tft.fillRect(1,1,238,38,ILI9341_LIGHT_GRAY); tft.setCursor(3,28); // salida de texto nuevo tft.imprimir(texto); // salida del cursor azul si (texto.longitud() > 0) { tft.fillRect(7+w,10,3,20,ILI9341_BLUE); } otra cosa { tft.fillRect(7,10,3,20,ILI9341_BLUE); } } // Mostrar teclado nulo draw_screen() { uint8_t ix = 0; uint16_t w,h; int16_t x1,y1; char tmp[2]; // Borrar pantalla y mostrar texto de entrada tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_BLACK, ILI9341_LIGHT_GRAY); tft.setFont(&KbdBold12pt7b); draw_text(); para (uint8_t yo = 1; yo<8; yo++) { para (uint8_t j = 0; j<6; j++) { si ((yo==7) && ((j==2) || (j == 3))) { si (j==2) { // Caso especial para la tecla de espacio tft.fillRoundRect(j*40+1,yo*40+1,78,38,9,ILI9341_LIGHT_GRAY); tft.drawRoundRect(j*40+1,yo*40+1,78,38,9,ILI9341_BLUE); tft.drawRoundRect(j*40+2,yo*40+2,76,36,7,ILI9341_BLUE); } } otra cosa { // Mostrar botones normales tft.fillRoundRect(j*40+1,yo*40+1,38,38,9,ILI9341_LIGHT_GRAY); tft.drawRoundRect(j*40+1,yo*40+1,38,38,9,ILI9341_BLUE); tft.drawRoundRect(j*40+2,yo*40+2,36,36,7,ILI9341_BLUE); // Mostrar valor clave centrado ix = (yo-1)*6+j; si (ix < 42) { tmp[0] = llaves[nivel][ix]; tmp[1] = 0; tft.getTextBounds(tmp, 0, 0, &x1, &y1, &w, &h); tft.setCursor(j*40+20-w/2,yo*40+20+h/2); tft.imprimir(tmp); } } } } } // Convierte una cadena UTF8 a código de teclado de 8 bits Cadena toKeyboard(Cadena texto) { Cadena res = ""; uint8_t yo = 0; char c; mientras que (yo<texto.longitud()) { c=texto[yo]; si (c==195) { // diéresis de caracteres UTF8 yo++; cambiar (texto[yo]) { caso 164: c=130; romper; caso 182: c=130; romper; caso 188: c=130; romper; caso 159: c=133; romper; caso 132: c=127; romper; caso 150: c=128; romper; caso 156: c=129; romper; por defecto: c=0; } } otra cosa si (c == 194) { // símbolo de grado de caracteres UTF8 yo++; si (texto[yo] == 176) c=134; otra cosa c=0; } otra cosa si (c > 128) { // los caracteres normales permanecen sin cambios c=0; } si (c>0) res.concat(c); yo++; } volver res; } // Convierte el texto de entrada del código del teclado de 8 bits a UTF8 Cadena fromKeyboard(Cadena texto) { Cadena res = ""; char c; para (uint8_t yo=0; yo<texto.longitud(); yo++) { c = texto[yo]; si (c > 126){ // tenemos caracteres especiales si (c==134) { res.concat("°"); } otra cosa { cambiar (c) { caso 130: res.concat("ä"); romper; caso 131: res.concat("ö"); romper; caso 132: res.concat("ü"); romper; caso 133: res.concat("ß"); romper; caso 127: res.concat("Ä"); romper; caso 128: res.concat("Ö"); romper; caso 129: res.concat("Ü"); romper; } } } otra cosa { // personaje normal res.concat(c); } } volver res; }
El código se comenta en detalle. Debería formar la base de tus propios experimentos.
Y aquí está la fuente:
Simplemente guárdelo como un archivo KbdBold12pt7b.h en la misma carpeta que el boceto.
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 } // 'UN' ,{ 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 } // 'YO' ,{ 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 } // 'PAG' ,{ 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 } // 'un' ,{ 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 } // 'yo' ,{ 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 } // 'pag' ,{ 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 }; // Aprox. 2858 bytes
Feliz codificación.
8 comentarios
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