Nota
¡Hola! Bienvenido a la comunidad de entusiastas de SunFounder Raspberry Pi, Arduino y ESP32 en Facebook. Profundiza en Raspberry Pi, Arduino y ESP32 junto con otros aficionados.
¿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.
Avances exclusivos: Obtén acceso anticipado a anuncios y vistas previas de nuevos productos.
Descuentos especiales: Disfruta de descuentos exclusivos en nuestros productos más recientes.
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.
2.2.2 Termistor (MCP3008)
Nota
Dependiendo de la versión de tu kit, identifica si tienes ADC0834 o MCP3008 y sigue la sección correspondiente.
Introducción
Al igual que un fotorresistor puede detectar la luz, un termistor es un dispositivo electrónico sensible a la temperatura que puede usarse para funciones de control de temperatura, como crear una alarma de calor.
Componentes requeridos
En este proyecto, necesitamos los siguientes componentes.
Principio
Un termistor es una resistencia sensible a la temperatura que presenta un cambio preciso y predecible en su resistencia proporcional a pequeños cambios de temperatura. Cuánto cambia su resistencia depende de su composición única. Los termistores pertenecen a un grupo más grande de componentes pasivos. A diferencia de sus contrapartes activas, los dispositivos pasivos no pueden proporcionar ganancia de potencia ni amplificación a un circuito.
El termistor es un elemento sensible y existen dos tipos: coeficiente de temperatura negativo (NTC) y coeficiente de temperatura positivo (PTC). En un PTC la resistencia aumenta con la temperatura, mientras que en un NTC ocurre lo contrario. En este experimento usamos un NTC.
El principio es que la resistencia del termistor NTC cambia con la temperatura del ambiente. Cuando la temperatura sube, la resistencia del termistor disminuye. Luego, el voltaje se convierte a valores digitales mediante el adaptador A/D, y la temperatura en Celsius o Fahrenheit se calcula mediante programación.
En este experimento se usa un termistor con una resistencia de referencia de 10 kΩ a 25 °C, junto con una resistencia de pull-up de 10 kΩ.
La relación entre resistencia y temperatura es:
RT = RN expB(1/TK – 1/TN)
RT es la resistencia del termistor NTC a la temperatura TK.
RN es la resistencia del NTC a la temperatura nominal TN. Aquí, RN = 10 kΩ.
TK es la temperatura en Kelvin (K = °C + 273.15).
TN es la temperatura nominal en Kelvin (298.15 K para 25 °C).
B es la constante del material del NTC (3950 en este caso).
exp significa exponencial y su base e es ≈ 2.7.
Si despejamos, obtenemos: TK= 1 / (ln(RT/RN)/B + 1/TN)
Para Celsius: °C = TK – 273.15.
Este es un modelo empírico válido solo dentro del rango especificado.
Diagrama esquemático
Nombre en la T-Board |
Físico |
WiringPi |
BCM |
|---|---|---|---|
SPICE0 |
pin24 |
10 |
8 |
SPIMOSI |
pin19 |
12 |
10 |
SPIMISO |
pin21 |
13 |
9 |
SPISCLK |
pin23 |
14 |
11 |
Procedimiento experimental
Paso 1: Construye el circuito.
Para usuarios de C
Paso 2: Ve a la carpeta del código.
cd ~/davinci-kit-for-raspberry-pi/c/2.2.2-2/
Paso 3: Compila el código.
gcc 2.2.2_Thermistor.c -o Thermistor -lwiringPi -lm
Nota
-lm es para enlazar la librería matemática. No omitir, o dará error.
Paso 4: Ejecuta el archivo compilado.
./Thermistor
Al ejecutarse, el termistor mide la temperatura ambiente y el programa imprime el valor calculado en pantalla.
Nota
Si no funciona o aparece el error «wiringPi.h: No such file or directory», consulta Instalar y Comprobar WiringPi.
Código
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#include <math.h>
#define SPI_CHANNEL 0 // CE0
#define SPI_SPEED 1000000 // 1MHz
int read_ADC(int channel) {
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // Bit de inicio
buffer[1] = (8 + channel) << 4; // Modo unipolar + canal
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int value = ((buffer[1] & 3) << 8) | buffer[2];
return value;
}
int main(void) {
int analogVal;
double Vr, Rt, temp, cel, Fah;
if (wiringPiSetup() == -1) {
printf("¡Error al iniciar wiringPi!\n");
return 1;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("¡Error al configurar SPI!\n");
return 1;
}
while (1) {
analogVal = read_ADC(0); // Leer de CH0
// MCP3008 es ADC de 10 bits (0–1023)
Vr = 3.3 * analogVal / 1023.0; // Vref = 3.3V
Rt = 10000.0 * Vr / (3.3 - Vr); // Divisor de tensión
temp = 1 / ((log(Rt / 10000.0) / 3950.0) + (1 / (273.15 + 25.0)));
cel = temp - 273.15;
Fah = cel * 1.8 + 32;
printf("Celsius: %.2f C Fahrenheit: %.2f F\n", cel, Fah);
delay(1000);
}
return 0;
}
Explicación del código
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#include <math.h>
Estos archivos de cabecera incluyen bibliotecas para el control de GPIO (wiringPi.h), comunicación SPI (wiringPiSPI.h), operaciones de E/S estándar (stdio.h) y funciones matemáticas (math.h) en C.
#define SPI_CHANNEL 0
#define SPI_SPEED 1000000
Define constantes para el canal SPI y la velocidad de comunicación SPI. Aquí se utiliza el canal SPI 0 (CE0) y una velocidad de reloj de 1 MHz.
int read_ADC(int channel)
Esta función lee datos analógicos de un canal específico del ADC MCP3008.
buffer[0] = 1;
buffer[1] = (8 + channel) << 4;
buffer[2] = 0;
Estas líneas formatean el comando SPI de acuerdo con el protocolo del MCP3008: un bit de inicio, configuración para modo de entrada simple (single-ended) y el número de canal.
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
Transfiere el comando SPI y recibe los datos de 10 bits del ADC MCP3008.
int value = ((buffer[1] & 3) << 8) | buffer[2];
Extrae y combina el resultado de 10 bits del ADC a partir del búfer SPI devuelto.
if (wiringPiSetup() == -1) { ... }
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) { ... }
Estas líneas inicializan WiringPi y configuran el SPI. Si la inicialización falla, el programa termina.
analogVal = read_ADC(0);
Lee la señal analógica del canal 0 del MCP3008, donde está conectado el divisor de tensión del termistor.
Vr = 3.3 * analogVal / 1023.0;
Convierte el valor digital del ADC en un voltaje analógico. El rango del ADC es 0–1023 con una tensión de referencia de 3,3 V.
Rt = 10000.0 * Vr / (3.3 - Vr);
Calcula la resistencia del termistor usando la fórmula del divisor de tensión. Se asume una resistencia de 10 kΩ en serie con el termistor.
temp = 1 / ((log(Rt / 10000.0) / 3950.0) + (1 / (273.15 + 25.0)));
Usa la ecuación del parámetro B (B-parameter equation) para convertir la resistencia del termistor a temperatura en Kelvin.
T(K) = 1 / [ln(Rt/R₀)/B + 1/T₀], donde - R₀ = 10 kΩ - B = 3950 - T₀ = 25 °C = 298.15 K
cel = temp - 273.15;
Convierte la temperatura de Kelvin a grados Celsius.
Fah = cel * 1.8 + 32;
Convierte la temperatura en Celsius a Fahrenheit.
printf("Celsius: %.2f C Fahrenheit: %.2f F\n", cel, Fah);
Muestra la temperatura en Celsius y Fahrenheit en la terminal con 2 decimales de precisión.
Para usuarios de Python
Paso 2: Configura la interfaz SPI e instala spidev (ver Configuración de SPI). Si ya lo hiciste, sáltalo.
Paso 3: Ve a la carpeta del código.
cd ~/davinci-kit-for-raspberry-pi/python
Paso 4: Ejecuta el archivo.
sudo python3 2.2.2-2_thermistor.py
Al ejecutarse, el termistor mide la temperatura ambiente y muestra el valor calculado.
Advertencia
Si aparece el error RuntimeError: Cannot determine SOC peripheral base address, consulta Si gpiozero no funciona..
Código
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import spidev
import time
import math
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
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
try:
while True:
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0
Rt = 10000.0 * Vr / (3.3 - Vr)
tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
Cel = tempK - 273.15
Fah = Cel * 1.8 + 32
print('Celsius: %.2f °C Fahrenheit: %.2f °F' % (Cel, Fah))
time.sleep(0.2)
except KeyboardInterrupt:
pass
finally:
spi.close()
GPIO.cleanup()
Explicación del código
Esta sección importa las bibliotecas necesarias:
spidevpara la comunicación SPI con el MCP3008timepara funciones de retardomathpara operaciones logarítmicas en la fórmula de temperatura de Steinhart–HartRPi.GPIOpara inicializar y limpiar los GPIO (incluido por completitud estructural)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import spidev import time import math import RPi.GPIO as GPIO
Inicializa el modo GPIO como BCM y configura la interfaz SPI en el bus 0 y dispositivo 0 (CE0), con una velocidad de 1 MHz.
# Configurar modo GPIO GPIO.setmode(GPIO.BCM) # Inicializar SPI para MCP3008 (Bus 0, CE0) spi = spidev.SpiDev() spi.open(0, 0) # Bus 0, Dispositivo 0 (CE0) spi.max_speed_hz = 1000000 # 1 MHz
Define una función
read_adc(channel)para leer valores analógicos de un canal específico (0–7) del MCP3008. Envía un comando SPI de 3 bytes y recibe un resultado analógico de 10 bits (0–1023).def read_adc(channel): """ Leer valor analógico del canal 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
Bucle principal: Lee el voltaje analógico de un termistor en el canal 0, lo convierte en resistencia, y luego usa la ecuación de Steinhart–Hart para estimar la temperatura en Celsius y Fahrenheit. Las lecturas se actualizan cada 0,2 segundos.
try: while True: # Leer valor analógico del canal CH0 del MCP3008 analogVal = read_adc(0) # Convertir a voltaje (asumiendo referencia de 3,3 V) Vr = 3.3 * analogVal / 1023.0 # Calcular resistencia del termistor (R2 en divisor de tensión = 10 kΩ) Rt = 10000.0 * Vr / (3.3 - Vr) # Cálculo Steinhart–Hart tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0))) # Convertir a Celsius y Fahrenheit Cel = tempK - 273.15 Fah = Cel * 1.8 + 32 # Imprimir el resultado print('Celsius: %.2f °C Fahrenheit: %.2f °F' % (Cel, Fah)) time.sleep(0.2)
El bloque
finallyasegura un cierre correcto. Cierra la interfaz SPI y limpia la configuración de GPIO para liberar todos los recursos de hardware.except KeyboardInterrupt: pass finally: spi.close() GPIO.cleanup()