Páginas

sábado, 26 de julio de 2014

Tutorial Arduino IV: Sensor de Temperatura 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




22 comentarios:

  1. Este comentario ha sido eliminado por un administrador del blog.

    ResponderEliminar
  2. Muchas gracias por el articulo. Todo muy claro

    Saludos

    ResponderEliminar
  3. Enhorabuena por el trabajo. Quisisera saber que tipo de sensor de inmersión para arduino seria capaz de trabajar en rangos de temperatura de -55÷250°C?

    ResponderEliminar
  4. El unico sensor encapsulado para su uso con liquidos que tenemos es el DS18B20 que llega hasta 125ºC: http://www.cetronic.es/sqlcommerce/disenos/plantilla1/seccion/producto/DetalleProducto.jsp?idIdioma=&idTienda=93&codProducto=999334005&cPath=1343

    ResponderEliminar
  5. Hola gracias por el tuto, solo decir que a mi personalmente en el pin 13 no me funcionaba, pero en el 6, todo sin problemas. :)

    Gracias!

    ResponderEliminar
  6. Hola, gracias por el tutorial que me va a ayudar mucho en una practica de instrumentación. Lo que quería preguntar es ¿saben de alguna manera para comunicar dichos datos a LabView? Me ayudaría bastante! Oh si tienen algún otro tutorial para esto, se los agradecería mucho...

    ResponderEliminar
  7. consulta,alguien me podria ayudar.....en el monitor serie me toma o lee el sensor....(aclaro que tengo uno solo) ,pero no me muestra la temperatura...que podra ser?ya verifique varias veces el conexionado y nada....

    ResponderEliminar
  8. Deseo un curso de arduino para elaborar un decibelimetro, para detectar ruidos en el hogar.

    ResponderEliminar
  9. disculpa seria posible almacenar estos datos en una tarjeta sd?

    ResponderEliminar
    Respuestas
    1. Efectivamente, podrias usar una shield como esta para hacer datalogging:

      http://www.cetronic.es/sqlcommerce/disenos/plantilla1/seccion/producto/DetalleProducto.jsp?idIdioma=&idTienda=93&codProducto=999334016&cPath=1342

      Eliminar
  10. Buenos días, Me empiza midiendo correctamente; al rato aparacen medidas de -127 de forma aleatoria, para terminar todas las medidas en -127 y no se porque.
    Probé con un segundo sensor, y le pasó lo mismo.
    Estoy pensando que -127 corresponde a todos ceros en complemento a dos, creo, y que el sensor me envie todo ceros?

    ResponderEliminar
    Respuestas
    1. Tenia el mismo problema hasta que incorpore la resistencia de 4,7K al circuito. Midiendo con el tester debe llegar casi a 5v para que arduino reconozca el sensor.
      Con respecto al Sketch anda bien. Muchas Gracias Cetronic!

      Eliminar
  11. Es dificil saber el motivo, puede deberse a problemas de estabilidad del sensor o de la placa o a defectos del conexionado o de la resistencia utilizada.

    ResponderEliminar
  12. Hola, muy buen tutorial, partiendo de que soy muy novato, sería posible hacer esto con varios sensores dht22, me refiero a unificarlos en un solo pin y buscar la dirección de cada uno?
    Gracias

    ResponderEliminar
    Respuestas
    1. No es posible, los sensores de la serie DHTXX no son compatibles con el protocolo One Wire, con lo que requieren de pines independientes para enviar las lecturas

      Eliminar
    2. Ok muchas gracias, por otro lado, tu tutorial me ha sevido para hacer funcionar las sondas, pero me gustaría poder activar una serie de reles de una placa de 8 relés, con los dht22 ya lo he conseguido gracias a otro tutorial pero los ds18b20 no se como. He intentado hacerlo como los dht pero no lo consigo, soy demasiado novato,un saludo, y gracias

      Eliminar
  13. Muchas gracias por el tutorial,la verdad es muy bueno,os quisiera preguntar¿como se podria monitorizar las temperaturas de los sensores sin tener conectado arduino al pc?yo habia pensado que a lo mejor con un modulo wifi o bluetooth se podria pero soy novato y me gustaria si sabeis como,un saludo y gracias

    ResponderEliminar
    Respuestas
    1. Efectivamente con modulos ethernet, wifi o bluetooth podrias hacerlo, te dejo unos enlaces:

      http://www.cetronic.es/sqlcommerce/disenos/plantilla1/seccion/producto/DetalleProducto.jsp?idIdioma=&idTienda=93&codProducto=151185007&cPath=1342

      http://www.cetronic.es/sqlcommerce/disenos/plantilla1/seccion/producto/DetalleProducto.jsp?idIdioma=&idTienda=93&codProducto=999334020&cPath=1342

      http://www.cetronic.es/sqlcommerce/disenos/plantilla1/seccion/producto/DetalleProducto.jsp?idIdioma=&idTienda=93&codProducto=999334043&cPath=1342

      Eliminar
    2. Por ejemplo, desde el celular podes hacer la lectura mediante bluetooth realizando una app con https://appinventor.mit.edu/
      Entre otras.

      Eliminar
  14. Kisiera saber como conectar una pantalla lcd con los sensores y asi mostrar en la pantalla la temperatura!! Are un proyecto de una encuvadora de huevo!! Ayudenme porfavor

    ResponderEliminar