miércoles, 3 de junio de 2015

Sensor temperatura sumergible DS18B20

Continuamos esta serie de tutoriales sobre el uso de sensores ambientales con la plataforma Arduino, utilizando un sensor bastante interesante, el sensor de temperatura DS18B20. Se trata de un sensor digital que tiene dos cualidades muy útiles, por un lado disponemos de una versión encapsulada y cableada que permite su uso en exteriores e incluso en contacto con líquidos, de hecho es sumergible, por otro utiliza un protocolo llamado 1-Wire que nos permite utilizar varios sensores de forma simultanea conectandolos a un mismo pin del Arduino, siendo capaces de identificar la lectura de cada uno de ellos de forma independiente. Esto se consigue gracias a que de fabrica, cada sensor sale con un código identificativo de 64 bits, que lo distingue de forma única de cualquier otro.



Material Necesario

El material necesario para la realización de este tutorial consiste en:


Los datasheet necesarios son:

Esquema de Montaje

Cuando trabajamos con varios sensores DS18B20 o en general varios dispositivos que trabajen con el protocolo 1-Wire, podemos dejar que la propia librería utilizada (ahora la veremos) asigne las lecturas a los sensores, sin embargo, no es muy práctico dado que dicho orden no tiene porque coincidir con el orden de colocación de los sensores respecto a la placa Arduino, en términos prácticos no sabremos que sensor registra que lectura. Para evitar este inconveniente tenemos que averiguar la dirección del sensor, la cual tiene este formato: 

0x28 0x8A 0xB1 0x40 0x04 0x00 0x00 0xC7

Como el tema se va complicando vamos a empezar limitandonos a obtener las direcciones de los dos sensores que vamos a utilizar. Para ello vamos a necesitar dos librerías:


Si no estáis familiarizados con la instalación de librerías tenemos un tutorial al respecto: Tutorial Arduino II: Librerias Arduino.


Con respecto al esquema, señalar que hemos puesto la versión estandar del sensor en TO-92, eso se debe a que no esta disponible como objeto en Fritzing la versión cableada que tenemos, la misma tiene tres cables: uno rojo para el voltaje, otro azul o negro (según la versión) para el GND y uno amarillo para la linea de datos, por ese motivo (el ser una versión cableada) necesitamos las pinzas de cocodrilo, para poder realizar la conexión de forma rápida y sencilla. Por otra parte veis que usamos una resistencia "pull-up" de 4K7 Ohm y 1/4W entre el voltaje y la linea de datos.







Sketch Arduino


El sketch para averiguar la dirección del sensor sería este:





//Incluimos las librerias que hemos decargado previamente
#include <OneWire.h>
#include <DallasTemperature.h>

//El ejemplo se realiza con Arduino Uno, conectando el pin de datos al Pin 13
#define ONE_WIRE_BUS 13
OneWire oneWire(ONE_WIRE_BUS);  // Creamos el objeto oneWire indicando el pin utilizado para comunicar con cualquier dispositivo OneWire
DallasTemperature sensores(&oneWire); // Asociamos nuestra referencia oneWire a un sensor de Dallas
DeviceAddress Sensor;  // Array donde almacenamos la direccion del sensor DS18B20

void setup(void)
{
  Serial.begin(9600);  //Iniciamos la comunicacion serie
  Serial.println("Direccion Sensor DS18B20:");
  sensores.begin();  //Iniciamos los sensores
  //Obtenemos la direccion del sensor de temperatura
  if (!sensores.getAddress(Sensor, 0)) 
  //Si no es posible determinar la direccion nos da un mensaje de error
    Serial.println("Imposible encontrar direccion del sensor.");
}

//Creamos la funciona Mostrar_Direccion
void Mostrar_Direccion(DeviceAddress direccion)
{
  //Definimos la amplitud de la direccion del sensor: 8 bits.
  //El sensor envia dos tipos de datos, una lectura de hasta 12 bits y una direccion de 8 bits relevantes
  for (uint8_t i = 0; i < 8; i++) 
  {
    //Le indicamos que añada "0x" antes de cada grupo de digitos que forman la direccion.
    //Si no usamos esta instruccion luego habrá que añadir "0x" a mano para usarla en el siguiente sketch.
    Serial.print("0x"); 
     if (direccion[i] < 16) Serial.print("0");
    Serial.print(direccion[i], HEX);//Usamos formato Hexadecimal
  }
}

void loop(void)
  //Muestra la direccion del sensor
  Serial.print("Direccion del sensor: ");
  Mostrar_Direccion(Sensor);
  Serial.println();
  delay(5000);
}



Si abrimos el Monitor Serial veremos la dirección obtenida en un formato que podremos usar en el sketch para obtener las lecturas de los sensores DS18B20.



:


Esquema de Montaje

El esquema de conexionado en Fritzing para realizar la lectura de dos sensores DS18B20 de forma simultanea a través del mismo pin de Arduino sería el siguiente:




Como veréis lo único que se hace es puentear el GND y el VCC de los sensores, así como los respectivos pines de datos.


Sketch Arduino

El sketch completo para obtener los datos de temperatura de ambos sensores así como para establecer la resolución de la misma (viene todo explicado en el propio sketch), es el siguiente:



Sketch Arduino



//La primera parte del sketch is igual al utilizado para averiguar la direccion de los sensores
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 13
                            
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensores(&oneWire);

//Indicamos las direcciones de los sensores
DeviceAddress S1 = {0x28, 0xF6, 0x15, 0x06, 0x06, 0x00, 0x00, 0xA8};  //Sensor Interior
DeviceAddress S2 = {0x28, 0x1B, 0xCB, 0x05, 0x06, 0x00, 0x00, 0xBF};  //Sensor Exterior

void setup(void)
{
  Serial.begin(9600);  //Abrimos la comunicación por serial
  sensores.begin();  //Iniciamos los sensores
}

//Creamos una funcion para mostrar la direccion de los sensores
void Mostrar_Direccion(DeviceAddress direccion)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (direccion[i] < 16)
      Serial.print("0");
    Serial.print(direccion[i], HEX);
  }
}

//Funcion que muestra la temperatura en grados centigrados del sensor
void Mostrar_Temperatura(DeviceAddress direccion)
{
  float tempC = sensores.getTempC(direccion);
  Serial.print("Temperatura: ");
  Serial.print(tempC);
}

//Funcion que muestra la resolucion del sensor de dicha direccion. Las resoluciones posibles pueden ser:
//Resolucion a 9 bits 0.50 ºC
//Resolucion a 10 bits 0.25 ºC
//Resolucion a 11 bits 0.125 ºC
//Resolucion a 12 bits 0.0625 ºC
void Mostrar_Resolucion(DeviceAddress direccion)
{
  Serial.print("Resolucion: ");
  Serial.print(sensores.getResolution(direccion));
  Serial.println();  
}

//Funcion que muestra los datos del sensor de dicha direccion
void Mostrar_Datos(DeviceAddress direccion)
{
  Serial.print("Direccion del dispositivo: ");
  Mostrar_Direccion(direccion);
  Serial.print(" ");
  Mostrar_Temperatura(direccion);
  Serial.println();
}

void loop(void)
{
  Serial.println("Comprobacion Direccion Sensores DS18B20:");
  //Podemos ver el numero de dispositivos que estan conectados al bus 1-Wire
  Serial.print("El numero de dispositivos es: ");
  Serial.println(sensores.getDeviceCount(), DEC);
  Serial.print("Direccion Sensor Interior: ");
  Mostrar_Direccion(S1);
  Serial.println();
  Serial.print("Direccion Sensor Exterior: ");
  Mostrar_Direccion(S2);
  Serial.println();
  //Establecemos la resolucion para cada sensor, PRECISION es a 9 bits
  sensores.setResolution(S1, 9);  //Resolucion a 9 bits 0.50 ºC
  sensores.setResolution(S2, 10);  //Resolucion a 10 bits 0.25 ºC
  //Si queremos mostrar la resolucion que tiene cada sensor:
  Serial.print("Resolucion Sensor Interior: ");
  Serial.print(sensores.getResolution(S1), DEC);
  Serial.println();
  Serial.print("Resolucion Sensor Exterior: ");
  Serial.print(sensores.getResolution(S2), DEC);
  Serial.println();
  sensores.requestTemperatures();  //Enviamos el comando para obtener los datos de los sensores
  //Mostramos los datos de todos los sensores
  //Llamamos a la funcion Mostrar_Datos indicando la direccion del sensor que queremos leer
  Serial.print("Sensor Interior --> ");
  Mostrar_Datos(S1);
  Serial.print("Sensor Exterior --> ");
  Mostrar_Datos(S2);
  delay(2000);  //Retardo de 2 segundo
}



Abriendo el Serial Monitor obtendremos los siguientes datos:




Como ya os habréis dado cuenta las ventajas de este protocolo en general y de este sensor en particular son obvias, usando un solo pin de Arduino, es decir, dejando el resto libre para otras funcionalidades (pantallas TFT, salidas digitales para controlar reles,...etc) podemos obtener múltiples lecturas cuyo origen puede estar físicamente alejado de la placa, por tratarse de sensores digitales. Por ello son sensores muy usados en proyectos de domótica, control industrial, ...etc

1 comentario:

  1. Tío, buen tuto... Pero necesito orientación urgente sobre un proyecto que estoy haciendo... Cuando conecto el sensor de temperatura a la SIM900, a la hora de checar la temperatura en el serial monitor, me aparece -127.00 Responde, por favor :( Saludos!

    ResponderEliminar