.. note:: ¡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 [|link_sf_facebook|] y únete hoy. .. _2.2.2_c_mcp3008: 2.2.2 Termistor (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 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. .. image:: img/list2_2.2.2_thermistor.png 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. .. image:: img/image325.png 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: R\ :sub:`T` = R\ :sub:`N` exp\ :sup:`B(1/TK – 1/TN)` - **R\ T** es la resistencia del termistor NTC a la temperatura **T\ K**. - **R\ N** es la resistencia del NTC a la temperatura nominal **T\ N**. Aquí, **R\ N** = 10 kΩ. - **T\ K** es la temperatura en Kelvin (K = °C + 273.15). - **T\ N** 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: T\ :sub:`K`\ = 1 / (ln(R\ :sub:`T`/R\ :sub:`N`)/B + 1/T\ :sub:`N`) Para Celsius: **°C = T\ K – 273.15**. Este es un modelo empírico válido solo dentro del rango especificado. Diagrama esquemático -------------------- .. list-table:: :widths: 30 30 30 30 :header-rows: 1 * - 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 .. image:: img/schematic_2.2.2_thermistor_mcp3008.png Procedimiento experimental -------------------------- **Paso 1:** Construye el circuito. .. image:: img/july24_2.2.2_thermistor_mcp3008.png Para usuarios de C ^^^^^^^^^^^^^^^^^^ **Paso 2:** Ve a la carpeta del código. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/c/2.2.2-2/ **Paso 3:** Compila el código. .. raw:: html .. code-block:: gcc 2.2.2_Thermistor.c -o Thermistor -lwiringPi -lm .. note:: -lm es para enlazar la librería matemática. No omitir, o dará error. **Paso 4:** Ejecuta el archivo compilado. .. raw:: html .. code-block:: ./Thermistor Al ejecutarse, el termistor mide la temperatura ambiente y el programa imprime el valor calculado en pantalla. .. note:: Si no funciona o aparece el error `"wiringPi.h: No such file or directory"`, consulta :ref:`install_wiringpi`. **Código** .. code-block:: c #include #include #include #include #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** .. code-block:: c #include #include #include #include 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. .. code-block:: 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. .. code-block:: c int read_ADC(int channel) Esta función lee datos analógicos de un canal específico del ADC MCP3008. .. code-block:: c 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. .. code-block:: c wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3); Transfiere el comando SPI y recibe los datos de 10 bits del ADC MCP3008. .. code-block:: c 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. .. code-block:: c 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. .. code-block:: c 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. .. code-block:: c 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. .. code-block:: c 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. .. code-block:: c 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 .. code-block:: c cel = temp - 273.15; Convierte la temperatura de Kelvin a grados Celsius. .. code-block:: c Fah = cel * 1.8 + 32; Convierte la temperatura en Celsius a Fahrenheit. .. code-block:: c 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 :ref:`spi_configuration`). Si ya lo hiciste, sáltalo. **Paso 3:** Ve a la carpeta del código. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/python **Paso 4:** Ejecuta el archivo. .. raw:: html .. code-block:: sudo python3 2.2.2-2_thermistor.py Al ejecutarse, el termistor mide la temperatura ambiente y muestra el valor calculado. .. warning:: Si aparece el error ``RuntimeError: Cannot determine SOC peripheral base address``, consulta :ref:`faq_soc`. **Código** .. raw:: html .. code-block:: python #!/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: - ``spidev`` para la comunicación SPI con el MCP3008 - ``time`` para funciones de retardo - ``math`` para operaciones logarítmicas en la fórmula de temperatura de Steinhart–Hart - ``RPi.GPIO`` para inicializar y limpiar los GPIO (incluido por completitud estructural) .. code-block:: python #!/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. .. code-block:: python # 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). .. code-block:: python 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. .. code-block:: python 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 ``finally`` asegura un cierre correcto. Cierra la interfaz SPI y limpia la configuración de GPIO para liberar todos los recursos de hardware. .. code-block:: python except KeyboardInterrupt: pass finally: spi.close() GPIO.cleanup()