Tutorial: como utilizar o Sensor de temperatura DS18B20 (prova de água) com Arduino

Adquira estes componentes na Loja do Lab de Garagem

Neste tutorial vamos mostrar como utilizar o sensor de temperatura DS18B20 à prova de água com Arduino. Este sensor utiliza o protocolo digital de apenas um fio (One Wire), portanto apenas uma porta digital para comunicação.

Para fazer as ligações, o sensor contém três fios: um vermelho (VCC), um preto (GND) e um branco (Dados). Conecte o vermelho no 5V do Arduino e o preto no GND do Arduino. Conecte o fio branco no pino digital 10 e um resistor de 4k7 ohm entre o fio branco e o VCC (resistor de Pull-Up). Para maiores informações sobre o sensor utilizado, clique aqui!

Agora que feito as ligações, baixe a biblioteca necessária aqui para fazer a leitura do sensor. Extraia a biblioteca OneWire para dentro da pasta "libraries" localizada dentro da pasta do Arduino. Abra a IDE do Arduino e cole a programação abaixo:

#include <OneWire.h>

int SensorPin = 10; 


OneWire ds(SensorPin); 

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

void loop(void) {
float temp = getTemp();
Serial.println(temp);

delay(100); 

}


float getTemp(){

byte data[12];
byte addr[8];

if ( !ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;
}

if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return -1000;
}

if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}

ds.reset();
ds.select(addr);
ds.write(0x44,1); 

byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); 


for (int i = 0; i < 9; i++) { 
data[i] = ds.read();
}

ds.reset_search();

byte MSB = data[1];
byte LSB = data[0];

float TRead = ((MSB 8) | LSB); 
float Temperature = TRead / 16;

return Temperature;

}

A programação acima adquire a temperatura em graus Celsius. O Arduino verifica se o sensor está conectado corretamente. Caso estiver, prossegue para a aquisição de dados. Para a aquisição de dados é necessário mandar um endereço para detectar o sensor, um endereço para a leitura dos dados do sensor. E depois o Arduino poder converter e mostrar a leitura exata no Serial Monitor.

Dentro da IDE do Arduino, selecione a versão da sua placa Arduino (UNO, Duemilanove, etc) e a porta (COMx, ttyUSBx, ttyACMx, etc) e depois clique em "UPLOAD". Ao terminar de fazer o "UPLOAD", abra a Serial Monitor e selecione "9600" de baud. Você verá o valor da temperatura adquirido pelo sensor em graus Celsius como mostra a figura abaixo:

E é isso! Esperamos que tenha gostado! Caso tenha dúvidas, poste aqui neste blog! Para sugestões de tutoriais, clique aqui! Para ver outros tutoriais e projetos desenvolvidos pela equipe LdG e por outros garagistas, clique aqui e aqui, respectivamente! Até a próxima!

Referências:

http://www.sparkfun.com/products/11050

http://bildr.org/2011/07/ds18b20-arduino/

http://www.arduino.cc/playground/Learning/OneWire

http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Temp/DS18B20...

Exibições: 56525

Comentar

Você precisa ser um membro de Laboratorio de Garagem (arduino, eletrônica, robotica, hacking) para adicionar comentários!

Entrar em Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)

Comentário de Antonio Vitor Elias Swaid Junior em 20 abril 2016 às 13:56

não saiu rsrs

float TRead = ((MSB "sinal de menor""sinal de menor" 8) | LSB); // da maneira mais difícil ;-)

Comentário de Antonio Vitor Elias Swaid Junior em 20 abril 2016 às 13:52

Sobre o exemplo, está bem legal. Mas tem um erro de sintaxe... Provavelmente por causa do caracter "sinal de menor".

O correto seria : float TRead = ((MSB 8) | LSB);

Se não sair, coloca dois sinais de menor juntos, entre o MSB e o 8 que vai funcionar. Aqui está funcionando legal. Outra coisa que fiz foi usar um resistor de 3.3k em vez de 4.7k. Não acheium de 4.7k em casa rsrs.

Obrigado.

Comentário de José Gustavo Abreu Murta em 22 março 2016 às 10:31

O resistor é usado somente para terminar o barramento, não ? 

Se for isso, não creio que o valor do resistor possa melhorar as medidas. 

Sugiro que coloque um capacitor de 10uF entre o 5V e o terra. 

Veja se melhora algo.

Comentário de LUCIO P PATROCINIO em 22 março 2016 às 8:27

Olá José, 

Considerando 4 sensores justapostos, não creio que seja uma variação normal dentro de um distância de menos de 4 mm. Quanto a tolerância, o fabricante afirmou que seria de 1%, porém os valores possui uma variação maior que 1%. Encontrei variações próximas de 3%. Conforme relatei anteriormente, não são variações grandes, porém são superiores a tolerância. Em um dos "posts" encontrei a informação que se o número de sensores associados ao mesmo resistor (4,7 kohm) for grande, recomenda-se a redução da resistência elétrica, porém não ficou claro o critério a ser adotado. Também não ficou claro o impacto do valor do resistor externo sobre a medida de temperatura. 

Comentário de José Gustavo Abreu Murta em 21 março 2016 às 16:57

Essa variação pode ser talvez uma variação normal dentro da sala. 

Ou então pode ser variação normal dentro da tolerância do sensor. 

Sabe nos informar qual é a tolerância do sensor ?

Comentário de LUCIO P PATROCINIO em 21 março 2016 às 13:21

Fiz uma ligação em “modo normal” de vários sensores (mais especificamente 4 sensores) DS18B20. Coloquei-os medindo a mesma posição no quarto, porém mostraram valores diferentes entre si. A diferença não é muito grande (em torno de meio grau celsius). Gostaria de saber se isso tem algo a ver com o resistor utilizado (4,7 kohm) e se eu poderia melhorar a precisão da medida usando resistores diferentes para cada sensor.

Comentário de Rafael em 31 outubro 2015 às 10:29

Se eu possuir mais de um sensor, como posso verificar qual deles está com problema caso um esteja. Retornando na tela o nome ou o codigo dele? desde ja agradeco 

Comentário de Robson Paula em 25 julho 2015 às 11:19

É tem sim um cocô:

Troque:

float TRead = ((MSB 8) | LSB);

Por:

float TRead = ((MSB, 8) | LSB);

Ah e dê a descarga! (Clicando em Upload kkkk)

Boa sorte!

Comentário de José Gustavo Abreu Murta em 21 janeiro 2015 às 23:46

Esse exemplo esta com erros, quem ninguém resolve.

E eu não vou quebrar o côco, tentando descobrir esse erro, que provavelmente é de compatibilidade de versões.

Procurei em vários lugares e descobri um exemplo que esta funcionando bem. 

http://playground.arduino.cc/Learning/OneWire

Baixei e instalei essa Biblioteca OneWire :

http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip

Como instalar uma Biblioteca:

http://arduino.cc/en/Guide/Libraries

Estou usando a versão mais atual do Arduino : ARDUINO 1.0.6

http://arduino.cc/en/Main/Software

A minha placa é Arduino 2009. 

Estou usando o pino Digital 10 para fazer as leituras.

Não copie esse Sketch, pois pode ter algum caracter suprimido.

Copiei aqui só para referência. 

Usei o exemplo DS18x20_Temperature dentro da pasta da Biblioteca OneWire.

#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");
}

Esse é um exemplo da Console com as leituras de temperaturas :

Comentário de ROBERTO NOYA GALLUZZO em 21 outubro 2014 às 19:16

o meu esta dando este erro. Alguem poderia me ajudar??

ketch_oct21a.ino: In function 'float getTemp()':
sketch_oct21a:49: error: expected `)' before numeric constant
sketch_oct21a:49: error: expected `)' before ';' token

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço