Medida de la temperatura con termopar
Las sondas de temperatura basadas en termopar determinan la temperatura midiendo la pequeña fuerza electromotriz que origina la unión de dos metales (conductores) distintos a distintas temperaturas; el llamado efecto termoeléctrico o efecto Seebeck. Son muy eficaces para trabajar con amplios rangos de temperaturas, especialmente en los tramos altos.
Las sondas de tipo K (cromel–alumel), las más usadas, entre otras razones por su relación entre precio y prestaciones, son capaces, en teoría, de medir temperaturas entre −180 °C y +1300 °C, aunque frecuentemente se utilizan para medir temperaturas, aproximadamente, entre los +50 °C y los +800 °C.
A la eficacia del sistema de medida de temperatura basado en termopar, le acompaña la necesidad de resolver tres cuestiones para poder ser explotado: ① capacidad de gestionar tensiones muy bajas (del orden de µV) o amplificar la respuesta del termopar para que un microcontrolador pueda trabajar con ella, ② corrección de la medida de la sonda para equipararla a una distribución lineal (linealización de la respuesta del termopar) y ③ compensación de unión fría para corregir la dependencia que existe entre la temperatura medida por la sonda y la temperatura ambiente.
Características del MAX6675
El IC MAX6675 sirve para resolver de manera sencilla estos tres aspectos y además, gracias en gran medida a que utiliza un bus SPI para las comunicaciones, es muy fácil de explotar en una aplicación basada en microcontrolador además de separar el punto de medida y el de procesado de los datos de forma más cómoda que la alternativa que supone extender el cable de la sonda.
Numéricamente, el MAX6675 es capaz de medir temperaturas de entre 0 °C y (aproximadamente) +1024 °C utilizando 12 bits con una resolución de 0,25 °C. A efectos prácticos, para ser fiable la medida, la temperatura objetivo debe ser unos grados superior a la temperatura ambiente e inferior a +700 °C. En tales circunstancias, el margen de error se encuentra en el entorno de los ±3 °C, mayor error a mayor temperatura y a mayor tensión de alimentación.
El tiempo de conversión de la temperatura del MAX6675 oscila entre los 170 ms y los 220 ms, como no hay forma de saber cuándo ha terminado la conversión y se puede solicitar la lectura del valor de la temperatura, lo habitual es dejar un tiempo algo superior al máximo, un cuarto de segundo (250 ms) es un valor suficientemente seguro y sencillo de recordar.
Implementación hardware del MAX6675
La compensación de unión fría se realiza utilizando un diodo de silicio ubicado en el interior del MAX6675. Aunque según la tabla de características del fabricante, el integrado puede funcionar entre −20 °C y +85 °C, la temperatura a la que se encuentre el MAX6675 puede ser relevante en el error de medida de la temperatura objetivo. Es importante procurar que la temperatura ambiente, la del entorno del MAX6675, sea razonablemente estable y sobre todo, que no sea superior a +40 °C, temperatura a partir de la cual el error de medida es mayor.
La inclusión del MAX6675 en un circuito microcontrolado es muy sencilla, el único componente que necesita es un filtro a la entrada de la alimentación (típicamente un condensador de 100 nF y opcionalmente otro más de 10 µF en condiciones muy ruidosas). Por otro lado, la conexión negativa de la sonda (alumel) debe conectarse a masa lo más cerca posible del pin GND.
A nivel más mecánico que electrónico, también es importante considerar el contexto en el que se implementa el termopar, tanto el extremo sensible (sonda) como el conector al equipo de medida. Para ambos existen varios estándares industriales correspondientes al conector macho y hembra aéreo y de panel cuya descripción no corresponde a este artículo.
Implementación software del MAX6675
La lectura desde un microcontrolador de la medida de la temperatura que realiza el MAX6675 se hace conforme al protocolo SPI: se establece a nivel bajo CS y cada ciclo de reloj (SCLK alto+bajo) se obtiene un bit. La única peculiaridad es que el MAX6675 utiliza un SPI simplificado que no acepta recepción de datos, solamente envía el valor de la temperatura.
Los 12 bits con los que el MAX6675 expresa la temperatura se transmiten en un bloque de 16 bits. El MSB (bit más significativo), que normalmente almacenaría el signo de la temperatura, no se utiliza, ya que solamente trabaja con temperaturas positivas. De los cuatro restantes, el bit cero (el bit menos significativo) representa el estado de la salida de datos, normalmente se deja en alta impedancia y se ignora su valor que, por otra parte, podría establecerse «manualmente» como uno o cero con una resistencia pull-up o con una resistencia pull-down. El bit uno se utiliza como un indicador del dispositivo (normalmente a nivel bajo o de valor cero) y el bit número dos informa del estado de la sonda estableciendo un nivel alto cuando el termopar está abierto (desconectado), por lo que su valor normal de funcionamiento es cero.
El siguiente código para Arduino se muestra un ejemplo que ilustra cómo obtener la carga útil con el valor de la temperatura desde el MAX6675. Se leen dos valores byte
usando la librería SPI, se cargan en un int
, se rotan 3 bits (para reubicar los bits de temperatura ignorando los de estado) y se divide entre 4.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#define PIN_CS_MAX6675 10 // Pin de Arduino al que se conecta la señal CS del MAX6675 #define ESPERA_ENTRE_LECTURAS 1000 // Un valor mayor que 220 ms (al menos 250 ms por seguridad) #include <SPI.h> // Añadir al código la librería de comunicaciones SPI int temperatura; // Entero en el que se almacenan los datos recibidos desde el MAX6675 void setup() { Serial.begin(9600); // Inicializar las comunicaciones serie para mostrar la temperatura en la consola SPI.begin(); // Inicializar las comunicaciones SPI pinMode(PIN_CS_MAX6675,OUTPUT); // Declarar como salida el pin al que se conecta el MAX6675 digitalWrite(PIN_CS_MAX6675,HIGH); // Establecer CS a nivel alto (inhabilitar las comunicaciones SPI con el MAX6675) } void loop() { digitalWrite(PIN_CS_MAX6675,LOW); // Habilitar las comunicaciones SPI con el MAX6675 temperatura=SPI.transfer(0); // Recibir el byte más significativo temperatura<<=8; // Colocar los 8 bits más significativos en su posición temperatura|=SPI.transfer(0); // Añadir los 8 bits del siguiente byte recibido desde el MAX6675 digitalWrite(PIN_CS_MAX6675,HIGH); // Desactivar las comunicaciones SPI con el MAX6675 temperatura>>=3; // Reubicar en la variable los datos de la temperatura (para que el LSB del valor quede en su posición) Serial.print("Temperatura del horno: "); // Mostrar un mensaje para identificar qué temperatura se está monitorizando (un horno de cerámica, por ejemplo) Serial.print((float)temperatura/4.0,DEC); // Dividir el valor entre 4 (el valor representa cuartos de grado) Serial.println(" °C"); // Indicar las unidades en las que se muestra la temperatura delay(ESPERA_ENTRE_LECTURAS); // Una forma poco elegante pero muy elocuente de leer la temperatura cada cierto intervalo } |
El anterior código para Arduino solamente considera el valor de la temperatura, sobrescribiendo los datos de estado al rotar tres posiciones los bits cargados del MAX6675. Dado que el tercer bit (b02) informa sobre el estado de la sonda, con el valor uno (nivel alto) cuando se desconecta, una interesante mejora podría ser informar, por ejemplo, encendiendo un LED de alarma, de la desconexión de la sonda.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#define PIN_CS_MAX6675 10 // Pin de Arduino al que se conecta la señal CS del MAX6675 #define BIT_ESTADO_SONDA_MAX6675 2 // Bit que representa el estado de la sonda, si está conectada o no al MAX6675 #define PIN_LED_SONDA 8 // Pin al que se conecta el LED que avisa de la desconexión de la sonda (alarma) #define ESPERA_ENTRE_LECTURAS 1000 // Un valor mayor que 220 ms (al menos 250 ms por seguridad) #include <SPI.h> // Añadir al código la librería de comunicaciones SPI int temperatura; // Entero en el que se almacenan los datos recibidos desde el MAX6675 boolean error_sonda; // ¿La sonda está conectada al MAX6675? void setup() { Serial.begin(9600); // Inicializar las comunicaciones serie para mostrar la temperatura en la consola SPI.begin(); // Inicializar las comunicaciones SPI pinMode(PIN_CS_MAX6675,OUTPUT); // Declarar como salida el pin al que se conecta el MAX6675 digitalWrite(PIN_CS_MAX6675,HIGH); // Establecer CS a nivel alto (inhabilitar las comunicaciones SPI con el MAX6675) pinMode(PIN_LED_SONDA,OUTPUT); // Declarar como salida el pin al que se conecta el LED de aviso del estado de la sonda } void loop() { digitalWrite(PIN_CS_MAX6675,LOW); // Habilitar las comunicaciones SPI con el MAX6675 temperatura=SPI.transfer(0); // Recibir el byte más significativo temperatura<<=8; // Colocar los 8 bits más significativos en su posición temperatura|=SPI.transfer(0); // Añadir los 8 bits del siguiente byte recibido desde el MAX6675 digitalWrite(PIN_CS_MAX6675,HIGH); // Desactivar las comunicaciones SPI con el MAX6675 error_sonda=((int)temperatura>>BIT_ESTADO_SONDA_MAX6675)&true; // Consultar el bit de estado de la sonda y almacenarlo en error_sonda digitalWrite(PIN_LED_SONDA,error_sonda); // Encender o apagar el LED según el estado de la sonda (error/desconectada encendido) if(error_sonda) { Serial.println("Sonda de temperatura desconectada"); // Informar del error en la consola } else { temperatura>>=3; // Reubicar en la variable los datos de la temperatura (para que el LSB del valor quede en su posición) Serial.print("Temperatura del horno: "); // Mostrar un mensaje para identificar qué temperatura se está monitorizando (un horno de cerámica, por ejemplo) Serial.print((float)temperatura/4.0,DEC); // Dividir el valor entre 4 (el valor representa cuartos de grado) Serial.println(" °C"); // Indicar las unidades en las que se muestra la temperatura } delay(ESPERA_ENTRE_LECTURAS); // Una forma poco elegante pero muy elocuente de leer la temperatura cada cierto intervalo } |
En el código del ejemplo anterior se obtiene el estado de la sonda (si está conectada o no) rotando el valor cargado del MAX6675 para que el bit que indica esta circunstancia quede en el LSB (bit menos significativo) y posteriormente se ignoran el resto de bits con una operación AND con el valor true
que se representa numéricamente como uno.
Jhon Elier
Monte el circuito con el mudulo MAX 6675con el arduino y no le lee temperaturas bajo cero
Víctor Ventura
Hola, Jhon.
Efectivamente, aunque las sondas de tipo K pueden medir temperaturas bajo cero y el MAX6675 funciona a temperaturas bajo cero (entre −20 °C y +85 °C, aunque mejor por debajo de 40 °C) el MAX6675 solamente es capaz de medir temperaturas desde 0 °C hasta +1024 °C. Siento mucho si en el artículo no lo dejo bastante claro 🙁 seguramente la confusión venga de hablar de esos dos datos sin remarcar a la vez los límites de funcionamiento del MAX6675. Si te fijas en la hoja de datos, en la descripción del integrado que hay en cada página (arriba a la derecha) dice «Cold-Junction-Compensated K-Thermocouple-to-Digital Converter (0°C to +1024°C)»
Muchas gracias por participar en polaridad.es
Raul
Buenas tardes Victor,
Yo estoy construyendo un circuito para controlar la temperatura de un horno, pero me interesa poder hace un comparativo de la temperatura y cuando llegue a cierto valor por ejemplo 100 C mandar una señal digital de 5V, hasta ahorita eh podido sacar el valor del MAX6675 en celsius pero no me permite hacer comparaciones, tienes alguna idea de como podria hacerle’, agradezco mucho tu apoyo,
Saludos
Víctor Ventura
Hola, Raúl.
Creo que no entiendo tu pregunta 🙁 ¿Con qué quieres comparar la temperatura, con una constante (100)? ¿No bastaría entonces algo como
if(temperatura>100)
? Casi seguro que te refieres a otra cosa.Tampoco me queda claro lo de la señal digital (quiero decir si preguntas cómo hacerlo) ¿Te refieres a algo como
digitalWrite(HIGH)
o sería enviar algo usando algún protocolo (I2C, SPI, Ethernet, wifi…)?A lo mejor si lo explicas con más detalle podemos ayudarte 🙂
Gracias a ti por participar en polaridad.es
Raul
Muchas gracias Victor, como bien comentas eso es lo que quería hacer, solo que por alguna razón no me permitía hacer la comparación if(temperatura>100), ya pude hacerlo, muchas gracias por tu apoyo,
Saludos
Víctor Ventura
Gracias a ti por contárnoslo en polaridad.es ¡Hasta pronto!
Javier
Hola Victor, lo felicito por estos desarrollos, nos enriquesen bastante. Me interesa este articulo, pues requiero tomar mediciones cada 10 segundos por periodos de 2 horas (leer y alamcenar datos 2 horas y no trabaja 2 horas) y enviarlas a un computador (cable de red) para al final del día tabular y comparar estos datos, la temperatura oscila entre 0ºC y 140ºC, hasta ahora estoy asimilando este protocolo (que detectaria la temperatura actual) pero como acondiciono el resto de factores (hardware y software) para este proyecto?, mil gracias por su ayuda.
Víctor Ventura
Hola, Javier.
No entiendo tu pregunta 🙁
¿Te funciona la lectura del MAX6675 pero no sabes cómo enviar los datos al PC? En el artículo sobre la monitorización desde un ordenador de sensores conectados a una placa Arduino usando Python tienes algunas pistas.
Claro que lo de «cable de red» me hace sospechar que te refieres a Ethernet. Precisamente, ayer mismo, escribí un ejemplo, a petición de un grupo de lectores, que explica cómo hacerlo. Aunque no es para enviar los datos de una sonda termopar K, sino para implementar en un servidor web mínimo con Arduino la lectura de un sensor UV, creo que podría servirte de ayuda.
Si el problema es calcular un valor intermedio a partir de los que vas monitorizando, dependerá del tipo de posprocesado que quieras aplicarle. Si envías los datos cada 10 segundos, tampoco esto me queda muy claro 🙁 , seguramente puedas calcular la mediana de un grupo (relativamente) pequeño de datos en la propia placa Arduino. Lógicamente, si el volumen de datos es mayor (¿solo tomas una medida cada 10 segundos o estás midiendo y promediando todo el tiempo?) tendrás que almacenar unos pocos (a corto plazo) en el PC (en un vector) procesarlos y luego almacenarlos definitivamente (en una base de datos).
Espero haber ayudado un poco ¡Suerte con tu proyecto!
Gary
Hola Victor!,
He tratado de implementar el código que has proporcionado, pero no logro llevar a cabo alguna medición.
Es posible que enseñes la conexion realizada entre el max6675 y arduino?
Saludos y excelente articulo!
Víctor Ventura
Hola, Gary.
El MAX6675 comunica por SPI de manera unidireccional (no espera datos) así que debes conectar el pin MISO de tu placa Arduino al correspondiente del MAX6675.
También necesitarás conectar la señal de reloj SCK de ambos y poner a nivel bajo (GND) el pin CS del MAX6675 de manera fija o conectándolo a alguna salida digital de tu placa Arduino (típicamente el 10) para activarlo o desactivarlo, por ejemplo, por si hay varios dispositivos en el mismo bus.
Lógicamente, también debes conectar el nivel GND de Arduino y del MAX6675.
Como sabrás, la sonda tiene polaridad que es necesario respetar.
No te puedo mandar una foto del una «instalación» con el MAX6675 (tampoco se verían las conexiones al MCU) pero cuando tenga un rato conecto una placa que tengo para las pruebas a algún Arduino con cables de colores por si te orienta un poco.
Gracias por participar en polaridad.es
Gary
Hola Victor!,
He logrado realizar las lecturas, gracias por tu explicación. Ahora he estado trabajando en realizar una grafica en tiempo real por medio de Realterm y Kst http://real2electronics.blogspot.cl/2009/11/graficar-con-kst.html
Hasta ahora no me ha sido posible enviar los datos por el puerto serie, haber si me puedes dar alguna ayuda.
Saludos y excelente aporte!!
Gerardo Fuerte Mendoza
Hola tengo este codigo y quiero hacer una comparación el punto aquí es que no se donde se almacena el dato de la temperatura o con cual puedo hacer la comparación ya que espero que cuando llegue a los 180°C deje de pasar corriente con un re elevador.
Muchas gracias por la ayuda.
#include
int ktcSO = 8;
int ktcCS = 9;
int ktcCLK = 10;
MAX6675 ktc(ktcCLK, ktcCS, ktcSO);
void setup()
{
Serial.begin(9600);
delay(500);
}
void loop()
{
serial.print(ktc.readCelsius());
}
Víctor Ventura
Hola, Gerardo.
Aunque no sé muy bien cómo funciona ese código, parece que la lectura la realiza el método
readCelsius()
del objetoktc
de la claseMAX6675
(el nombre del documento de la línea#include
se ha perdido al ser texto normal, no código).Para almacenar el valor de la temperatura puedes declarar una variable al principio del programa o en el bloque que la uses. Supongo que la variable será de tipo
float
, pero no te lo puedo asegurar porque no conozco la librería que has usado. Luego debes asignar a la variable el valor que devuelvereadCelsius()
, por ejemplo, con algo comotemperatura=ktc.readCelsius();
.Lo de comparar no me termina de quedar claro y a lo peor te digo una obviedad. Supongamos que defines el valor con
#define TEMPERATURA_MAXIMA 180.0
, luego tendrías que usar la variable que la almacenaif(temperatura>TEMPERATURA_MAXIMA)
… o directamente leerla con el método anteriorif(temperatura>ktc.readCelsius())
…Espero haberte ayudado un poco 🙂 Gracias por participar en polaridad.es
Pablo
Hola buenas he seguido el ejemplo y las conexiones.
Al abrir un monitor serie la temperatura que me mide el siempre 0.
He revisado las conexiones a mi arduinio Mini Pro:
LED –> PIN 9
MAX6675:
S0: pin 12 (MISO)
CS: pin 10
SCK: pin 13 (SCK)
VCC: VCC
GND: GND
Al abrir el monitor serie me salta el siguiente mensaje:
HOLATemperatura del horno: 0.0000000 ºC
DEcir que la sonda también la he revisado:
Rojo color + MAX 6675
Azul color + MAX 6675
Un saludo.
Pablo
nada he cambiado la sonda y funciona.
menuda empanada.
un saludo
Víctor Ventura
Hola, Pablo.
Pues muchas gracias por contárnoslo porque así nos ayudas por si se nos presenta un caso parecido 🙂
¡Vuelve pronto por polaridad.es!
carlos clavijo
hola Victor.
tengo una duda estoy trabajando con el max 6675, pero me refleja una temperatura incorrecta en la pc por ejemplo un pid me refleja que tengo una temperatura de 50° pero la termocupla k conectada al max6675 me refleja 40°.. que puedo variar para mejorar la precisión al medir?
Miguel Arquez
Hola Victor buen dia. Es posible alimentar la Max6675 con una fuente externa de 5V?
Gracias. En espera de tu respuestas.
MIGUEL ARQUEZ DE LEON
Hola buen dia.
por favor me sacas de una duda.
la Max6675 la puedo alimentar con una fuente externa de 5V?
para no tener que alimentarla desde arduino?.
Gracias en espera de su pronta respuesta.
Víctor Ventura
¡¡ Sí, por supuesto !!
ing Uriel Hernandez
Buenos dias, mi aplicacion consiste en monitorear temperatura dentro de una tuberia, me gustaria saber si tiene alguna idea de como o con que accesorio se enrosca a una tuberia. saludos
Fernando Gold
Buenas tardes:
Pretendo instalar 6 Max6675 y lo quiero poner en un busen cascad, la librería lo soporta o hay que agregar otra. Cómo sería.
Gracias
Alberto
Buenas,
En primer lugar muchas gracias por tu post. Me ha parecido bien elaborado, muy educativo, y me ha resultado de gran utilidad.
estoy utilizando este módulo para una impresora 3D open-source y estoy teniendo problemas. El módulo con el IC MAX6675 es en concreto el del fabricante Olymex. Para probar únicamente el módulo MAX6675 estoy cargando en mi Arduino MEGA el primero de los códigos de tu post. Únicamente cambio el Pin del CS, de acuerdo con cómo he conectado yo y que utilizo un MEGA en lugar de un UNO.
* ____________________________
* |OLYMEX | Arduino MEGA 2560|
* _____________________________
* |1 – VCC | VCC |
* |2 – GND | GND |
* |7 – MISO| 50 – SPI MISO |
* |9 – SCK | 52 – SPI SCK |
* |10 – SS | 66 – A12 |
* _____________________________
Lee bien todo y todo funciona bien. Mi problema es que la médida de la tempetura oscila continuamente 10ºC arriba 10ºC abajo aprox. Por ejemplo:
Temperature of the Hot-End: 45.2500 °C
Temperature of the Hot-End: 45.2500 °C
Temperature of the Hot-End: 49.5000 °C
Temperature of the Hot-End: 57.7500 °C
Temperature of the Hot-End: 60.7500 °C
Temperature of the Hot-End: 51.7500 °C
Temperature of the Hot-End: 44.7500 °C
Temperature of the Hot-End: 46.2500 °C
Temperature of the Hot-End: 54.7500 °C
Temperature of the Hot-End: 60.5000 °C
Temperature of the Hot-End: 55.0000 °C
Temperature of the Hot-End: 44.7500 °C
Temperature of the Hot-End: 45.5000 °C
Temperature of the Hot-End: 51.2500 °C
Temperature of the Hot-End: 59.7500 °C
La verdad es que no entiendo por qué de repente la medida es tan inestable. El otro día funcionaba bien y no he cambiado nada… Alguna idea?
Muchas gracias de antemano
Saludos
Kmilo
Hola, quería consultarte si existe alguna forma de implementar la comunicación SPI a Firmata para leer el MAX6675. Porque estoy haciendo un proyecto con Arduino en el que tengo la interfaz de usuario hecha en Python y me comunico con el Arduino por Firmata.
Estuve buscando y no encontré nada de nada… Además lo único que puedo hacer con la librería de Python que me permite usar firmata es leer y escribir en los pines…
Bueno, espero tu respuesta y desde ya, gracias.