Teclado Mecanico

En este proyecto pretendo crear un teclado auxiliar de 16 teclas que mediante dos pulsadores conseguimos tener en un solo teclado 64 teclas para todas aquellas personas, que como yo mismo, solo podemos usar una mano para manejar los ordenadores y ciertas teclas se nos hace complicado usarlas y no podemos prescindir de ellas, ya que las usamos habitualmente para escribir correos electrónicos o los que nos dedicamos al mundillo de la programación.

En el primer teclado tenemos. Aquellos caracteres espaciales de un teclado convencional. Pulsando el pulsador de la derecha se enciende el led de color verde que nos indica que dicho teclado se convierte en una calculadora con las 4 operaciones básicas de sumar, restar, multiplicar y dividir. Si por el contrario pulsamos el de la izquierda, se enciende el led de color azul y de esta manera sabemos que el teclado responde a las combinaciones de las teclas de “CTRL+F…” y con los dos pulsadores activados, el led se ilumina de color rojo indicándonos que el teclado está preparado para la combinación de teclas ·ALT+F…”.

Para que funcionen dichas combinaciones en Windows, usaremos la aplicación “Autohotkey” con la cual la programaremos cada una de las teclas que le hemos asignado a este teclado, tanto para las de “CTRL+F…” o las “ALT+F…”. En Mac, podemos hacer lo mismo con la aplicación “Keyboard Maestro”.

En esta ocasión veréis que he utilizado un Arduino Leonardo, que lleva incorporado el Atmega32U4 ya que si lo probáis con cualquier otra no os funcionara.

Junto a este escrito os dejare un fichero comprimido con el código fuente de la aplicación y las dos librerías modificadas para que reconozca al teclado español, estos tres ficheros han de estar en la misma carpeta.

Cabe comentar que, si lo vais a usar en Mac, la primera tecla que habéis de presionar a la hora de que el sistema reconozca el teclado, es el símbolo “<”; de esta manera no perderéis la configuración del teclado principal.

Materiales:

Protoboard
Arrduino Leonardo
Teclado
2 Pulsadores
3 resistencias de 150 Ohm
2 Resisténcias de 4,7K
1 Led RGB

Y un manojo de cables para realizar las conexiones pertinentes.

Esquema de conexión:

Aplicación:

Teclado membrana
keyboard.h
keyboard.cpp
/*
 * Pulsador-interuptor anlógico en modointerruptor
 * Arduino Leonardo 32U4
 * RESISTENCIA 10K O4,7K A NEGATIU L'ALTRE NEGATIU AL PIN A0 I A1
 * I el otro a voltaje 5V
 */
#include <Keypad.h>
#include "Keyboard.h"    // Esta es una biblioteca "incorporada" sin necesidad de instalar
#include <SoftwareSerial.h>
#include <Wire.h>
 
SoftwareSerial serial1(10, 11); // RX, TX
 
String textoRecebido = "";
unsigned long delay1 = 0;
 
 
#define RxD 0                             // Usado para conexion rs232 virtual.
#define TxD 1                             // Usado para conexion rs232 virtual.
 
#define PulsadorD A0  // Pulsador derecho
#define PulsadorE A1  // Pulsador izquierdo
 
const byte filas = 4;     //Numero de filas del teclado
const byte columnas = 4;  //Numero de columnas del teclado
 
 
int iniciD = 0;    //Estado incial del pulsdor derecho
int estatACD = 0;  //Estado actual del pulsador derecho
int estatAND = 0;  //Guarda estado anterior del pulsador derecho
 
int iniciE = 0;    //Estado incial del pulsdor izquierdo
int estatACE = 0;  //Estado actual del pulsador izquierdo
int estatANE = 0;  //Guarda Estado anterior del pulsador izquierdo
 
int rled = A3;     // Pin PWN 11 para led rojo
int bled = A4;     // Pin PWM 10 para led azul
int vled = A5;     // Pin PWM 9  para led verde
 
int vdos = 0;
 
//Defino una matriz 4x4 con la posicion de las filas y columnas
char matriz[filas][columnas] =
{
 
  { '<', '>', '@', 'A'},
  { '{', '}', '#', 'B'},
  { '(', ')', '/', 'C'},
  { '*', '0', '[', ']'},
 
};
 
byte pinesFilas[filas] = {5, 4, 3, 2};       //Pines donde van conectadas las filas del teclado
byte pinesColumnas[columnas] = {9, 8, 7, 6}; //Pines donde van conectadas las columnas del teclado
 
//Inicializo el teclado con el numero de filas, columnas, los pines del Arduino utilizados y la matriz
Keypad teclado = Keypad( makeKeymap(matriz), pinesFilas, pinesColumnas, filas, columnas);
 
 
SoftwareSerial comVirtual(RxD, TxD);
 
 
 
void leds(){
    estatACD = digitalRead(PulsadorD); //Leemos el estado del pulsador derecho
    estatACE = digitalRead(PulsadorE); //Leemos el estado del pulsador derecho izquierdo
    vdos = 0;
  
  //Pulsador derecho
    if(estatACD && estatAND == 0){    //Si el pulsador derecho esta pulsado
        iniciD = 1 - iniciD;
        delay(100);
    }
    estatAND = estatACD;
     
    if(iniciD == 1){                  //SI EL PULSADOR ESTA PULSADO
      vdos = 1;
    }
 
  //Pulsador izquierdo
    if(estatACE && estatANE == 0){    //Si el pulsador izquierdo esta pulsado
        iniciE = 1 - iniciE;
        delay(100);
    }
    estatANE = estatACE;
     
    if(iniciE == 1){                  //SI EL PULSADOR ESTA PULSADO
      vdos = 2;
    }
 
    if(iniciD == 1 && iniciE == 1){   //SI EL PULSADOR ESTA PULSADO
      vdos = 3;
    }
  
}
   
void setup() {
  pinMode(13, OUTPUT);
  pinMode(PulsadorD, INPUT);
  pinMode(PulsadorE, INPUT);
    /*----- Se inicializan pines PWM como salida*/  
  pinMode(rled, OUTPUT);
  pinMode(bled, OUTPUT);
  pinMode(vled, OUTPUT);
  Serial.begin(9600);   //Inicializo el puerto serie
 
}
 
void loop() {
    leds();
  
    switch (vdos) {
      case 1:
        digitalWrite(13, HIGH);
        digitalWrite(rled, LOW);
        digitalWrite(bled, LOW);
        digitalWrite(vled, HIGH);
        verd();
                   
        delay(200);
        break;
      case 2:
        digitalWrite(13, HIGH);
        digitalWrite(rled, LOW);
        digitalWrite(bled, HIGH);
        digitalWrite(vled, LOW);
        blau();
         
        delay(200);
        break;
      case 3:
        digitalWrite(13, HIGH);
        digitalWrite(rled, HIGH);
        digitalWrite(bled, LOW);
        digitalWrite(vled, LOW);
        vermell();
           
        delay(200);
        break;  
      case 0:
          digitalWrite(13, LOW);
          digitalWrite(rled, LOW);
          digitalWrite(bled, LOW);
          digitalWrite(vled, LOW);
 
           // ************ Teclado ******************
          char caracter;
          char tecla_presionada = teclado.getKey();   //Almaceno en una variable la tecla presionada
      
          if (tecla_presionada)
          {
             Keyboard.begin();                        //begin keyboard 
             Keyboard.write(tecla_presionada);        //Envia caracter
             Keyboard.end();
           }
  
          delay(200);
          break;
     }   
}
 
void verd(){
                  // ************ Pulsador derecho ******************
  char caracter;
  char tecla_presionada = teclado.getKey();    //Almaceno en una variable la tecla presionada
         
  if (tecla_presionada)
     {
      Keyboard.begin();                       //begin keyboard 
      // Keyboard.write(tecla_presionada);    //Envia caracter
      if(tecla_presionada == '<'){
        Keyboard.print("1");
      }
      if(tecla_presionada == '>'){
        Keyboard.print("2");
      }
       if(tecla_presionada == '@'){
        Keyboard.print("3");
      }
       if(tecla_presionada == 'A'){
        Keyboard.print("/");
      }
       if(tecla_presionada == '{'){
        Keyboard.print("4");
      }
       if(tecla_presionada == '}'){
        Keyboard.print("5");
      }
       if(tecla_presionada == '#'){
        Keyboard.print("6");
      }
       if(tecla_presionada == 'B'){
        Keyboard.print("*");
      }
       if(tecla_presionada == '('){
        Keyboard.print("7");
      }
       if(tecla_presionada == ')'){
        Keyboard.print("8");
      }
       if(tecla_presionada == '/'){
        Keyboard.print("9");
      }
       if(tecla_presionada == 'C'){
        Keyboard.print("-");
      }
       if(tecla_presionada == '*'){
        Keyboard.print(",");
      }
       if(tecla_presionada == '0'){
        Keyboard.print("0");
      }
       if(tecla_presionada == '['){
        Keyboard.print("=");
      }
       if(tecla_presionada == ']'){
        Keyboard.print("+");
      }
      Keyboard.end();
     }
}      
 
 void blau(){
                  // ************ Pulsador izquierdo ******************
  char caracter;
  char tecla_presionada = teclado.getKey();    //Almaceno en una variable la tecla presionada
         
  if (tecla_presionada)
     {
      Keyboard.begin();                        //begin keyboard 
         if(tecla_presionada == '<'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F1);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '>'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F2);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '@'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F3);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }   
        if(tecla_presionada == '{'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F4);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '}'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F5);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '#'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F6);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }              
        if(tecla_presionada == '('){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F7);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == ')'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F9);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '/'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F9);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }   
        if(tecla_presionada == '*'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F10);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '0'){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F11);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '['){
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_F12);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }          
     }
}      
 
void vermell(){
 
                  // ************ Pulsador derecho e izquierdo ******************
  char caracter;
  char tecla_presionada = teclado.getKey();    //Almaceno en una variable la tecla presionada
         
  if (tecla_presionada)
     {
     Keyboard.begin();                        //begin keyboard 
       if(tecla_presionada == '<'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F1);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '>'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F2);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '@'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F3);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }   
        if(tecla_presionada == '{'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F4);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '}'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F5);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '#'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F6);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }              
        if(tecla_presionada == '('){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F7);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == ')'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F9);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '/'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F9);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }   
        if(tecla_presionada == '*'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F10);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '0'){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F11);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
        if(tecla_presionada == '['){
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_F12);
          delay(100);
          Keyboard.releaseAll();
          Keyboard.end();
       }
     }
}      
/*
  Keyboard.h
 
  Copyright (c) 2015, Arduino LLC
  Original code (pre-library): Copyright (c) 2011, Peter Barrett
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
 
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
 
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
 
#ifndef KEYBOARD_h
#define KEYBOARD_h
 
#include "HID.h"
 
#if !defined(_USING_HID)
 
#warning "Using legacy HID core (non pluggable)"
 
#else
 
//================================================================================
//================================================================================
//  Keyboard
 
#define KEY_LEFT_CTRL   0x80
#define KEY_LEFT_SHIFT    0x81
#define KEY_LEFT_ALT    0x82
#define KEY_LEFT_GUI    0x83
#define KEY_RIGHT_CTRL    0x84
#define KEY_RIGHT_SHIFT   0x85
#define KEY_RIGHT_ALT   0x86
#define KEY_RIGHT_GUI   0x87
 
#define KEY_UP_ARROW    0xDA
#define KEY_DOWN_ARROW    0xD9
#define KEY_LEFT_ARROW    0xD8
#define KEY_RIGHT_ARROW   0xD7
#define KEY_BACKSPACE   0xB2
#define KEY_TAB       0xB3
#define KEY_RETURN      0xB0
#define KEY_ESC       0xB1
#define KEY_INSERT      0xD1
#define KEY_DELETE      0xD4
#define KEY_PAGE_UP     0xD3
#define KEY_PAGE_DOWN   0xD6
#define KEY_HOME      0xD2
#define KEY_END       0xD5
#define KEY_CAPS_LOCK   0xC1
#define KEY_F1        0xC2
#define KEY_F2        0xC3
#define KEY_F3        0xC4
#define KEY_F4        0xC5
#define KEY_F5        0xC6
#define KEY_F6        0xC7
#define KEY_F7        0xC8
#define KEY_F8        0xC9
#define KEY_F9        0xCA
#define KEY_F10       0xCB
#define KEY_F11       0xCC
#define KEY_F12       0xCD
 
//  Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct
{
  uint8_t modifiers;
  uint8_t reserved;
  uint8_t keys[6];
} KeyReport;
 
class Keyboard_ : public Print
{
private:
  KeyReport _keyReport;
  void sendReport(KeyReport* keys);
public:
  Keyboard_(void);
  void begin(void);
  void end(void);
  size_t write(uint8_t k);
  size_t press(uint8_t k);
  size_t release(uint8_t k);
  void releaseAll(void);
};
extern Keyboard_ Keyboard;
 
#endif
#endif
/*
  Keyboard.cpp
 
  Copyright (c) 2015, Arduino LLC
  Original code (pre-library): Copyright (c) 2011, Peter Barrett
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
 
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
 
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
 
#include "Keyboard.h"
 
#if defined(_USING_HID)
 
//================================================================================
//================================================================================
//  Keyboard
 
static const uint8_t _hidReportDescriptor[] PROGMEM = {
 
  //  Keyboard
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)  // 47
    0x09, 0x06,                    // USAGE (Keyboard)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x85, 0x02,                    //   REPORT_ID (2)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
 
  0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
 
  0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
 
  0x95, 0x06,                    //   REPORT_COUNT (6)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
 
  0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0,                          // END_COLLECTION
};
 
Keyboard_::Keyboard_(void)
{
  static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
  HID().AppendDescriptor(&node);
}
 
void Keyboard_::begin(void)
{
}
 
void Keyboard_::end(void)
{
}
 
void Keyboard_::sendReport(KeyReport* keys)
{
  HID().SendReport(2,keys,sizeof(KeyReport));
}
 
extern
const uint8_t _asciimap[128] PROGMEM;
/*
 * _asciimap took from Keyboard.cpp,
 * need somebody to test with spansih layout.
 */
 
#define SHIFT 0x80
const uint8_t _asciimap[128] =
{
  0x00,             // NUL          0
  0x00,             // SOH
  0x00,             // STX
  0x00,             // ETX
  0x00,             // EOT
  0x00,             // ENQ
  0x00,             // ACK
  0x00,             // BEL
  0x2a,      // BS  Backspace
  0x2b,      // TAB  Tab
  0x28,      // LF  Enter           10
  0x00,             // VT
  0x00,             // FF
  0x00,             // CR
  0x00,             // SO
  0x00,             // SI
  0x00,             // DEL
  0x00,             // DC1
  0x00,             // DC2
  0x00,             // DC3
  0x00,             // DC4          20
  0x00,             // NAK
  0x00,             // SYN
  0x00,             // ETB
  0x00,             // CAN
  0x00,             // EM
  0x00,             // SUB
  0x00,             // ESC
  0x00,             // FS
  0x00,             // GS
  0x00,             // RS           30
  0x00,             // US
 
  0x2c,          //  ' '
  0x1e|SHIFT,    // !
  0x1f|SHIFT,    // "
    0x20,        // # 
  0x21|SHIFT,    // $
  0x22|SHIFT,    // %
  0x23|SHIFT,    // &
  0x2d,    // '
  0x25|SHIFT,    // (               40
  0x26|SHIFT,    // )
  0x30|SHIFT,    // *
  0x30,          // +
  0x36,          // ,
  0x38,          // -
  0x37,          // .    
  0x24|SHIFT,    // /
  0x27,          // 0
  0x1e,          // 1
  0x1f,          // 2               50
  0x20,          // 3
  0x21,          // 4
  0x22,          // 5
  0x23,          // 6
  0x24,          // 7
  0x25,          // 8
  0x26,          // 9
  0x37|SHIFT,      // :
  0x36|SHIFT,      // ;
    0x64,         // <             60
  0x27|SHIFT,      // =    
  0x64|SHIFT,      // > 0x64|SHIFT,
  0x2d|SHIFT,      // ?
    0x1f,            // @   
  0x04|SHIFT,      // A
  0x05|SHIFT,      // B
  0x06|SHIFT,      // C
  0x07|SHIFT,      // D
  0x08|SHIFT,      // E
  0x09|SHIFT,      // F             70
  0x0a|SHIFT,      // G
  0x0b|SHIFT,      // H
  0x0c|SHIFT,      // I
  0x0d|SHIFT,      // J
  0x0e|SHIFT,      // K
  0x0f|SHIFT,      // L
  0x10|SHIFT,      // M
  0x11|SHIFT,      // N
  0x12|SHIFT,      // O
  0x13|SHIFT,      // P             80
  0x14|SHIFT,      // Q
  0x15|SHIFT,      // R
  0x16|SHIFT,      // S
  0x17|SHIFT,      // T
  0x18|SHIFT,      // U
  0x19|SHIFT,      // V
  0x1a|SHIFT,      // W
  0x1b|SHIFT,      // X
  0x1c|SHIFT,      // Y
  0x1d|SHIFT,      // Z             90
  0x2f,          // [
  0x31,          // bslash 
  0x30,          // ]
    0x94|SHIFT,          // ^
  0x38|SHIFT,    // _
  0x2e|SHIFT,    // `    
  0x04,          // a
  0x05,          // b
  0x06,          // c
  0x07,          // d               100
  0x08,          // e
  0x09,          // f
  0x0a,          // g
  0x0b,          // h
  0x0c,          // i
  0x0d,          // j
  0x0e,          // k
  0x0f,          // l
  0x10,          // m
  0x11,          // n               110
  0x12,          // o
  0x13,          // p
  0x14,          // q
  0x15,          // r
  0x16,          // s
  0x17,          // t
  0x18,          // u
  0x19,          // v
  0x1a,          // w
  0x1b,          // x               120
  0x1c,          // y
  0x1d,          // z
  0x34,    // {
    0x38|SHIFT,   // |
  0x32,    // }
  0x21,    // ~
  0        // DEL                   127
};
 
// Init var         
bool _altGrMap[128];
bool _altFine = false;
 
// Individually define all needed char
void initAltGr() {
  _altFine = true;
 
  _altGrMap[126] = true; // ~
  _altGrMap[123] = true; // {
  _altGrMap[91] = true;  // [
  _altGrMap[93] = true;  // ]
  _altGrMap[125] = true; // }
  _altGrMap[92] = true;  // bslash
  _altGrMap[124] = true; // |
  _altGrMap[64] = true;  // @
  _altGrMap[35] = true; // #   35
  _altGrMap[94] = true; // ^
  _altGrMap[96] = true; // `
 }
 
uint8_t USBPutChar(uint8_t c);
 
// press() adds the specified key (printing, non-printing, or modifier)
// to the persistent key report and sends the report.  Because of the way
// USB HID works, the host acts like the key remains pressed until we
// call release(), releaseAll(), or otherwise clear the report and resend.
size_t Keyboard_::press(uint8_t k)
{
  uint8_t i;
  if (k >= 136) {      // it's a non-printing key (not a modifier)
    k = k - 136;
  } else if (k >= 128) {  // it's a modifier key
    _keyReport.modifiers |= (1<<(k-128));
    k = 0;
  } else {        // it's a printing key
    int oldKey = k;
    k = pgm_read_byte(_asciimap + k);
    if (!k) {
      setWriteError();
      return 0;
    }
    if (k & 0x80) {            // it's a capital letter or other character reached with shift
      _keyReport.modifiers |= 0x02;  // the left shift modifier
      k &= 0x7F;
    }
 
    if (!_altFine)
      initAltGr();
    if (_altGrMap[oldKey])
      _keyReport.modifiers |= 0x40;
  }
 
  // Add k to the key report only if it's not already present
  // and if there is an empty slot.
  if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
    _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
    _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
 
    for (i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0x00) {
        _keyReport.keys[i] = k;
        break;
      }
    }
    if (i == 6) {
      setWriteError();
      return 0;
    }
  }
  sendReport(&_keyReport);
  return 1;
}
 
// release() takes the specified key out of the persistent key report and
// sends the report.  This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
size_t Keyboard_::release(uint8_t k)
{
  uint8_t i;
  if (k >= 136) {      // it's a non-printing key (not a modifier)
    k = k - 136;
  } else if (k >= 128) {  // it's a modifier key
    _keyReport.modifiers &= ~(1<<(k-128));
    k = 0;
  } else {        // it's a printing key
    int oldKey = k;
    k = pgm_read_byte(_asciimap + k);
    if (!k) {
      return 0;
    }
    if (k & 0x80) {              // it's a capital letter or other character reached with shift
      _keyReport.modifiers &= ~(0x02);  // the left shift modifier
      k &= 0x7F;
    }
 
    if (_altGrMap[oldKey])
      _keyReport.modifiers &= ~(0x40);
  }
 
  // Test the key report to see if k is present.  Clear it if it exists.
  // Check all positions in case the key is present more than once (which it shouldn't be)
  for (i=0; i<6; i++) {
    if (0 != k && _keyReport.keys[i] == k) {
      _keyReport.keys[i] = 0x00;
    }
  }
 
  sendReport(&_keyReport);
  return 1;
}
 
void Keyboard_::releaseAll(void)
{
  _keyReport.keys[0] = 0;
  _keyReport.keys[1] = 0;
  _keyReport.keys[2] = 0;
  _keyReport.keys[3] = 0;
  _keyReport.keys[4] = 0;
  _keyReport.keys[5] = 0;
  _keyReport.modifiers = 0;
  sendReport(&_keyReport);
}
 
size_t Keyboard_::write(uint8_t c)
{
  uint8_t p = press(c);  // Keydown
  release(c);            // Keyup
  return p;              // just return the result of press() since release() almost always returns 1
}
 
Keyboard_ Keyboard;
 
#endif

Descarga de los ficheros:

No debes olvidar de incluir los tres ficheros en la misma carpeta.