Nota

¡Hola, bienvenido a la comunidad de entusiastas de SunFounder Raspberry Pi, Arduino y ESP32 en Facebook! Profundiza en Raspberry Pi, Arduino y ESP32 con otros entusiastas.

¿Por qué unirse?

  • Soporte experto: Resuelve problemas postventa y desafíos técnicos con la ayuda de nuestra comunidad y equipo.

  • Aprende y comparte: Intercambia consejos y tutoriales para mejorar tus habilidades.

  • Vistas previas exclusivas: Obtén acceso anticipado a nuevos anuncios de productos y adelantos.

  • Descuentos especiales: Disfruta de descuentos exclusivos en nuestros productos más nuevos.

  • Promociones y sorteos festivos: Participa en sorteos y promociones de temporada.

👉 ¿Listo para explorar y crear con nosotros? Haz clic en [Aquí] y únete hoy mismo.

4.1.10 Monitor de sobrecalentamiento (MCP3008)

Nota

../_images/mcp3008_and_adc0834.jpg

Dependiendo de la versión de tu kit, identifica si tienes ADC0834 o MCP3008 y continúa con la sección correspondiente.

Introducción

Puede que desees crear un dispositivo de monitoreo de sobrecalentamiento que se aplique a diversas situaciones, por ejemplo, en una fábrica, donde queremos tener una alarma y el apagado automático de la máquina cuando hay un sobrecalentamiento del circuito. En este proyecto, usaremos un termistor, joystick, zumbador, LED y LCD para crear un dispositivo inteligente de monitoreo de temperatura cuyo umbral es ajustable.

Componentes requeridos

En este proyecto, necesitamos los siguientes componentes.

../_images/list2_Overheat_Monitor1.png

Es definitivamente conveniente comprar un kit completo, aquí está el enlace:

Nombre

ELEMENTOS EN ESTE KIT

ENLACE

Kit Raphael

337

Raphael Kit

También puedes comprarlos por separado en los enlaces de abajo.

INTRODUCCIÓN DEL COMPONENTE

ENLACE DE COMPRA

Placa de Extensión GPIO

COMPRAR

Protoboard

COMPRAR

Cables de Puente

COMPRAR

Resistor

COMPRAR

LED

COMPRAR

Módulo Joystick

-

MCP3008

-

Transistor

COMPRAR

I2C LCD1602

COMPRAR

Termistor

COMPRAR

Zumbador

-

Diagrama esquemático

Nombre T-Board

físico

wiringPi

BCM

SPICE0

Pin 24

10

8

SPIMOSI

Pin 19

12

10

SPIMISO

Pin 21

13

9

SPISCLK

Pin 23

14

11

GPIO22

Pin 15

3

22

GPIO23

Pin 16

4

23

GPIO24

Pin 18

5

24

SDA1

Pin 3

SCL1

Pin 5

../_images/schematic_over_monitor_mcp30081.png

Procedimientos experimentales

Paso 1: Construye el circuito.

../_images/july24_3.1.8_overheat_monitor_mcp30081.png

Paso 2: Configura la interfaz SPI e instala la librería spidev (ver Configuración de SPI para instrucciones detalladas). Si ya completaste estos pasos, puedes omitirlos.

Paso 3: Ve a la carpeta del código.

cd ~/raphael-kit/python-pi5

Paso 4: Ejecuta el archivo ejecutable.

sudo python3 4.1.13-2_OverheatMonitor_zero.py

Cuando el código se ejecuta, la temperatura actual y el umbral de alta temperatura 40 se muestran en el I2C LCD1602. Si la temperatura actual es mayor que el umbral, el zumbador y el LED se activan para alertarte.

Joystick aquí se utiliza para ajustar el umbral de alta temperatura. Moviendo el Joystick en la dirección de los ejes X e Y se puede ajustar (subir o bajar) el umbral de temperatura actual. Presionar el Joystick una vez más restablece el umbral a su valor inicial.

Nota

  • Si obtienes el error FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1', debes consultar Configuración de I²C para habilitar el I2C.

  • Si obtienes el error ModuleNotFoundError: No module named 'smbus2', ejecuta sudo apt install python3-smbus2.

  • Si aparece el error OSError: [Errno 121] Remote I/O error, significa que el módulo está mal cableado o dañado.

  • Si el código y el cableado están correctos, pero la LCD no muestra contenido, puedes ajustar el potenciómetro en la parte posterior para aumentar el contraste.

Advertencia

Si aparece el error RuntimeError: Cannot determine SOC peripheral base address, consulta Si «gpiozero» no funciona.

Código

Nota

Puedes Modificar/Restablecer/Copiar/Ejecutar/Detener el código a continuación. Pero antes debes ir a la ruta del código fuente como raphael-kit/python. Después de modificar el código, puedes ejecutarlo directamente para ver el efecto.

#!/usr/bin/env python3

import LCD1602
from gpiozero import LED, Buzzer, Button
import spidev
import time
import math

# Inicializar botón del joystick, zumbador y LED
Joy_BtnPin = Button(22)  # GPIO22, Pin15
buzzPin = Buzzer(23)     # GPIO23, Pin16
ledPin = LED(24)         # GPIO24, Pin18

# Establecer umbral inicial de temperatura alta
upperTem = 40

# Inicializar SPI para MCP3008 (Bus 0, CE0 -> GPIO8 / Pin24)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000  # 1 MHz

# Inicializar LCD (dirección I2C 0x27, retroiluminación activada)
LCD1602.init(0x27, 1)

def read_adc(channel):
    """
    Leer valor analógico del MCP3008 (0–7)
    """
    if channel < 0 or channel > 7:
        return -1
    adc = spi.xfer2([1, (8 + channel) << 4, 0])
    value = ((adc[1] & 0x03) << 8) | adc[2]
    return value

def get_joystick_value():
    """
    Lee los valores del joystick y devuelve un cambio según su posición.
    """
    x_val = read_adc(1)
    y_val = read_adc(2)
    if x_val > 800:
        return 1
    elif x_val < 200:
        return -1
    elif y_val > 800:
        return -10
    elif y_val < 200:
        return 10
    else:
        return 0

def upper_tem_setting():
    """
    Ajusta y muestra el umbral de temperatura alta en la LCD.
    """
    global upperTem
    LCD1602.write(0, 0, 'Upper Adjust: ')
    change = int(get_joystick_value())
    upperTem += change
    strUpperTem = str(upperTem)
    LCD1602.write(0, 1, strUpperTem)
    LCD1602.write(len(strUpperTem), 1, '              ')
    time.sleep(0.1)

def temperature():
    """
    Lee la temperatura actual del sensor y la devuelve en grados Celsius.
    """
    analogVal = read_adc(0)
    Vr = 3.3 * analogVal / 1023.0  # Voltaje en la resistencia fija
    if Vr == 0:
        return 0  # Evitar división por cero
    Rt = 10000.0 * Vr / (3.3 - Vr)  # Fórmula ajustada
    temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
    Cel = temp - 273.15
    return round(Cel, 2)

def monitoring_temp():
    """
    Monitorea y muestra la temperatura actual y el umbral.
    Activa el zumbador y el LED si la temperatura supera el límite.
    """
    global upperTem
    Cel = temperature()
    LCD1602.write(0, 0, 'Temp: ')
    LCD1602.write(0, 1, 'Upper: ')
    LCD1602.write(6, 0, str(Cel))
    LCD1602.write(7, 1, str(upperTem))
    time.sleep(0.1)
    if Cel >= upperTem:
        buzzPin.on()
        ledPin.on()
    else:
        buzzPin.off()
        ledPin.off()

# Bucle principal de ejecución
try:
    lastState = 1
    stage = 0
    while True:
        currentState = Joy_BtnPin.value
        if currentState == 1 and lastState == 0:
            stage = (stage + 1) % 2
            time.sleep(0.1)
            LCD1602.clear()
        lastState = currentState
        if stage == 1:
            upper_tem_setting()
        else:
            monitoring_temp()
except KeyboardInterrupt:
    LCD1602.clear()
    spi.close()

Explicación del código

  1. Se importan las librerías necesarias. LCD1602 es para mostrar en la LCD vía I2C, gpiozero proporciona soporte para LED, zumbador y botón, spidev se usa para comunicar con el ADC MCP3008, y time y math son bibliotecas estándar para retrasos y cálculos de temperatura.

    #!/usr/bin/env python3
    
    import LCD1602
    from gpiozero import LED, Buzzer, Button
    import spidev
    import time
    import math
    
  2. Inicializa los componentes de hardware conectados a los pines GPIO:

    • Button(22) conectado al botón del joystick.

    • Buzzer(23) y LED(24) sirven como indicadores de alta temperatura.

    Joy_BtnPin = Button(22)  # GPIO22, Pin15
    buzzPin = Buzzer(23)     # GPIO23, Pin16
    ledPin = LED(24)         # GPIO24, Pin18
    
  3. Se establece el umbral de temperatura predeterminado y se inicializan tanto SPI para MCP3008 como la pantalla LCD1602.

    upperTem = 40
    
    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1000000
    
    LCD1602.init(0x27, 1)
    
  4. La función read_adc lee el valor analógico de un canal especificado (0–7) del MCP3008 usando el protocolo SPI y devuelve un valor de 10 bits.

    def read_adc(channel):
        if channel < 0 or channel > 7:
            return -1
        adc = spi.xfer2([1, (8 + channel) << 4, 0])
        value = ((adc[1] & 0x03) << 8) | adc[2]
        return value
    
  5. La posición del joystick se evalúa leyendo los canales 1 y 2 del MCP3008. Dependiendo de la dirección X o Y, se devuelven diferentes valores para ajustar el umbral.

    def get_joystick_value():
        x_val = read_adc(1)
        y_val = read_adc(2)
        if x_val > 800:
            return 1
        elif x_val < 200:
            return -1
        elif y_val > 800:
            return -10
        elif y_val < 200:
            return 10
        else:
            return 0
    
  6. upper_tem_setting ajusta el umbral de temperatura usando el joystick. Muestra el valor actual del umbral en la LCD y asegura un formato limpio.

    def upper_tem_setting():
        global upperTem
        LCD1602.write(0, 0, 'Upper Adjust: ')
        change = int(get_joystick_value())
        upperTem += change
        strUpperTem = str(upperTem)
        LCD1602.write(0, 1, strUpperTem)
        LCD1602.write(len(strUpperTem), 1, '              ')
        time.sleep(0.1)
    
  7. La función temperature lee el valor analógico del canal 0 del MCP3008 (conectado a un termistor), calcula el voltaje, resistencia y finalmente la temperatura en Celsius usando la aproximación de Steinhart–Hart.

    def temperature():
        """
        Reads the current temperature from the sensor and returns it in Celsius.
        """
        analogVal = read_adc(0)
        Vr = 3.3 * analogVal / 1023.0  # Voltage across the fixed resistor
        if Vr == 0:
            return 0  # Prevent division by zero
        Rt = 10000.0 * Vr / (3.3 - Vr)  # Adjusted formula: thermistor voltage is (3.3 - Vr)
        temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
        Cel = temp - 273.15
        return round(Cel, 2)
    
  8. monitoring_temp lee continuamente la temperatura actual, la compara con el umbral superior y muestra ambos valores en la LCD. Si la temperatura excede el umbral, el zumbador y el LED se encienden.

    def monitoring_temp():
        global upperTem
        Cel = temperature()
        LCD1602.write(0, 0, 'Temp: ')
        LCD1602.write(0, 1, 'Upper: ')
        LCD1602.write(6, 0, str(Cel))
        LCD1602.write(7, 1, str(upperTem))
        time.sleep(0.1)
        if Cel >= upperTem:
            buzzPin.on()
            ledPin.on()
        else:
            buzzPin.off()
            ledPin.off()
    
  9. El bucle principal alterna entre modo de configuración y modo de monitoreo usando el botón del joystick. Una pulsación alterna el modo. En modo de configuración se ajusta el umbral; en modo de monitoreo, se revisa continuamente la temperatura.

    try:
        lastState = 1
        stage = 0
        while True:
            currentState = Joy_BtnPin.value
            if currentState == 1 and lastState == 0:
                stage = (stage + 1) % 2
                time.sleep(0.1)
                LCD1602.clear()
            lastState = currentState
            if stage == 1:
                upper_tem_setting()
            else:
                monitoring_temp()
    
  10. Al salir con interrupción por teclado, la pantalla LCD se limpia y la comunicación SPI se cierra correctamente.

    except KeyboardInterrupt:
        LCD1602.clear()
        spi.close()