Detector de temperatura PC python/Arduino

Introducción

Este proyecto te permite crear una estación de monitoreo y alarma física para la temperatura de tu ordenador. Utilizaremos un script de Python para leer (o simular) la temperatura de la CPU en tiempo real. Este script envía comandos simples (como ‘B’, ‘M’, o ‘A’) a una placa Arduino a través del puerto serie (USB). El Arduino, a su vez, interpreta estos comandos para activar un sistema de alerta visual (LEDs de colores) y sonoro (un buzzer).

Es una forma innovadora y clara de tener un control externo sobre la «salud» de tu PC, ideal para gamers o al realizar tareas pesadas que pueden causar sobrecalentamiento. Es un proyecto perfecto para aprender sobre la comunicación serial entre un programa de PC (Python) y el hardware (Arduino).

Materiales Necesarios

  • Placa Arduino (Cualquier modelo estándar, como el Arduino UNO, Nano, o similar).

  • Un ordenador (PC o portátil) con Python instalado y la capacidad de instalar librerías (como pyserial).

  • 3 LEDs de colores (Específicamente: 1 Verde, 1 Amarillo, 1 Rojo).

  • 1 Buzzer (Zumbador), preferiblemente un modelo «activo» que suena al recibir voltaje.

  • 3 Resistencias de 220Ω (una para cada LED).

  • Protoboard (Placa de pruebas).

  • Cables Jumper (tipo macho-macho).

  • Cable USB (adecuado para tu placa Arduino, para conectarla al PC).

Esquema de Montaje

El montaje se centra en conectar los componentes de salida (LEDs y buzzer) a los pines digitales del Arduino.

  • Cada uno de los 3 LEDs se conecta a un pin digital diferente (ej. pines 10, 11 y 12).

  • Cada LED debe tener su resistencia de 220Ω conectada en serie (generalmente en la pata larga, ánodo) para limitar la corriente.

  • El buzzer se conecta a otro pin digital (ej. pin 9).

  • Todos los componentes (los 3 LEDs y el buzzer) deben compartir una conexión a tierra, conectando sus pines negativos (cátodos o patas cortas) al pin GND del Arduino.

Conexiones:

El circuito es muy directo. Todos los componentes se alimentan y controlan directamente desde el Arduino.

    • LED Verde (Nivel Seguro):

      • Ánodo (pata larga) → Resistencia de 220Ω → Pin 10 del Arduino.

      • Cátodo (pata corta) → Pin GND del Arduino.

    • LED Amarillo (Nivel Advertencia):

      • Ánodo (pata larga) → Resistencia de 220Ω → Pin 11 del Arduino.

      • Cátodo (pata corta) → Pin GND del Arduino.

    • LED Rojo (Nivel Peligro):

      • Ánodo (pata larga) → Resistencia de 220Ω → Pin 12 del Arduino.

      • Cátodo (pata corta) → Pin GND del Arduino.

    • Buzzer (Alarma de Peligro):

      • Pin Positivo (+) (o pata larga) → Pin 9 del Arduino.

      • Pin Negativo (-) (o pata corta) → Pin GND del Arduino.

    • Conexión Principal:

      • Cable USB → Conecta el Arduino al puerto USB de tu ordenador (este cable sirve tanto para la alimentación como para la comunicación de datos desde Python).

Código de Arduino

// Pines para los LEDs
const int pinLedVerde = 10;
const int pinLedAmarillo = 11;
const int pinLedRojo = 12;

// Pin para el buzzer (reemplaza al motor)
const int pinBuzzer = 9;

void setup() {
  // Inicia la comunicación serie (clave)
  Serial.begin(9600); 
  
  pinMode(pinLedVerde, OUTPUT);
  pinMode(pinLedAmarillo, OUTPUT);
  pinMode(pinLedRojo, OUTPUT);
  pinMode(pinBuzzer, OUTPUT); // Configura el pin del buzzer

  // Asegurarse que todo empieza apagado
  apagarTodo();
}

void loop() {
  // Revisa si Python ha enviado algún dato
  if (Serial.available() > 0) {
    // Lee el carácter de comando
    char comando = Serial.read();

    if (comando == 'B') { // 'B' de Baja
      apagarTodo();
      digitalWrite(pinLedVerde, HIGH);
    } 
    else if (comando == 'M') { // 'M' de Media
      apagarTodo();
      digitalWrite(pinLedAmarillo, HIGH);
    }
    else if (comando == 'A') { // 'A' de ALARMA
      apagarTodo();
      digitalWrite(pinLedRojo, HIGH);
      digitalWrite(pinBuzzer, HIGH); // ¡Activa la alarma!
    }
    else if (comando == 'O') { // 'O' de Off
      apagarTodo();
    }
  }
}

// Función para apagar todo
void apagarTodo() {
  digitalWrite(pinLedVerde, LOW);
  digitalWrite(pinLedAmarillo, LOW);
  digitalWrite(pinLedRojo, LOW);
  digitalWrite(pinBuzzer, LOW); // Apaga el buzzer
} 

Código de Python

  1. Necesitas tener Python instalado en tu ordenador.

  2. Necesitas instalar la biblioteca pyserial. Puedes hacerlo abriendo una terminal o símbolo del sistema y ejecutando: pip install pyserial

import serial
import time

# --- CONFIGURACIÓN DE UMBRALES (Igual que antes) ---
UMBRAL_MEDIO = 60.0  # Grados C para pasar a Amarillo
UMBRAL_ALTO = 80.0   # Grados C para activar la Alarma (Rojo + Buzzer)

# --- TEMPERATURAS FALSAS PARA LA DEMO ---
# Esta lista simula una subida de temperatura, una alarma, y una bajada.
# Puedes cambiar los números como quieras.
lista_de_temperaturas = [
    45.0,  # Normal (Verde)
    55.0,  # Normal (Verde)
    65.0,  # Advertencia (Amarillo)
    75.0,  # Advertencia (Amarillo)
    81.0,  # ¡ALARMA! (Rojo + Buzzer)
    85.0,  # ¡ALARMA! (Rojo + Buzzer)
    72.0,  # Baja a Advertencia (Amarillo)
    50.0   # Vuelve a Normal (Verde)
]

try:
    # IMPORTANTE: Conéctate al COM5
    arduino = serial.Serial(port='COM5', baudrate=9600, timeout=1)
    print("Conectado a Arduino en COM5. ¡INICIANDO SIMULACIÓN!")
    print("Esto demostrará la comunicación Python -> Arduino.")
    time.sleep(2) 

    indice = 0
    # Bucle infinito para que la demo se repita
    while True:
        
        # 1. Obtiene la temperatura falsa de nuestra lista
        temp = lista_de_temperaturas[indice]
        
        # 2. Lógica de decisión (exactamente igual que antes)
        if temp >= UMBRAL_ALTO:
            print(f"[SIMULADO] ¡ALARMA! Temperatura: {temp}°C")
            arduino.write(b'A') # 'A' de Alarma (Rojo + Buzzer)
            
        elif temp >= UMBRAL_MEDIO:
            print(f"[SIMULADO] Advertencia. Temperatura: {temp}°C")
            arduino.write(b'M') # 'M' de Media (Amarillo)
            
        else:
            print(f"[SIMULADO] Normal. Temperatura: {temp}°C")
            arduino.write(b'B') # 'B' de Baja (Verde)
            
        # 3. Avanza al siguiente número de la lista
        indice = indice + 1
        
        # 4. Si llega al final de la lista, vuelve al principio
        if indice >= len(lista_de_temperaturas):
            indice = 0
            print("--- Reiniciando simulación ---")
            
        # Espera 3 segundos antes de mostrar la siguiente temperatura
        time.sleep(3) 

except serial.SerialException:
    print(f"Error: No se pudo conectar a COM5.")
    print("Asegúrate de que el Arduino esté conectado y el IDE cerrado.")
except KeyboardInterrupt:
    print("\nDeteniendo simulación.")
finally:
    # Al salir, apaga todo en el Arduino
    if 'arduino' in locals() and arduino.is_open:
        arduino.write(b'O') # 'O' de Off
        arduino.close()
        print("Conexión cerrada.")

Explicación del código

1. El Script de Python (El Emisor)

  • Biblioteca serial (PySerial): Esta es la biblioteca clave. Permite a Python acceder a los puertos COM (puertos serie) del ordenador.

    • arduino = serial.Serial(port='COM5', baudrate=9600, ...): Esta línea es la que abre la conexión con tu placa Arduino, especificando el puerto (el que tú usas) y la velocidad de comunicación (9600 baudios), que debe ser idéntica a la configurada en el Arduino.

  • Biblioteca time: Se usa simplemente para time.sleep(3), que crea una pausa de 3 segundos entre cada envío de datos.

  • Lógica del Script (Simulación): En lugar de leer un sensor real, el script tiene una lista predefinida: lista_de_temperaturas = [45.0, 55.0, 65.0, ...].

    • Un bucle while True: recorre esta lista continuamente.

    • Una estructura if...elif...else compara la temperatura (falsa) actual de la lista con las variables UMBRAL_MEDIO y UMBRAL_ALTO.

    • Acción Clave: Dependiendo de la temperatura, Python envía un único byte al Arduino. Por ejemplo, arduino.write(b'A'). La b antes de la letra indica que se envía como un byte (datos crudos) y no como un texto normal.

  • Bloque try...except...finally:

    • El try: envuelve el código principal para que, si falla (por ejemplo, si el Arduino está desconectado o el COM5 está ocupado por el IDE de Arduino), el programa no se bloquee.

    • El except serial.SerialException: captura ese error y te avisa.

    • El finally: se asegura de que, si el script se cierra (incluso con Ctrl+C), se ejecute arduino.close(), liberando el puerto COM5.

2. El Código de Arduino (El Receptor)

  • Comunicación Serial (Integrada): No se necesitan bibliotecas especiales; Arduino lo trae incorporado.

    • Serial.begin(9600): Inicia la comunicación serie en el Arduino, asegurándose de que «escuche» a la misma velocidad (9600 baudios) a la que Python «habla».

  • Configuración (setup()):

    • Se usan pinMode(PIN, OUTPUT) para todos los pines de los LEDs (10, 11, 12) y el pin del buzzer (9), indicando que el Arduino enviará voltaje hacia ellos.

  • Lógica del loop(): El Arduino se dedica a escuchar pasivamente.

    • if (Serial.available() > 0): Esta es la función más importante. Constantemente pregunta: «¿Ha llegado algún dato (byte) desde el PC?».

    • char comando = Serial.read();: Si la respuesta es sí, esta línea lee ese byte que llegó (la ‘A’, ‘M’, ‘B’ u ‘O’) y lo guarda en la variable comando.

    • Estructura if...else if...: El código comprueba el valor de la variable comando.

    • if (comando == 'A'): Si el comando es ‘A’ (Alarma), apaga todo y luego enciende el LED rojo y el buzzer usando digitalWrite(pinLedRojo, HIGH); y digitalWrite(pinBuzzer, HIGH);.

    • apagarTodo(): Es una función auxiliar que creamos para asegurarnos de que todos los LEDs y el buzzer estén apagados (LOW) antes de encender el correcto. Esto evita que los LEDs se queden encendidos de estados anteriores.

Este proyecto es una excelente demostración de cómo combinar un script de PC (Python) con la electrónica (Arduino) para crear un sistema de monitoreo interactivo y en tiempo real.

 

Material

Aquí os dejamos los materiales que nosotros compramos cuando empezamos. Si quieres darnos una pequeña ayuda puedes comprar desde este link. Gracias por leernos!