ArduiTouch 2 - Touchscreen als Eingabetastatur - AZ-Delivery

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.

DisplaysEsp-32Projekte für anfängerSmart home

8 comentarios

Rüdiger Schwarz

Rüdiger Schwarz

Hallo
habe den Touchscreen jetzt als eigeständige Tastaur geändert
Info: RSW 01_2022

/ COM 9600

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_LIGHT
GRAY);
tft.setCursor(3, 28);
delay (500);
#endif
*****************************************************************
zum testen geht auch der USB am ESP32 und er Software Arduino

Siggi

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

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

Deja un comentario

Todos los comentarios son moderados antes de ser publicados