|     Inicio    |   |         |  |   FOROS      |  |      |      
   Elastix - VoIP B4A (Basic4Android) App inventor 2 PHP - MySQL
  Estación meteorológica B4J (Basic4Java) ADB Shell - Android Arduino
  AutoIt (Programación) Visual Basic Script (VBS) FireBase (BD autoactualizable) NodeMCU como Arduino
  Teleco - Emisora de A.M. Visual Basic Cosas de Windows Webs interesantes
T Búsqueda en este sitio:


.

Arduino en español
Circuitos con Arduino - Juan Antonio Villalpando

-- Tutorial de iniciación a Arduino --

Volver al índice del tutorial

___________________________

24.- Sensor de temperatura. DS18B20.

- Mediante un sensor podemos obtener la temperatura ambiente.

- Vamos a utilizar el DS18B20 Digital Temperature Sensor. (-55~125'C). (error ~0,5º)

- Lo podemos encontrar en un módulo pequeño o en solitario.

- Podemos comprar el módulo tal cual, o bien el sensor solitario y añadirle en el conexionado una resistencia de 4,7 K

_________________
- Patillaje.

En módulo

Se puede encontrar por 1,2 € en Aliexpress.

Fíjate que la secuencia de patillaje no es la misma que la del sensor.

Tiene una resistencia de 4,7K.

Solo sensor

Se puede encontrar por 0,7 € en Aliexpress.

Es conveniente comprar al menos tres unidades para realizar pruebas.

Es mejor comprar este modelo que el módulo de la izquierda.

Necesita una resistencia de 4,7K.

Dallas

ds1820-report.pdf

DS18B20.pdf

_________________
- Conexionado.

- Cuidado con la secuencia de terminales en el módulo y en el sensor, no es la misma.

 

Conexionado con el módulo. El módulo ya tiene soldada la resistencia SMD de 4k7.
(Si te fijas sobre la Resistencia R1, está escrito 472, esto significa 47 y dos cero: 4700)

 





Conexionado con el sensor. Necesita una resistencia de 4K7 conectada entre el terminal positivo y el DQ (terminal intermedio).

Esta es otro forma de conectarlo, fíjate que cuando hay un solo sensor de temperatura, como en este caso, no es necesario conectar el terminal de la derecha.

La información va por un solo hilo, es lo que se llama one wire.

_________________
- L
ibrería OneWire.

http://www.pjrc.com/teensy/td_libs_OneWire.html

http://forum.arduino.cc/index.php?topic=18231.30

Si estás utilizando IDE 1.X.X bájate esta librería: OneWire.zip.

Esta librería utiliza solo dos cables uno de datos y otro de GND para enviar la información. Le línea de datos de toma de terminales DIGITALES.

La descomprimes. Copia la carpeta OneWire en la subcarpeta libraries de tu Arduino.

Una librería, en realidad la traducción sería biblioteca, es un controlador, un driver para manejar un dispositivo, en este caso el DS18B20

(Utiliza esta vieja versión de librería: OneWire2.zip si estás utilizando IDE antiguo como el 0022 que crean archivos .pde)

_________________
- Código.

- Está en la carpeta examples de la librería.

- Gran parte de este código es para obtener y presentar el código del sensor, puedes eliminar muchas de esas líneas.

- Este código detecta si hay más de un sensor conectado al pin10 y presenta la temperatura de todos ellos. Más abajo en esta página se verán una conexión con varios sensores.

Código
#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)

void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}

_________________
- Monitor Serial.

Para ver la temperatura entramos en el Serial Monitor.

Obtendremos la Temperatura actual cada segundo.

La salida de datos es de la forma:

Data = 1 A1 1 4B 46 7F FF C 10 D9 CRC=D9

- La temperatura se obtiene: 1 x 256 + (10 x 16 + 1) = 417

417 / 16 = 26,06 º

_____________________________
2.- Encender/apagar el LED13.

Vamos a modificar el programa para que cuando la temperatura sea mayor de 26º se encienda el LED13

Añadimos al código anterior, las líneas rojas.

Enciende/apaga LED13

void setup(void) {
Serial.begin(9600);
pinMode(13, OUTPUT);
}

............................................

celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");

if (celsius > 26.0){
digitalWrite(13, HIGH);}
else {
digitalWrite(13, LOW);
}


}

 

Podemos hacer que en vez de encender un LED, suene un sonido mediante un BUZZER.

_____________________________
3.- Varios sensores de temperatura.

- Si tenemos varios sensores podemos realizar el montaje de la figura. Este tipo de conexión se denomina modo de alimentación parásito.
- Todo los terminales 1 van a Gnd.
- Los terminales centrales van al Pin10 del Arduino y a la resistencia de 4K7.
- El otro extremo de la resistencia va a 5V del Arduino.
- Los terminales de la derecha de los sensores no se conectan. Van al aire.

- Cada sensor medirá la temperatura del lugar donde se encuentre.

- El código es el mismo que hemos visto al principio de esta página.

- En el Serial Monitor veremos la temperatura de los tres sensores.

También se puede hacer este montaje, pero da los mismos resultados que el anterior.

Las características del 18B20 nos dice esto:

Optional VDD. VDD must be grounded for operation in parasite power mode.

Es decir, si utilizamos un solo elemento, podemos dejar el terminal Vdd de la derecha al aire. Si lo conectamos en modo parásito lo debemos llevar a Gnd, sin embargo en pruebas realizadas presentan la misma temperatura.

Hoja de datos

_________________________________

4.- Visualización en pantalla LCD.

- Le echamos un vistazo al tutorial 31pantallaLCD.htm

- Vamos a acoplar a nuestro proyecto la pantalla LCD que vimos en un tutorial anterior, esta pantalla va a funcionar en modo bus I2C.

- Se presentará en la pantalla los tres valores de temperatura secuencialmente.

He unido los dos códigos el del sensor de temperatura visto en esta página y el de la pantalla LCD.

En este código las temperaturas aparecen secuencialmente.

Código
// Librerías para pantalla LCD
#include <Wire.h>                 
#include <LiquidCrystal_I2C.h>    
// LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// Librería para sensores
#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)

void setup(void) {
  Serial.begin(9600);
  lcd.begin(16,2);// Columnas y filas de LCD  
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
  
  ////////// Presentación en la pantalla LCD.
 /////////// Código añadido. 
  
  lcd.clear(); // Borra pantalla
  lcd.setCursor(0,0); // Inicio del cursor
  lcd.print(celsius);
  delay (2000);
  lcd.clear();
  lcd.setCursor(3,1); // Siguiente renglón.
  lcd.print("KIO4.COM");
  delay (1000);
  
}

___________________________

- Este es un código parecido al anterior, en este caso salen las tres temperaturas a la vez, en la variable de cadena todos, se van

acumulando las tres temperaturas, luego se presentan y se borra la variable todos para recibir a otras tres.

30.50 30.44 30.5

Código
// Librerías para pantalla LCD
#include <Wire.h>                 
#include <LiquidCrystal_I2C.h>    
// LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// Librería para sensores
#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)
String todos;

void setup(void) {
  Serial.begin(9600);
  lcd.begin(16,2);// Columnas y filas de LCD  
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
  ///// Presentación en la pantalla LCD
  ///// 30.50 30.44 30.5 
  // Modificado por Juan A. Villalpando
  // KIO4.COM
  // lcd.clear(); // Borra pantalla
  lcd.setCursor(0,0); // Inicio del cursor
  lcd.print(todos);
  todos="";
  lcd.setCursor(4,1); // Siguiente renglón.
  lcd.print("KIO4.COM");
  delay (1000);
    
    
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
  
  ////////// Presentación en la pantalla LCD.
 /////////// Código añadido. 
  todos =todos + celsius + " ";
 
}

_________________________________

- I2C.

En estos ejemplos podemos ver otros sensores de temperatura y el bus de comunicación I2C.

Vídeo sobre I2C. Sensor de temperatura:
http://tallerarduino.wordpress.com/2012/04/27/arduino-tutorials-cap-6-i2c-comunication/

I2C

http://atc.ugr.es/~afdiaz/fich/bus_i2c.pdf

http://www.uco.es/~el1mofer/Docs/IntPerif/Bus%20I2C.pdf

________________________________

- Mi correo:
juana1991@yahoo.com
- KIO4.COM - Política de cookies. Textos e imágenes propiedad del autor:
© Juan A. Villalpando
No se permite la copia de información ni imágenes.
Usamos cookies propias y de terceros que entre otras cosas recogen datos sobre sus hábitos de navegación y realizan análisis de uso de nuestro sitio.
Si continúa navegando consideramos que acepta su uso. Acepto    Más información