Arduino Pro Micro

Teclamicro

Dispositivo pensado para introducir contraseñas por teclado en el PC y acceder al sistema o ejecutar programas que requieran contraseña. Permite introducir diferentes contraseñas según la posición de un conmutador mecánico que tiene en la caja. También permite hacer movimientos del ratón cada minuto para evitar que el equipo se ponga en ahorro de energía. Las funciones anteriores se ejecutan al pasar por el dispositivo una tarjeta RFID admitida.

Cuando se pasa una tarjeta RFID cerca del lector, si la tarjeta es válida se activa el led verde y suena un pitido agudo por el zumbador y, si la tarjeta no es válida se activa el led rojo y suena otro pitido más grave por el zumbador para indicar que no se ha conseguido el acceso.


Conmutador de 7 posiciones para poner diferentes contraseñas o repetir cada minuto un movimiento de ratón para que el PC no entre en ahorro de energía...


Pulsador de Reset y conector USB hacía el PC...


El dispositivo solo introduce las contraseñas por teclado cuando se pasa una tarjeta o llavero RFID válido. Se utiliza un lector RFID modelo RC522.


Pinout de conexiones del lector RC522...


Este montaje se había realizado inicialmente con una placa ESP32 emulando un teclado Bluetooth. Al final se cambió la ESP32 por un Arduino Pro Micro que trabaja directamente como un teclado o ratón normal (interfaz HDI).


Conector y cableado en la parte posterior del lector RFID-RC522...

Código utilizado en este montaje

/* TECLAMICRO - JIDS 2024

Este programa escribe contraseñas o textos en el PC usando un Arduino Pro Micro. Las contraseñas se 
escriben solo cuando se pasa una tarjeta RFID válida por el lector. 

Se pueden programar 7 contraseñas u opciones de escritura diferentes para cualquier tarjeta RFID que
esté admitida. Las tarjetas se identifican por su ID y están configuradas directamente en este código.

Una de las opciones está dedicada a hacer movimientos del cursor del ratón cada minuto de forma que 
el PC no se ponga en ahorro de energía cuando está haciendo alguna tarea larga.
*/

#include <SPI.h>
#include <MFRC522.h>
#include <Keyboard.h>
#include "Mouse.h"

constexpr uint8_t RST_PIN = 9;
constexpr uint8_t SS_PIN = 10;

MFRC522 mfrc522(SS_PIN, RST_PIN);

int RXLED = 17;

const int conmuta1Pin = 6;  // Rojo
const int conmuta2Pin = 7;  // Amarillo 
const int conmuta3Pin = 8;  // Gris
const int conmuta4Pin = 21; // A3 Verde
const int conmuta5Pin = 2;  // Marrón
const int conmuta6Pin = 3;  // Naranja
const int conmuta7Pin = 4;  // Azul
int conmuta1, conmuta1ant;
int conmuta2, conmuta2ant;
int conmuta3, conmuta3ant;
int conmuta4, conmuta4ant;
int conmuta5, conmuta5ant;
int conmuta6, conmuta6ant;
int conmuta7, conmuta7ant;
int tarjeta_admitida = 0;
const int buzzerPin = 9;
const int ledrojoPin = 19;   // A1
const int ledverdePin = 20;  // A2

void setup() {
  pinMode(conmuta1Pin, INPUT_PULLUP);
  pinMode(conmuta2Pin, INPUT_PULLUP);
  pinMode(conmuta3Pin, INPUT_PULLUP);
  pinMode(conmuta4Pin, INPUT_PULLUP);
  pinMode(conmuta5Pin, INPUT_PULLUP);
  pinMode(conmuta6Pin, INPUT_PULLUP);
  pinMode(conmuta7Pin, INPUT_PULLUP);
  pinMode(buzzerPin, OUTPUT); 
  pinMode(ledrojoPin, OUTPUT); 
  pinMode(ledverdePin, OUTPUT); 

  pinMode(RXLED, OUTPUT); 
  Serial.begin(9600);

  SPI.begin();    
  mfrc522.PCD_Init(); 
  mfrc522.PCD_DumpVersionToSerial();
  noTone(buzzerPin);
}

void readHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void loop() {
  // Busca nuevas tarjetas RFID en el lector
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    digitalWrite(RXLED, HIGH); 
    return;
  }

  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  
  digitalWrite(RXLED, LOW);
  Serial.print("RFID UID: ");
  readHex(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.println();

  tarjeta_admitida = 0;

  // Tarjeta RFID 1 admitida (llavero azul)
  if (mfrc522.uid.uidByte[0] == 0x6a || 
      mfrc522.uid.uidByte[1] == 0x91 || 
      mfrc522.uid.uidByte[2] == 0x4b || 
      mfrc522.uid.uidByte[3] == 0x57 ) {
        tarjeta_admitida = 1;
        Serial.print(F("Tarjeta admitida: "));
  }     

  // Tarjeta RFID 2 admitida (tarjeta blanca)
  if (mfrc522.uid.uidByte[0] == 0xdb || 
      mfrc522.uid.uidByte[1] == 0x60 || 
      mfrc522.uid.uidByte[2] == 0x94 || 
      mfrc522.uid.uidByte[3] == 0x21 ) {
        tarjeta_admitida = 1;
        Serial.print(F("Tarjeta adminida: "));
  }     

  if (tarjeta_admitida == 0) {
    digitalWrite(ledrojoPin, HIGH); // activa el led rojo
    for (int m = 400; m > 200; m = m - 10) {  
      tone(buzzerPin, m); 
      delay(15);
      noTone(buzzerPin);
    }
    Serial.println("Incorrect UID");
    delay(1000);
    digitalWrite(ledrojoPin, LOW); // desactiva el led rojo
    return;
  }
  
  if (tarjeta_admitida == 1) {
    Serial.println("conmuta1 = ");
    digitalWrite(ledverdePin, HIGH); // activa el led verde
    for (int m = 700; m < 800; m = m + 20) {  
      tone(buzzerPin, m); 
      delay(20);
      noTone(buzzerPin);
    }
    digitalWrite(ledverdePin, LOW); // desactiva el led verde

    conmuta1 = 1;  // Activado=0   Desactivado=1
    conmuta2 = 1;
    conmuta3 = 1;
    conmuta4 = 1;
    conmuta5 = 1;
    conmuta6 = 1;
    conmuta7 = 1;

    conmuta1 = digitalRead(conmuta1Pin);
    conmuta2 = digitalRead(conmuta2Pin);
    conmuta3 = digitalRead(conmuta3Pin);
    conmuta4 = digitalRead(conmuta4Pin);
    conmuta5 = digitalRead(conmuta5Pin);
    conmuta6 = digitalRead(conmuta6Pin);
    conmuta7 = digitalRead(conmuta7Pin);

    Serial.println(" ");
    Serial.print("conmuta1 = ");
    Serial.println(conmuta1);
    Serial.print("conmuta2 = ");
    Serial.println(conmuta2);
    Serial.print("conmuta3 = ");
    Serial.println(conmuta3);
    Serial.print("conmuta4 = ");
    Serial.println(conmuta4);
    Serial.print("conmuta5 = ");
    Serial.println(conmuta5);
    Serial.print("conmuta6 = ");
    Serial.println(conmuta6);
    Serial.print("conmuta7 = ");
    Serial.println(conmuta7);
 
    // **************** POSICION 1 - CTRL ALT SUPR *********************
    if (conmuta1 == 0) {
        /* Esta opción hace un Windows logon en un equipo que requiere pulsar CTRL-ALT-SUPR para iniciar 
           sesión y saca avisos legales que hay que pasar pulsando INTRO así que pulsa las siguientes teclas:
             INTRO
             CTRL-ALT-SUPR
             INTRO
             escribe el nombre de USUARIO
             TABULADOR
             escribe la CONTRASEÑA
             INTRO
             INTRO
          */
        Keyboard.begin(KeyboardLayout_es_ES);

        Keyboard.press(KEY_RETURN);
        Keyboard.release(KEY_RETURN);
        delay(2500);

        Keyboard.press(KEY_LEFT_CTRL);    // CTRL
        Keyboard.press(KEY_LEFT_ALT);     // ALT
        Keyboard.press(KEY_DELETE);       // SUPR
        
        Keyboard.release(KEY_LEFT_CTRL);  // CTRL
        Keyboard.release(KEY_LEFT_ALT);   // ALT
        Keyboard.release(KEY_DELETE);     // SUPR
        delay(2500);

        Keyboard.press(KEY_RETURN);
        Keyboard.release(KEY_RETURN);
        delay(2500);

        Keyboard.print("nombre_del_USUARIO");
        delay(1000);

        Keyboard.press(KEY_TAB);   // TAB
        Keyboard.release(KEY_TAB);  
        delay(300);

        Keyboard.print("contraseña1");
        Keyboard.flush();

        delay(300);
        Keyboard.press(KEY_RETURN);
        Keyboard.release(KEY_RETURN);
        delay(100);

        Keyboard.press(KEY_RETURN);
        Keyboard.release(KEY_RETURN);
        delay(1000);
        Keyboard.press(KEY_RETURN);
        Keyboard.release(KEY_RETURN);
        delay(1000);

        Keyboard.end();
      } 

      // **************** POSICION 2 - CONTRASEÑA WINDOWS + INTRO *********************
      if (conmuta2 == 0) {
        Keyboard.begin(KeyboardLayout_es_ES);
        Keyboard.print("contraseña1");
        Keyboard.press(KEY_RETURN);
        Keyboard.release(KEY_RETURN);
        delay(100);
        Keyboard.end();
      }

      // **************** POSICION 3 - CONTRASEÑA WINDOWS (SIN PULSAR LUEGO INTRO) *********************
      if (conmuta3 == 0) {
        Keyboard.begin(KeyboardLayout_es_ES);
        Keyboard.print("contraseña1");
        Keyboard.end();
      }

      // **************** POSICION 4 - CONTRASEÑA USO CERTIFICADO DIGITAL *********************
      if (conmuta4 == 0) {
        Keyboard.begin(KeyboardLayout_es_ES);

        Keyboard.press(108);  // escribe el carácter: "l"
        Keyboard.release(108);
        delay(20);

        //  ---

        Keyboard.press(50);   // escribe el carácter: "2"
        Keyboard.release(50);
        delay(20);

        Keyboard.end();
      }  

      // **************** POSICION 5 - CONTRASEÑA 2 *********************
      if (conmuta5 == 0) {
        Keyboard.begin(KeyboardLayout_es_ES);
        Keyboard.print("contraseña2");
        Keyboard.end();
      }  

      // **************** POSICION 6 - CONTRASEÑA 3 *********************
      if (conmuta6 == 0) {
        Keyboard.begin(KeyboardLayout_es_ES);
        Keyboard.print("contraseña3");
        Keyboard.end();
      }  

      // **************** POSICION 7 - MUEVE EL RATON CADA MINUTO *********************
      // Esta opción se encarga de hacer un movimiento del ratón cada 60 segundos para evitar
      // que el equipo entre en ahorro de energia
      if (conmuta7 == 0) {
        Mouse.begin();
        // Repite mover el ratón hasta que se haga un reset
        while(true) {
          Mouse.move(20, 0, 0);
          delay(00);
          Mouse.move(0, 20, 0);
          delay(200);
          Mouse.move(-20, 0, 0);
          delay(200);
          Mouse.move(0, -20, 0);
          delay(60 * 1000ul);  // Espera 1 minuto para volver a mover el ratón
        }  
        Mouse.end();
      }  

    delay(20);
  }
  else {
    Serial.print(F("Tarjeta no autorizada: "));
    }
  
  digitalWrite(RXLED, HIGH);
  delay(200);                                          
}


// Envía al puerto serie un array de bytes como valores hexadecimales
void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

// Envía al puerto serie un array de bytes como valores decimales
void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], DEC);
  }
}

Pulsa aquí para descargar el código "teclamicro.ino"