.. note::
¡Hola, bienvenido a la Comunidad de Entusiastas de SunFounder Raspberry Pi & Arduino & ESP32 en Facebook! Sumérgete en el mundo de Raspberry Pi, Arduino y ESP32 junto a otros entusiastas.
**¿Por qué unirse?**
- **Soporte experto**: Resuelve problemas postventa y desafíos técnicos con la ayuda de nuestra comunidad y equipo.
- **Aprender y compartir**: Intercambia consejos y tutoriales para mejorar tus habilidades.
- **Preestrenos exclusivos**: Obtén acceso anticipado a nuevos anuncios de productos y adelantos.
- **Descuentos especiales**: Disfruta de descuentos exclusivos en nuestros productos más recientes.
- **Promociones y sorteos festivos**: Participa en sorteos y promociones especiales de temporada.
👉 ¿Listo para explorar y crear con nosotros? Haz clic en [|link_sf_facebook|] y únete hoy mismo.
.. _4.1.13_py_mcp3008:
4.1.13 Monitor de Sobrecalentamiento (MCP3008)
==============================================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Dependiendo de la versión de tu kit, identifica si tienes **ADC0834** o **MCP3008** y procede con la sección correspondiente.
Introducción
------------
Puede que desees crear un dispositivo de monitoreo de sobrecalentamiento que se aplique a varias situaciones, por ejemplo, en una fábrica, si queremos tener una alarma y el apagado automático oportuno de la máquina cuando hay un sobrecalentamiento del circuito.
En este proyecto, utilizaremos un termistor, un joystick, un zumbador, un LED y una pantalla LCD para hacer un dispositivo inteligente de monitoreo de temperatura cuyo umbral sea ajustable.
Componentes requeridos
----------------------
En este proyecto, necesitamos los siguientes componentes.
.. image:: ../img/list2_Overheat_Monitor.png
:width: 800
:align: center
Es definitivamente conveniente comprar un kit completo, aquí tienes el enlace:
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - Nombre
- ELEMENTOS EN ESTE KIT
- ENLACE
* - Kit Raphael
- 337
- |link_Raphael_kit|
También puedes comprarlos por separado en los siguientes enlaces.
.. list-table::
:widths: 30 20
:header-rows: 1
* - INTRODUCCIÓN DEL COMPONENTE
- ENLACE DE COMPRA
* - :ref:`cpn_gpio_board`
- |link_gpio_board_buy|
* - :ref:`cpn_breadboard`
- |link_breadboard_buy|
* - :ref:`cpn_wires`
- |link_wires_buy|
* - :ref:`cpn_resistor`
- |link_resistor_buy|
* - :ref:`cpn_led`
- |link_led_buy|
* - :ref:`cpn_joystick`
- \-
* - :ref:`cpn_mcp3008`
- \-
* - :ref:`cpn_transistor`
- |link_transistor_buy|
* - :ref:`cpn_i2c_lcd`
- |link_i2clcd1602_buy|
* - :ref:`cpn_thermistor`
- |link_thermistor_buy|
* - :ref:`cpn_buzzer`
- \-
Diagrama esquemático
--------------------
.. list-table::
:header-rows: 1
* - Nombre
- T-Board
- 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
-
-
.. image:: ../img/schematic_over_monitor_mcp3008.png
:align: center
Procedimientos experimentales
-----------------------------
**Paso 1:** Construye el circuito.
.. image:: ../img/july24_3.1.8_overheat_monitor_mcp3008.png
**Paso 2:** Configura la interfaz SPI e instala la librería ``spidev`` (consulta :ref:`spi_configuration` para instrucciones detalladas).
Si ya has completado estos pasos, puedes omitirlos.
**Paso 3:** Ve a la carpeta del código.
.. raw:: html
.. code-block::
cd ~/raphael-kit/python
**Paso 4:** Ejecuta el archivo.
.. raw:: html
.. code-block::
sudo python3 4.1.13-2_OverheatMonitor.py
Al ejecutar el código, la temperatura actual y el umbral de alta temperatura **40** se muestran en la **I2C LCD1602**.
Si la temperatura actual es mayor que el umbral, el zumbador y el LED se activan para alertarte.
El **Joystick** se utiliza para ajustar el umbral de alta temperatura. Moviendo el **Joystick** en la dirección de los ejes X y Y puedes subir o bajar el umbral de temperatura. Presiona el **Joystick** nuevamente para restablecer el umbral al valor inicial.
.. note::
* Si obtienes el error ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'``, debes consultar :ref:`i2c_config` 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 defectuoso.
* Si el código y el cableado son correctos, pero la LCD aún no muestra contenido, ajusta el potenciómetro en la parte trasera para aumentar el contraste.
.. warning::
Si aparece el error ``RuntimeError: Cannot determine SOC peripheral base address``, por favor consulta :ref:`faq_soc`
Código
------
.. note::
Puedes **Modificar/Restablecer/Copiar/Ejecutar/Detener** el siguiente código.
Pero antes de eso, 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.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
import math
import LCD1602
# Definiciones de pines GPIO
JOY_BTN_PIN = 22 # Botón
BUZZER_PIN = 23 # Zumbador
LED_PIN = 24 # LED
# Inicialización de GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(JOY_BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUZZER_PIN, GPIO.OUT)
GPIO.setup(LED_PIN, GPIO.OUT)
# Umbral inicial de temperatura
upperTem = 40
# Inicializar SPI para MCP3008
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000 # 1 MHz
# Inicializar LCD1602
LCD1602.init(0x27, 1)
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
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
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)
def temperature():
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0
if Vr == 0:
return 0
Rt = 10000.0 * (3.3 - Vr) / Vr
tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
Cel = tempK - 273.15
return round(Cel, 2)
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:
GPIO.output(BUZZER_PIN, GPIO.HIGH)
GPIO.output(LED_PIN, GPIO.HIGH)
else:
GPIO.output(BUZZER_PIN, GPIO.LOW)
GPIO.output(LED_PIN, GPIO.LOW)
try:
lastState = GPIO.input(JOY_BTN_PIN)
stage = 0
while True:
currentState = GPIO.input(JOY_BTN_PIN)
if currentState == GPIO.HIGH and lastState == GPIO.LOW:
stage = (stage + 1) % 2
time.sleep(0.1)
LCD1602.clear()
lastState = currentState
if stage == 1:
upper_tem_setting()
else:
monitoring_temp()
except KeyboardInterrupt:
pass
finally:
LCD1602.clear()
GPIO.cleanup()
spi.close()
Explicación del código
----------------------
1. **Importación de librerías**
Carga las librerías necesarias para controlar GPIO, SPI, LCD, retrasos y cálculos matemáticos.
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
import math
import LCD1602
2. **Configuración de pines GPIO**
Define los pines GPIO para el botón del joystick, zumbador y LED.
.. code-block:: python
JOY_BTN_PIN = 22 # Button pin
BUZZER_PIN = 23 # Buzzer pin
LED_PIN = 24 # LED pin
GPIO.setmode(GPIO.BCM)
GPIO.setup(JOY_BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUZZER_PIN, GPIO.OUT)
GPIO.setup(LED_PIN, GPIO.OUT)
3. **Inicialización de SPI y LCD**
Abre la interfaz SPI para MCP3008 y configura la pantalla LCD1602 en la dirección I2C 0x27.
.. code-block:: python
upperTem = 40
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
LCD1602.init(0x27, 1)
4. **Lectura ADC**
Lee valores analógicos de los canales 0–7 del MCP3008.
.. code-block:: python
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. **Lectura del Joystick**
Interpreta la posición del joystick para modificar el umbral.
.. code-block:: python
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. **Ajuste del umbral**
Muestra “Upper Adjust” en la pantalla y ajusta el umbral según el joystick.
.. code-block:: python
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. **Cálculo de temperatura**
Convierte el valor analógico del sensor en temperatura (°C) usando la ecuación Steinhart–Hart.
.. code-block:: python
def temperature():
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0
if Vr == 0:
return 0
Rt = 10000.0 * (3.3 - Vr) / Vr
tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
Cel = tempK - 273.15
return round(Cel, 2)
8. **Monitoreo de temperatura**
Muestra la temperatura y el umbral en la pantalla, activa el zumbador y el LED si se supera el umbral.
.. code-block:: python
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:
GPIO.output(BUZZER_PIN, GPIO.HIGH)
GPIO.output(LED_PIN, GPIO.HIGH)
else:
GPIO.output(BUZZER_PIN, GPIO.LOW)
GPIO.output(LED_PIN, GPIO.LOW)
9. **Lógica principal**
Cambia entre modo de ajuste de umbral y monitoreo al presionar el botón del joystick.
.. code-block:: python
try:
lastState = GPIO.input(JOY_BTN_PIN)
stage = 0
while True:
currentState = GPIO.input(JOY_BTN_PIN)
if currentState == GPIO.HIGH and lastState == GPIO.LOW:
stage = (stage + 1) % 2
time.sleep(0.1)
LCD1602.clear()
lastState = currentState
if stage == 1:
upper_tem_setting()
else:
monitoring_temp()
10. **Limpieza al salir**
Apaga el zumbador, limpia GPIO y cierra la interfaz SPI.
.. code-block:: python
except KeyboardInterrupt:
pass
finally:
LCD1602.clear()
GPIO.cleanup()
spi.close()