Uno de los ejercicios más comunes para Arduino es la adquisición de un valor de temperatura. Podemos realizar este proceso con una librería, pero vamos a investigar un poco más la ciencia que hay en su interior.

Vamos a realizar un ejercicio para obtener valores de temperatura y en un segundo tutorial introduciremos un control de temperatura con un calentador mediante PID. Los sistemas PID siempre requieren de un actuador y de un sensor. Así que vamos con la parte del sensor para leer valores correctos y precisos.

Antes que nada, necesitaremos los siguientes elementos creando el siguiente circuito.

  • Un termistor NTC de 100KΩ
  • Una resistencia de 10KΩ
  • Arduino

Este circuito es una simple lectura desde el pin analógico 0, es por ello que vamos a observar los valores a través del monitor serie y seguidamente manipularemos sus lecturas en bruto para obtener valores de temperatura correctos.

Realizaremos los siguientes ejercicios desde la página ArduBlockly para entender mejor el proceso.

En este primer paso, hemos de interpretar en una escala el valor leido por nuestra placa. Para ello, hemos de hacer un cálculo en función del valor de la resistencia que hemos conectado. En nuestro caso es de 10KΩ, pero en el caso de haber conectado una resistencia de otro valor, deberíamos modificar ese valor.

int resistance;
float reading;

void setup() {
  Serial.begin(9600);
  pinMode(A0, INPUT);

  resistance = (int)(10000); //Resistance value 10K
  reading = (float)(0);

}

void loop() {
  reading = analogRead(A0);
  reading = 1023 / reading - 1;
  reading = resistance / reading;
  Serial.print("Thermistor Resistance: ");
  Serial.println(reading);

}

El procedimiento de cálculo para hallar esta resistencia del sensor NTC se basa en despejar de la ecuación la resistencia incógnita con los valores medidos en función de la lectura con un valore de rango entre 0 – 1023 del voltaje. Desde la siguiente página se puede leer el procedimiento completo.

(1)   \begin{equation*} \frac{Vcc-A0}{10K} =\frac{A0}{R} \end{equation*}

(2)   \begin{equation*} R = \frac{A0*10K}{Vcc-A0} = \frac{10K}{ \frac{Vcc-A0}{A0}} = \frac{10K}{ \frac{Vcc}{A0} -1} \end{equation*}

 

Aún así, esta no es la mejor manera de realizar lecturas, ya qué puede ocurrir que exista una componente de ruido que haga que nuestra lectura, se vea modificada, presente picos indeseables, etc…

Para evitar una saturación de fluctuaciones en los valores leidos, lo que vamos a hacer es sumar una serie de lecturas en conjunto para hacer la media y obtener así un dato de temperatura robústo.



int resistance;
float reading;
int nsamples;
float average;
int i;

void setup() {
  Serial.begin(9600);
  pinMode(A0, INPUT);

  resistance = (int)(10000);
  reading = (float)(0);
  nsamples = (int)(40);
  average = (float)(0);

}

void loop() {
  average = 0;

  for (i = 1; i <= nsamples;  i ++) {
    reading = analogRead(A0);
    average = average + reading;
  }
  average = average / nsamples;
  average = 1023 / average - 1;
  average = resistance / average;
  Serial.print("Thermistor Resistance: ");
  Serial.println(average);

}


Pero despues, de todo esto, aún no sabemos el valor real de temperatura.

Para ello, vamos a relacionar el valor de la resistencia que estamos leyendo con la escala real de temperatura.

Para ello, necesitaremos conocer la ecuación de SteinHart-Hart.

(3)   \begin{equation*} \frac{1}{T} = A+ B\ln(R)+C[\ln(R)]^{3} \end{equation*}

Esta ecuación relaciona el valor de resistencia proporcionado por un semiconductor; como es el NTC de 100KΩ, con la temperatura real.

A un lado de la ecuación aparece nuestro valor de temperatura a la inversa,  y al otro lado, tenemos tres coeficientes A ,B y C aparentemente desconocidos multiplicados por un logaritmo neperiano en función de la resistencia que nosotros antes hemos obtenido.

Nuestro problema para despejar la temperatura de esta ecuación, será obtener los coeficientes. Para ello, disponemos de tablas que nos informan de estos tres valores en función del sensor que hemos comprado, o sino, se puede calcular si medimos la resistencia obtenida en distintas temperaturas desde el siguiente enlace que crea las gráficas de comportamiento de nuestro sensor. Para conocer el procedimiento de cálculo se puede atender al siguiente pdf.

De todas formas, en este ejercicio utilizaremos una ecuación de Steinhart-Hart simplificada o (B Parameter Equation), para depender unicamente de un factor.

(4)   \begin{equation*} \frac{1}{T} = \frac{1}{T{0}}+ \frac{1}{B}ln(R/R{0}) \end{equation*}

Donde el valor T0 es la temperatura ambiental; que nosotros consideraremos de 25º y la R0 será el valor denuestra resistencia NTC de 100KΩ. No confundir con la resistencia del circuito, que puede variar y ya hemos realizado su corrección calculando R.

Para nuestro termistor utilizaremos el siguientes coeficiente Beta que podemos obtener de la hoja del fabricante o desde la página RepRap, que ya tienen un listado extenso de estos parámetros.

BCOEFFICIENT 4066

Así que podemos desarrollar el siguiente programa para obtener valores de temperatura con esta fórmula.

 



int resistance;
float reading;
int nsamples;
float average;
int T0;
float R0;
int B;
int i;

void setup() {
  Serial.begin(9600);
  pinMode(A0, INPUT);

  resistance = (int)(10000);
  reading = (float)(0);
  nsamples = (int)(40);
  average = (float)(0);
  T0 = (int)(25 + 273.15);
  R0 = (float)(100000);
  B = (int)(4066);

}

void loop() {
  average = 0;

  for (i = 1; i <= nsamples; i ++) {
    reading = analogRead(A0);
    average = average + reading;
  }
  average = average / nsamples;
  average = 1023 / average - 1;
  average = resistance / average;
  float steinhart;
 steinhart = average / THERMISTORNOMINAL; // (R/Ro)
 steinhart = log(steinhart); // ln(R/Ro)
 steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
 steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
 steinhart = 1.0 / steinhart; // Invert
 steinhart -= 273.15; 
  Serial.print("Thermistor Resistance: ");
  Serial.println(reading);

}


Una vez hecho este ejercicio, podemos añadir una resistencia para calentar y realizar un control PID para acondicionamiento.