martes, 29 de julio de 2014

Calibración de un termistor.

Calibración de un termistor.

Categoría: 2. Ciencia y tecnología.

Calibración de los sensores de temperatura.
Uno de los sensores se calibró leyendo valores de temperatura con un termómetro de mercurio marca Taylor (-20 a 110 °C) al mismo tiempo que se obtuvieron valores analógicos mostrados en el monitor serial del ambiente de programación Arduino. El rango de la calibración comprendió valores de 1 a 40 °C. A continuación se realizó una regresión lineal por mínimos cuadrados para obtener la ecuación que relaciona la temperatura en función del valor analógico medido con el sensor electrónico.

Los otros sensores se calibraron contra los valores obtenidos por el sensor calibrado contra el termómetro de mercurio. Para esto se utilizaron lecturas de 24 horas, cada cinco minutos, con los dos sensores colocados en el mismo sitio. El sensor exterior se calibró colocando la sonda calibrada junto a la sonda en el exterior, tomando lecturas al mismo tiempo. Así también, se colocó el sensor calibrado junto al sensor interior, tomando lecturas al mismo tiempo. Con estos datos se realizó una regresión lineal por mínimos cuadrados. Así se obtuvieron las ecuaciones de temperatura en función del valor analógico para cada una de las sondas de temperatura (Ver: Censado de datos. Monitorea un ambiente.).

Figura 1. Calibración del termómetro T_3 contra un termómetro de mercurio marca Taylor (-20 a 110 °C). Se tomaron lecturas analógicas (0 a 1023) con el sensor de temperatura y de manera simultánea se registraron las temperaturas medidas con el termómetro de mercurio. Con estos valores se obtuvo el gráfico y la ecuación por regresión lineal.

Figura 2. Calibración del termómetro T_2 tomando como referencia los valores de temperatura leídos con el sensor T_3, que fue previamente calibrado contra un termómetro de mercurio marca Taylor (-20 a 110 °C).

Figura 3. Calibración del termómetro T_1 tomando como referencia los valores de temperatura leídos con el sensor T_3, que fue previamente calibrado contra un termómetro de mercurio marca Taylor (-20 a 110 °C).

Figura 4. Mediciones de temperatura e iluminación una vez que se calibraron los sensores de temperatura. T_1 y T_3 se colocaron juntos en el interior de la habitación. T_2 se colocó en el exterior de la habitación. El sensor de iluminación se colocó en una ventana dentro de la habitación recibiendo la luz del exterior 

Una vez que se calibraron los tres termómetros, se colocó la sonda para medición de la iluminación. Así se hizo una medición de prueba con los cuatro sensores, registrando lecturas cada cinco minutos.

Termómetro1. Temperatura interior:                y=0.1591*x-56.113
Termómetro2 Temperatura exterior:                y=0.1116*x-35.358
Termómetro3 Temperatura del sistema:           y=0.13318*x-43.9853

En las ecuaciones de calibración el valor X corresponde al valor obtenido por el convertidor analógico / digital, AnalogRead(). Con ellas se calculan las temperaturas en grados Celsius, mismas que se despliegan en el monitor serial y se guardan en una tarjeta micro SD.

Una calibración más precisa, sin embargo, requiere algo más de trabajo. Puedes consultar el método de Steinhar-Hart y también utilizar una calculadora.







Censado de datos. Monitorea un ambiente.

Censado de datos. Monitorea un ambiente.

Categoría: 1. Programación y electrónica.

Este ejercicio es de utilidad para realizar un registro puntual o permanente de las condiciones de temperatura y luminosidad de un ambiente que se maneja automáticamente. De esta manera verificar que las condiciones que se programaron o se ajustaron en los equipos acondicionadores funcionan correctamente. Los datos se registran en un archivo de texto cada 10 minutos. También se despliegan en una pagina web muy simple que se refresca cada cinco segundos.

Una de las ventajas de este programa es que mientras estás visualizando la página web, los datos se refrescan cada 5 segundos (esto puede modificarse en el código) pero si cierras la página, el registro de datos continúa, refrescándose cada 60 segundos por default (también lo puedes programar con otra frecuencia).

El hardware para este ejercicio consiste en lo siguiente:
- Placa de desarrollo Arduino UNO R3.
- Shield Ethernet Arduino.
- Placa para prototipos.
- Tres termorresistencias (termistor) conectadas a GND con una resistencia de 10k_Ohm y calibradas.
- Una fotorresistencia de 2M_Ohm, conectada a GND con una resistencia de 10k_Ohm.
- Un led con resistencia de 1k_Ohm conectada a GND.
- Un buzzer.
- Fuente de alimentación 9Vcc.

En esta aplicación se combina el uso de las funciones de Ethernet y de la micro SD de Arduino Ethernet Shield. Se utilizaron como base los ejemplos DataLogger y WebServer que acompañan al IDE de Arduino. Además se trata de poner este equipo a trabajar de manera indepenciente. Es decir, no necesita estar conectado al puerto USB de la computadora, pero se pueden visualizar los datos en tiempo real en una computadora conectada a la misma red donde se conecta el servidor (Ethernet Shield).

De esta manera, no se depende del monitor serial para el despliegue de los datos censados ni se dedica una conexión USB para alimentar el circuito. 

Como aplicaciones para este sistema se sugiere el monitoreo de temperatura e iluminación durante un periodo de tiempo determinado, 24 a 48 h por ejemplo, y así detectar si la temperatura se mantiene dentro del rango deseado, o si se está fuera de las condiciones durante ciertas horas del día o la noche. También podemos calcular con cierta precisión la hora en que se encienden y apagan las luces. Esto puede ser útil si tenemos un sistema controlado automáticamente, pero queremos tener un registro de que esto está ocurriendo realmente. Podemos poner por ejemplo el caso en que una luminaria quede fuera de servicio. El equipo funciona correctamente, pero la iluminación no se encendió a la hora requerida. 

Esta aplicación se puede llevar a un invernadero donde las plantas necesitan un fotoperiodo mínimo para crecer o para no florear. Un laboratorio de cultivo de tejidos vegetales in vitro, donde se necesita exponer los cultivos a un fotoperiodo mínimo, normalmente 16 horas de iluminación por 8 horas de oscuridad. Una instalación donde se crían peces o aves y que requieren que la temperatura ambiente (aire o agua) estén siempre dentro de rango óptimo. 

En ambos casos, iluminación y temperatura, podemos agregar una alerta sonora cuando una de las condiciones salga de rango.

El sistema se puede manejar de manera permanente, teniendo cuidado de vaciar el archivo de destino cada semana o cada mes. Para no saturar la capacidad de la tarjeta de la memoria micro SD del Shield Arduino.

Este ejemplo se puede ampliar a otro tipo de mediciones, como pH, potencial redox, humedad relativa, presión atmosférica, concentración de CO (monóxido de carbono), entre otros. Contando con los sensores necesarios.

Así mismo es posible aumentar el número de sensores hasta 6 en el caso de ArduinoUNO. Si se trata de censar mayor número e variables se puede usar el Arduino Mega (16 entradas analógicas), que también es compatible con Ethernet Shield.


Gráfico 1. 

Los datos almacenados durante las 24h del día en un archivo de texto pueden procesarse con una hoja de cálculo (Microsoft Excel en este caso) para hacer un análisis visual de un gráfico. En él se puede distinguir claramente las horas de insolación y las horas de oscuridad. Para eso es necesario colocar la hora de inicio del censado, esto debe hacerse manualmente abriendo el archivo de texto y agregando la hora y fecha en el encabezado. En el editor de textos, menú [Editar] [Hora y fecha]. Es recomendable colocar en el encabezado del archivo de texto las ecuaciones de los sensores y la entrada analógica a la que se conectaron A0-A5 (para Arduino UNO).

Las temperaturas interior y en el sistema monitoreado (agua) se mantienen dentro de un rango estrecho, mientras que la temperatura exterior muestra una amplia variación, que durante el día se comporta de manera semejante a la intensidad luminosa (Ampliar el gráfico para ver detalles).

Los sensores de temperatura se encapsularon en un tubo de ensayo (vidrio) con bolitas de plomo unidas con silicón en el fondo (para evitar flotación). El tapón del tubo se selló con silicón para mantener siempre seco el termistor (Imagen 1).

Imagen 1.

La calibración de los termistores se hizo contra un termómetro de mercurio (Ver: calibración de un termistor). Colocando agua con hielo y tomando lecturas analógicas (0 - 1023) y de temperatura simultáneamente, hasta que el agua alcanza la temperatura ambiente. Otra serie de datos se toma en un vaso con agua caliente, hasta que se temperatura es la misma que el ambiente.

A continuación se muestra el código del programa (IDE Arduino).

/**********************************************
DataLogger_&_WebServer

Basado en:
DataLogger
 created  24 Nov 2010
 modified 9 Apr 2012
 by Tom Igoe

WebServer
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe

**********************************************/

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

int buzzer = 6;
int redLed = 9;
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);  // 192.168.1.177
EthernetServer server(80);
const int chipSelect = 4;
float sensor[5];
long double tiempoActual,tiempoPrevio,tiempoPrevio2;
long double intervalo = 600000;  // 10 minutos
long double intervalo2 = 60000;  // 1 minuto

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  Serial.print("Inicializando SD card ...");
  pinMode(10,OUTPUT);
  if (!SD.begin(chipSelect))
  {
    Serial.println("Falla en tarjeta. Inserte tarjeta ...");
    return;
  }
  Serial.println("Se inicalizo tarjeta SD ...");

  pinMode(buzzer,OUTPUT);
  pinMode(redLed,OUTPUT);
}


void loop() {
  tiempoActual=millis();
  EthernetClient client = server.available();

  if (client)
  {
    digitalWrite(redLed,HIGH);
    refreshWebServer();
    digitalWrite(redLed,LOW);
  }

  else
  {
    if (tiempoActual - tiempoPrevio2 > intervalo2)
    {
      digitalWrite(redLed,HIGH);
      refreshOutWeb();
      tiempoPrevio2 = millis();
      digitalWrite(redLed,LOW);
    }
  }

  if (tiempoActual - tiempoPrevio > intervalo)
  {
    digitalWrite(buzzer,HIGH);
    digitalWrite(redLed,HIGH);
    escribeArchivo();
    tiempoPrevio=millis();
    digitalWrite(buzzer,LOW);
    digitalWrite(redLed,LOW);
  }
}

/*********************        *********************/

void escribeArchivo()
{
  String dataString = "";
  int dato;  // Solo acepta int en la funcion String(dato);
  int tiempo = tiempoActual/60000;

  dataString += "\n";
  dataString += String(tiempo);
  dataString += "\t";

  for (int analogPin = 0; analogPin < 4; analogPin++)
  {
    dato = sensor[analogPin];
    dataString += String(dato);
    dataString += "\t";
  }

  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile)
  {
    dataFile.println(dataString);
    dataFile.close();
    Serial.println(dataString);
  }
  else {
    Serial.println("error opening datalog.txt");
  }
}


/*******************         **********************/

void refreshWebServer()
{
  EthernetClient client = server.available();

    digitalWrite(redLed,HIGH);
 
    Serial.println("new client");
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
 client.println("Refresh: 5");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          for (int analogChannel = 0; analogChannel < 4; analogChannel++) {
            float sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is \t");
            if (analogChannel == 0)
            {
              client.print("Interior ");
              sensorReading = 0.1591*sensorReading - 56.113;
              sensor[analogChannel]=sensorReading;
              client.print(sensorReading);
              client.print(" Celsius degree.");
            }
            if (analogChannel == 1)
            {
              client.print("Exterior ");
              sensorReading = 0.1116*sensorReading - 35.358;
              sensor[analogChannel]=sensorReading;
              client.print(sensorReading);
              client.print(" Celsius degree.");
            }
            if (analogChannel == 2)
            {
              client.print("Sistema ");
              sensorReading = 0.13318*sensorReading - 43.9853;
              sensor[analogChannel]=sensorReading;
              client.print(sensorReading);
              client.print(" Celsius degree.");
            }
            if (analogChannel == 3)
            {
              client.print("Iluminacion ");
              sensor[analogChannel]=sensorReading;
              client.print(sensorReading);
              client.print(" Digital value (0-1023).");
            }
            else
            {
              client.println(" ");
            }
            client.println("<br />");    
          }
          client.println("</html>");
          break;
        }
        if (c == '\n') {
         currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();
    Serial.println("client disonnected");
 
    digitalWrite(redLed,LOW);
}


/*******************        ***********************/

void refreshOutWeb()
{
          for (int analogChannel = 0; analogChannel < 4; analogChannel++)
          {
            float sensorReading = analogRead(analogChannel);
            if (analogChannel == 0)
            {
              sensorReading = 0.1591*sensorReading - 56.113;
              sensor[analogChannel]=sensorReading;
            }
            if (analogChannel == 1)
            {
              sensorReading = 0.1116*sensorReading - 35.358;
              sensor[analogChannel]=sensorReading;
            }
            if (analogChannel == 2)
            {
              sensorReading = 0.13318*sensorReading - 43.9853;
              sensor[analogChannel]=sensorReading;
            }
            if (analogChannel == 3)
            {
              sensor[analogChannel]=sensorReading;
            }
            else
            {
            }
          }
}

Los datos de calibración de los termómetros se graficaron en Excel y se ajustaron a una recta por el método de regresión por mínimos cuadrados. Las ecuaciones obtenidas son las siguientes:

Termometro1. Temperatura interior:              y=0.1591*x-56.113               Pin: A0
Termometro2. Temperatura exterior:             y=0.1116*x-35.358               Pin: A1
Termometro3. Temperatura del sistema:        y=0.13318*x-43.9853           Pin: A2

La fotorresistencia no se calibró. Para este dispositivo se registran los valores digitales leídos por el convertidor analógico digital (valores de 0 a 1023).

Figura 2.

Para poder visualizar los datos censados, se abre una ventana en el explorador y en la barra de direcciones se escribe la dirección IP que se utiliizó en el código del programa. Los valores se refrescan cada 5 segundos, lo cual es adecuado, ya que por ser una página web tan sencilla casi no consume recursos de la computadora en que se despliegan.

El valor de tiempo registrado en el archivo de texto está en minutos. Para poderlo manejar en Excel se recomienda convertir los datos de esa columna a valores de hora (00:00 a 23:59). Esto se hace fácilmente con la función TIEMPO(hora,minuto,segundo). Como el dato está en minutos, se colocan ceros en hora y segundo, en el atributo minuto se escribe la dirección de la celda que se va a convertir). En la primer celda de la siguiente columna se coloca la hora de inicio y a partir de la segunda se coloca una fórmula que suma esa primera celda (fija, como en $C$7+B8).

En el siguiente enlace puedes encontrar un proyecto para la construcción de un medidor de pulso utilizando optoelectrónica.

Dispositivos electrónicos programables como el que se utilizó en este ejemplo, pueden servir para la automatización de otras aplicaciones. En este enlace puedes ver unas notas sobre automatización de un invernadero. O en forma de presentación (automatización de un invernadero).