Capturar Teclas del Usuario Mediante Python y Arduino

En este Laboratorio vamos a realizar la captura de las teclas apretadas por el usuario mediante Python, la enviaremos hacia Arduino mediante comunicación serial y presentaremos los datos mediante un Display LCD 16×2.
AVISO IMPORTANTE:
Capturar las teclas del usuario sin su conocimiento puede ser considerado comportamiento malicioso (keylogger). Esta funcionalidad está permitida solo con fines educativos y en entornos controlados.
Paso 1
Ensamblar el circuito en el Protoboard de acuerdo al diseño presentado en clase. Tener mucho cuidado con la conexión de cables para evitar dañar el Display LCD 16×2. Las resistencias son de 220 Ohmios; sin embargo, en la implementación física puede ser necesario reemplazarlas por resistencias de 1000 ohmios.

Paso 2
Subir al Arduino el código que recibirá los datos desde Python mediante comunicación serial y mostrará la información en pantalla.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
String linea1 = "";
String linea2 = "";
bool recibidoLinea1 = false;
void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
lcd.print("Iniciando...");
delay(1000);
lcd.clear();
}
void loop() {
static String input = "";
// Leer línea desde Serial
while (Serial.available()) {
char c = Serial.read();
if (c == '\n') {
if (!recibidoLinea1) {
linea1 = input;
recibidoLinea1 = true;
} else {
linea2 = input;
}
input = "";
} else {
input += c;
}
}
// Scroll automático para ambas líneas
scrollLCD(linea1, linea2);
}
void scrollLCD(String texto1, String texto2) {
static unsigned long ultimaActualizacion = 0;
static int offset1 = 0;
static int offset2 = 0;
if (millis() - ultimaActualizacion >= 500) {
lcd.setCursor(0, 0);
lcd.print(ajustarScroll(texto1, offset1));
lcd.setCursor(0, 1);
lcd.print(ajustarScroll(texto2, offset2));
offset1 = (offset1 + 1) % (texto1.length() + 1);
offset2 = (offset2 + 1) % (texto2.length() + 1);
ultimaActualizacion = millis();
}
}
String ajustarScroll(String texto, int offset) {
texto += " "; // relleno para evitar corte abrupto
if (offset > texto.length() - 16) offset = 0;
return texto.substring(offset, offset + 16);
}
Paso 3
Preparar el Script en Python, el cual capturará los datos del sistema: Hora, Usuario, Sistema Operativo y teclas oprimidas por el usuario para ser enviadas mediante la librería PySerial al Arduino.
Requisitos y Librerías:
- Pyhton 3.12 (Recomendado)
- pip install keyboard pyserial
- pip install requests
Crear el Script en Python y no olvidar cambiar el puerto COM8 con el valor de tu computador.
import serial
import time
import os
import platform
import getpass
import keyboard
from datetime import datetime
puerto_serial = "COM8" # Cambiar según corresponda
baudrate = 9600
def obtener_info_sistema():
usuario = getpass.getuser()
sistema = platform.system()
hora = datetime.now().strftime("%H:%M")
return f"{hora} {usuario} {sistema}"
def enviar_serial(ser, linea1, linea2):
ser.write((linea1 + "\n").encode())
time.sleep(0.2)
ser.write((linea2 + "\n").encode())
def limpiar_y_reiniciar(ser):
print("Reiniciando sistema...")
ser.write(("LIMPIANDO...\n").encode())
time.sleep(2)
ser.reset_input_buffer()
ser.reset_output_buffer()
if __name__ == "__main__":
while True:
try:
with serial.Serial(puerto_serial, baudrate, timeout=1) as ser:
time.sleep(2)
# Enviar datos del sistema al iniciar
info = obtener_info_sistema()
ser.write((info + "\n").encode())
print("Info enviada:", info)
buffer = ""
while True:
if keyboard.is_pressed('esc'):
print("Finalizando por ESC...")
break
event = keyboard.read_event()
if event.event_type == keyboard.KEY_DOWN:
tecla = event.name
if tecla == "space":
tecla = " "
elif len(tecla) > 1:
tecla = f"<{tecla}>"
buffer += tecla
# Limitar a últimos 32 caracteres para scroll
buffer_scroll = buffer[-32:]
ser.write((buffer_scroll + "\n").encode())
print("Enviado:", buffer_scroll)
# Si se alcanzan 100 caracteres: reiniciar
if len(buffer) >= 100:
limpiar_y_reiniciar(ser)
break # sale del loop y reinicia desde cero
except Exception as e:
print("ERROR:", e)
time.sleep(3)
Paso 4
Conectar el Arduino al PC

Ejecutar el Script en Python

Resultado Final
El Display LCD mostrará los datos capturados del teclado, la hora, el usuario y el sistema operativo. Asi mismo reiniciará su buffer por cada 100 caracteres enviados.

Entregable a presentar
Mejorar el proyecto para que el LCD muestre también la dirección IP del equipo y el Hostname en la primera línea sin perder la captura del teclado en la segunda línea.
Presentar su informe por correo al instructor detallando Integrantes, Materiales, Procedimiento y el código de Arduino y Pyhton explicado.
