Sensores en Arduino (I): Temperatura
En Configuración de Instalaciones Domóticas y Automáticas de 2º curso del CFGS de Sistemas Electrotécnicos y Automatizados estamos ahora dedicando unas horas a la semana a la configuración de sistemas domóticos, para lo cual estamos integrando diferentes tipos de sensores en placas Arduino y elaborando algunas aplicaciones de control domótico en sistemas no propietarios.
Un caso especialmente interesante son los sensores de temperatura, en los cuales nos centraremos especialmente en los termistores NTC y los sensores de unión semiconductora (LM35 y TMP36), dejando fuera los RTD y termopares, que integraremos en sistemas automatizados basados en autómata programable.
En el caso de los termistores NTC, estamos trabajando con termistores NTC de 10K, con un rango de medición de -80ºC a 150ºC (de sobra para las aplicaciones que queremos diseñar).
El principal problema que plantean los termistores a la hora de emplearlos en aplicaciones de control de temperatura es sin duda la no linealidad de la curva R/T. Por contra, ofrecen gran sensibilidad, precisión y bajo coste frente a otro tipo de sensores. Su integración en sistemas domóticos, y en este caso en Arduino, exige una modelización de la curva R/T, teniendo en cuenta que en este tipo de sensores, una pequeña variación de la temperatura provoca una gran variación de la resistencia asociada. En este caso, al ser NTC, un aumento de temperatura provoca una gran disminución de la resistencia y viceversa.
El método más corriente para modelizar la curva R/T de los termistores NTC consiste en aplicar la ecuación de Steinhart-Hart, que relaciona la temperatura con la resistencia de la forma:
a,b y c son parámetros específicos de cada tipo de sensor, y por tanto deben ser determinados o especificados por el fabricante. En el caso de sensores NTC como es nuestro caso, es posible simplificar la ecuación de Steinhart-Hart por:
donde el parámetro B (beta) es específico de cada material (y además varía con la temperatura), To es la temperatura base de referencia (25ºC o 298.15 ºK) y Ro es la resistencia a esa temperatura de nuestro sensor (10K en nuestro caso).
Naturalmente, para poder modelizar las ecuaciones necesitamos conocer los valores de a, b y c o bien los valores de B, sin lo cual no podemos hacer gran cosa. El fabricante para este caso nos ofrece diversa documentación que será necesario diseccionar para poder averiguar aquello que nos interesa. Para el caso de los termistores de 10K (tipo F), el fabricante nos ofrecen las características de los mismos, dentro de las cuales podemos ver:
es decir, el fabricante ha modificado ligeramente la ecuación de Steinhart-Hart y nos ofrece valores de a, b, c y d para su modelización R/T (que no es la misma que la original y por tanto los coeficientes no son trasladables). Introducir la ecuación ahora en un sketch para Arduino es sencillo. El único problema se presenta a la hora de conocer los valores de Rth/R25, ya que en función de ellos debemos seleccionar a, b, c y d y además hallar Rth.
Para solucionar el primer problema, el fabricante nos proporciona además en el mismo documento una tabla de Rth/R25 a diferentes temperaturas. Podemos ver cómo en el rango entre 0ºC y 50ºC, que es donde utilizaremos nuestro sensor, nos situamos entre 0.36036 y 3.274, por lo que los valores de a, b, c y d nos quedan fijados.
Para solucionar el segundo problema (hallar Rth), es necesario transformar las variaciones de tensión en el pin analógico de Arduino en variaciones de resistencia. Podemos hacerlo con un montaje sencillo de la siguiente forma:
De este modo, analizando de forma sencilla el circuito, podemos concluir que Rth= (1024 x 10000 / (lectura A0)) – 10000. La lectura de A0 variará entre 0 y 1023, de modo que 0 corresponde a 0V en A0, y 1023 corresponde a 5V. De este modo, podemos hallar el valor de Rth en función del valor de lectura en el pin analógico. Introducimos igualmente dicha ecuación en Arduino, de forma que nos queda algo como:
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 42 43 44 45 46 47 48 49 50 |
/*+---------------------------------------------- LECTURA DE VALORES DE TEMPERATURA CON TERMISTOR Autor: JMDelgado Fecha: 28-02-2014 ----------------------------------------------+*/ #include <math.h> //GLOBAL int resistencia_ref = 10000; //Valor de la resistencia de referencia empleada en el conexionado del termistor int R25 = 10000; //Valor de la resistencia del termistor a 25ºC, en este caso, 10K int pin_termistor = 0; //Pin analogico de conexionado de nuestro termistor //TERMISTOR double termistor (int lectura) { double Rth; //Rth double temperatura; /*Para nuestro termistor, de acuerdo a tablas EC95 (1/T) = a+b*log(Rth/R25)+c*log(Rth/R25)^2+d*log(Rth/R25)^3 a=3.3540154E-03 b=2.5627725E-04 c=2.0829210E-06 d=4.6045930E-08*/ double a=3.3540154E-03; //Parametro a double b=2.5627725E-04; //Parametro b double c=2.0829210E-06; //Parametro c double d=4.6045930E-08; //Parametro d double rthr25; //log(Rth/R25) Rth = (1024 * float(resistencia_ref)/lectura)-float(resistencia_ref); //Valor de Rth en funcion del conexionado de nuestro termistor rthr25 = log(Rth/R25); temperatura = 1/(a+b*rthr25+c*rthr25*rthr25+d*rthr25*rthr25*rthr25); temperatura = temperatura-273.15; //Pasamos temperatura a ºC return temperatura; } //SETUP void setup() { Serial.begin(9600); } //LOOP void loop() { Serial.print("Temperatura: "); Serial.print(float(termistor(analogRead(pin_termistor)))); Serial.println(" oC"); delay(500); } |
El código anterior nos devolverá cada medio segundo el valor en ºC medido por el termistor NTC 10K.
Es posible no obstante plantear el código empleando para ello el parámetro B para nuestro termistor NTC. En este caso, podemos fijarnos en la tabla que el fabricante nos adjunta para termistores tipo F, donde se detalla el valor de B para cada rango de temperaturas. A pesar de que B no es constante con la temperatura, es posible considerarla más o menos constante por rangos:
De este modo, para nuestro caso podemos considerar su valor como 3895, y plantear ahora el código anterior como:
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 |
/*+---------------------------------------------- LECTURA DE VALORES DE TEMPERATURA CON TERMISTOR Autor: JMDelgado Fecha: 28-02-2014 ----------------------------------------------+*/ #include <math.h> //GLOBAL int resistencia_ref = 10000; //Valor de la resistencia de referencia empleada en el conexionado del termistor int R25 = 10000; //Valor de la resistencia del termistor a 25ºC, en este caso, 10K int pin_termistor = 0; //Pin analogico de conexionado de nuestro termistor //TERMISTOR double termistor (int lectura) { double Rth; //Resistencia del termistor double temperatura; //Temperatura double rthr25; //(Rth/R25) int beta = 3895; //Beta para el rango de temperaturas 0-50ºC (Datasheet EC95) Rth = (1024 * float(resistencia_ref)/lectura)-float(resistencia_ref); //Valor de Rth en funcion del conexionado de nuestro termistor rthr25 = log(Rth/R25); temperatura = 1/((1/298.15)+(1/float(beta))*rthr25); //Aplicamos directamente Steinhart-hart para NTC temperatura = temperatura-273.15; //Pasamos temperatura a ºC return temperatura; } //SETUP void setup() { Serial.begin(9600); } //LOOP void loop() { Serial.print("Temperatura: "); Serial.print(float(termistor(analogRead(pin_termistor)))); //Imprimimos la temperatura, devuelta por la funcion termistor y convertida a float Serial.println(" oC"); delay(500); } |
Obteniendo de esta forma valores muy similares a los obtenidos con el código anterior, por lo que la modelización puede considerarse correcta. En otro artículo plantearemos la simplificación obtenida (con los consiguientes sacrificios) al emplear sensores basados en unión semiconductora como los LM35 o TMP36.
Tags // arduino, formación, Instalaciones Térmicas, Programación
Trackback from your site.