11 abril 2013

Sensor de temperatura DS18B20 - Continuação

Continuando o assunto do sensor de temperatura DS18B20, hoje vou abordar a identificação e utilização desses sensores.

Encontrei muitos artigos na internet falando sobre esse sensor, mas poucos explicando como utilizá-los em quantidade, afinal, uma das grandes vantagens desse sensor é que você pode utilizar vários deles usando uma única porta do Arduino.

Partindo desse principio, vou apresentar um circuito com 2 sensores, e vamos utilizar 2 programas para :

1 - Identificar o endereço físico de cada sensor
2 - Utilizar esse endereço físico para obter a temperatura do sensor desejado

Os exemplos, com as alterações de praxe (traduções/comentários), foram retiradas do site Hacktronics :

Monte o circuito abaixo, tomando cuidado com a pinagem do sensor :

sensor de temperatura DS18B20
Obs : Utilizei resistores de 4K7

Baixe as bibliotecas abaixo, e copie para a pasta LIBRARIES da IDE do seu Arduino :

Biblioteca OneWire :

Biblioteca Dallas :

Agora carregue o programa abaixo, que vai identificar os endereços físicos dos sensores:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Programa : Scan DS18B20
// Alterações : Arduino e Cia
// Este programa procura pelos sensores no circuito e mostra o valor 
// do endereço físico de cada sensor no Serial Monitor

#include <OneWire.h>

// Conecte o pino central dos sensores ao pino 10 do Arduino
OneWire  ds(10);  

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

void discoverOneWireDevices(void) 
{
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

  Serial.print("Procurando dispositivos DS18B20...\n\r");

  while(ds.search(addr)) 
  {
    Serial.print("\n\rEncontrado sensor \'DS18B20\' com endereco:\n\r");
    for( i = 0; i < 8; i++) 
    {
      Serial.print("0x");
       if (addr[i] < 16) 
       {
        Serial.print('0');

       }
      Serial.print(addr[i], HEX);

       if (i < 7) 
       {
        Serial.print(", ");
       }

    }

    if ( OneWire::crc8( addr, 7) != addr[7]) 
    {
        Serial.print("CRC nao e valido!\n");
        return;
    }
  }
  Serial.print("\n\r\n\rFinal da verificacao.\r\n");
  ds.reset_search();
  return;
}

void loop(void) 
{
  // Loop Vazio
} 

Após transferir o programa para o Arduino, abra o Serial monitor, e você verá uma tela como essa, mostrando o endereço de cda DS18B20 :

Serial monitor - Scan DS18B20

Agora que você já tem o endereço de cada sensor, vamos utilizar um outro programa que vai usar os endereços obtidos acima, relacionar cada um com uma variável, e mostrar as temperaturas na tela :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Programa : Leitor temperatura sensores DS18B20
// Alterações : Arduino e Cia
// Este programa usa o endereço físico de cada sensor para mostrar as 
// informações de temperatura no Serial Monitor

#include <OneWire.h>

#include <DallasTemperature.h>

// Conectar o pino central dos sensores ao pino 10 do Arduino
#define ONE_WIRE_BUS 10

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer = { 0x28, 0xE1, 0x20, 0x9D, 0x04, 0x00, 0x00, 0x1A };
DeviceAddress outsideThermometer = { 0x28, 0xE5, 0x82, 0x9D, 0x04, 0x00, 0x00, 0x76 };
DeviceAddress dogHouseThermometer = { 0x28, 0x59, 0xBE, 0xDF, 0x02, 0x00, 0x00, 0x9F };

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(insideThermometer, 10);
  sensors.setResolution(outsideThermometer, 10);
  sensors.setResolution(dogHouseThermometer, 10);
}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) 
  {
    Serial.print("Erro ao ler temperatura !");
  } 
  else 
  {
    Serial.print("C: ");
    Serial.print(tempC);
    Serial.print(" F: ");
    Serial.print(DallasTemperature::toFahrenheit(tempC));
  }
}

void loop(void)
{ 
  delay(10000);
  Serial.print("Lendo temperaturas...\n\r");
  sensors.requestTemperatures();
  Serial.print("Temperatura Sensor 1: ");
  printTemperature(insideThermometer);
  Serial.print("\n\r");
  Serial.print("Temperatura Sensor 2: ");
  printTemperature(outsideThermometer);
  Serial.print("\n\r");
  Serial.print("Temperatura Sensor 3: ");
  printTemperature(dogHouseThermometer);
  Serial.print("\n\r\n\r");
}

Abra o serial monitor , para obter a temperatura dos sensores, em Celsius e Fahrenheit :

Lendo temperatura sensores DS18B20

Por enquanto é só. Mais informações sobre o sensor e como obter o datasheet você pode encontrar no meu artigo anterior sobre o DS18B20, clicando aqui.

54 comentários:

  1. mto bom o seu site. aguardo novos projetos !!
    principalmente usando arduino ethernet

    ResponderExcluir
    Respostas
    1. Obrigado ! Estou preparando alguns artigos sobre Arduino com Ethernet Shield. Valeu pela visita !

      Excluir
  2. Respostas
    1. Bom dia Gregório,

      Os 3 vão utilizar a mesma porta do Arduino. Dessa maneira, ligue o pino central do 2o. DS18B20 ao pino central do terceiro, e copie as ligações de Vcc, GND e o resistor.

      Abraço !

      Excluir
  3. Boa tarde,
    Gostaria de saber se consigo ter esse mesmo principio de diversos sensores para uma só uma porta do arduino, necessito fazer o controle de umidade de diversos pontos (20) e não tenho uma solução para isso.

    Obrigado,

    André Mattos

    ResponderExcluir
    Respostas
    1. Bom dia André,

      Estava dando uma olhada no datasheet do DS18B20, e ali diz que "como cada DS18B20 pode ser endereçado individualmente, o número de sensores que podem ser ligados à uma única porta é virtualmente ilimitado".

      Assim, creio que não há problemas em monitorar 20 sensores, mas tudo vai depender da distância entre eles, configurações elétrico/eletrônicas, etc.

      O datasheet do produto você encontra nesse link : http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf

      Abraço !

      Excluir
  4. Boa tarde,
    Tenho uma divida.
    Já tenho um arduino a funcionar com um shield para 9 sondas (sensores) a funcionar, mas...
    Com cabos até 1 metros funciona perfeitamente quando coloco cabos com mais cumprimento deixa de funcionar o que posso fazer para resolver?!

    Quero ter em browser 9 sondas de Comeras frigoríficas.

    Obrigado

    Ricardo Bravo

    ResponderExcluir
    Respostas
    1. Boa tarde Ricardo,

      Creio que você precisa de algum tipo de amplificador de sinal. Eu pessoalmente não conheço nenhum, mas nesse artigo aqui o pessoal fala sobre isso :

      http://lusorobotica.com/index.php?topic=5305.0

      Abraço !

      Excluir
  5. Ola, Muito Obrigado, Vlw.
    Mas gostaria de imprimir Apenas os numeros em celsius no LCD, como faço?

    ResponderExcluir
    Respostas
    1. Boa noite,

      Tente usar o esquema desse post, que usa também um sensor de temperatura, mas no caso é um LM35 :

      http://www.arduinoecia.com.br/2013/03/display-lcd-16x2-e-sensor-de.html

      Você vai conseguir adaptar facilmente para o DS18B20.

      Abraço !

      Excluir
  6. Bom dia amigo , gostaria de utilizar seu código, contudo estou tendo problema pois preciso que o mesmo funcione automaticamente , portanto gostaria de jogar o código do endereçamento junto com o outro para não precisar deste trabalho manual de copiar e colar . Você tem alguma ideia ou dica ? Outra coisa que gostaria de saber , é como é feita essa diferenciação dos endereços dos respectivos sensores ?
    Obrigado, abraço

    Att,
    Mateus Rodrigues Fonseca

    ResponderExcluir
    Respostas
    1. Boa noite Mateus,

      Estou sem esses sensores no momento, mas vou tentar comprar alguns e ver se consigo juntar os 2 códigos.

      Quanto aos endereços, cada sensor vem de fábrica com um endereço único.

      Abraço !

      Excluir
  7. Boa noite pessoal !!!

    Como posso utilizar individualmente os valores de temperatura para acionar as portas 1, 2 e 3 sempre que os valores registrados dos sensores forem maiores que 30 graus celsius ?

    Obrigado.

    ResponderExcluir
    Respostas
    1. Boa tarde Luis,

      Faça um IF para testar o valor da variável TempC

      if (TempC >= 30)
      {
      //comandos para acionar porta
      }

      Abraço !

      Excluir
  8. Olá, desejo utilizar os valores que são informados. Por exemplo: Se a temperatura de um sensor for maior que a do outro a temperatura maior deve aparecer na tela. Tem como realizar esse procedimento?

    ResponderExcluir
  9. Eu tenho uma diferença entre 2 e 3 graus para mais com esse sensor como posso corigir? eu usei um resistor de 10K será que é isso que ta dando a diferença? é que nao tenho um 4K7 para testar agora.

    ResponderExcluir
    Respostas
    1. Boa noite Rafael,

      Você tem um resistor de menor valor ? Faça um teste para ver se o erro permanece.

      Se tiver 2 resistores de 10K, coloque-os em paralelo para obter 5K. :)

      Abraço

      Adilson

      Excluir
    2. Era o resistor mesmo eu coloquei o resistor de 10k e ajustei a variavel sensors.setResolution para 12 dai deu certo ... Obrigado.

      Excluir
  10. Ola! Estou com as portas 8,9,10 e 11 sendo utilizadas para o motor de passo. Como devo proceder para fazer a identificação e ligações

    ResponderExcluir
  11. Como eu posso fazer para o meu sensor ds18b20 verificar se em 1 minuto ele teve uma alteração de mais 6 graus para ai eu dar o comando? alguem pode me ajudar?

    Tipo se eu 1 minuto a temperatura aumentar 6 graus faca tal comando ( eu vou colocar o comando ) caso contrario fica verificando a cada minuto se ouve essa diferenca para mais de 6 graus.

    ResponderExcluir
  12. na parte do codigo:

    float tempC = sensors.getTempC(deviceAddress);
    if (tempC == -127.00)
    {
    Serial.print("Erro ao ler temperatura !");
    }
    else
    {
    Serial.print("C: ");
    Serial.print(tempC);


    como posso fazer ele escrevrer na tela se eu tiver mais de um sensor qual é o sensor que apresentou erro?

    ResponderExcluir
    Respostas
    1. Bom dia Rafael,

      Eu não tenho esse sensor agora para testar, mas fica mais ou menos assim:

      float tempC = sensors.getTempC(deviceAddress);
      if (tempC == -127.00)
      {
      Serial.print("Erro ao ler temperatura do sensor: ");
      Seria.println((deviceAddress);
      }

      Abraço!

      Excluir
    2. Colocando esse codigo que vc me passou ele retorna esses erros:






      Codigo_Final_Arduino.ino: In function 'void printTemperature(uint8_t*)':
      Codigo_Final_Arduino:72: error: expected primary-expression before ')' token
      expected primary-expression before ')' token

      Excluir
  13. Ola amigo. Muito bom o post.. mas surgiu uma duvida, como faço para mostrar temperaturas negativas?

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Você vai precisar de um pequeno circuito auxiliar:

      http://electronics.stackexchange.com/questions/95911/lm35-negative-temperature-sensing-circuit

      Abraço!

      Excluir
  14. // set the resolution to 10 bit (good enough?)
    Estou com uma duvida nessa parte, para que server esses 10bit ?velocidade de transferencia ? algo do gênero ?

    ResponderExcluir
    Respostas
    1. Boa tarde Kelvin,

      Tem a ver com a precisão na leitura dos dados.

      Abraço!

      Excluir
  15. como posso ler um valor de temperatura analógico
    abraço

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Tente este artigo, por favor: http://www.arduinoecia.com.br/2013/02/lm35-sensor-de-temperatura.html

      Abraço!

      Excluir
  16. Como faco para exibir as temperaturas desse codigo no ethernet shild?

    ResponderExcluir
    Respostas
    1. Boa tarde Rafael,

      Nesse post aqui eu mostro o estado de um botão na Web usando o Ethernet Shield:

      http://www.arduinoecia.com.br/2013/06/ethernet-shield-wiznet-w5100-parte-2.html

      Você pode usar o mesmo princípio para exibir a temperatura.

      Abraço!

      Excluir
    2. Olá, obrigado pelo retorno, eu já tinha visto esse post seu, na verdade meu problema é somente em como exibir a variavel printTemperature(dogHouseThermometer); por exemplo pq nao mostra nada no html eu preciso fazer algo com ela pra exiba no html?

      Excluir
  17. boa tarde amigo, primeiro quero dar os parabens pelo post e ai vem uma duvida, rs, não estou conseguindo apresentar o valor lido pelo sensor no lcd, como posso proceder?

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Obrigado. Pelo serial monitor os valores aparecem normalmente ?

      Abraço!

      Excluir
    2. boa tarde, a minha duvida consegui solucionar antes de vc responder, mas em todo caso muito obrigado.

      Agora surgiu outra, meu medidor de temperatura fica travado no numero 85.00, alguma sugestao?

      Excluir
  18. Alguém já usou esse sensor com um ethernet shild? gostaria de um código para estudo.

    ResponderExcluir
  19. Testei e está dando erro na leitura de todos os sensores. O que pode estar acontecendo?

    ResponderExcluir
    Respostas
    1. Oi Roberto,

      Você está rodando o programa e ele não encontra nenhum sensor, é isso ?

      Abraço!

      Excluir
    2. Já encontrei onde estava o problema e tudo ficou ok. Agora tenho que montar o resto do projeto.

      Abraço,

      Excluir
    3. Valeu Roberto. Abraço! :)

      Adilson

      Excluir
  20. Gostaria de dar os parabéns pelo POST, projetos acontecem atraves deste. Prova disso é o meu, só que estou tendo problemas em printar os valores de deviceAddress sensor 1 e deviceAddress sensor 2 , quando incilializar , não estou sabendo printar os valores de s1 e s2, obrigado desde já.

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Muito obrigado. Você está falando do primeiro programa, certo ? Nada aparece na serial ?

      Abraço!

      Excluir
  21. da para usar esse esquema para o sensor sb19 ?

    ResponderExcluir
    Respostas
    1. Oi Bruno,

      Não tenho este sensor ainda... você encontrou no Brasil ?

      Abraço!

      Excluir
  22. Olá como faço para fazer a leitura com dois sensores em DUAS portas diferentes? Não estou conseguindo modificar o código pra essa situação. Obrigado! E parabéns pelo tópico, muito claro e objetivo!

    ResponderExcluir
  23. Olá, como faço para fazer a leitura de dois sensores com DOIS pinos diferentes (ex 2 e 3)? Tô tentando modificar o código acima, mas não tenho sucesso.

    ResponderExcluir
  24. Olá, alguém tem um pressostato funcionando com arduino?

    ResponderExcluir
  25. ola, estou realiznado leituras com o sensor ds18b20, as leituras estao sendo informadas na serial sem problemas, porem outras funcoes como servidor HTTP que esta rodando no arduino simplesmente param de funcionar, se desabilitar a leitura de temperatura o servidor HTTP volta a funcionar, alguma explicacao para isso?

    ResponderExcluir
    Respostas
    1. Oi Paulo,

      Isso pode ser algum conflito de bibliotecas.... veja se não utilizando os mesmos pinos de controle, por exemplo...

      Abraço!

      Excluir
  26. Olá, muito bom seu site e seu artigo! Mas tenho uma questão relevante:

    Para aplicações com mais de um sensor realmente é necessário adicionar um resistor de 4.7k para cada um?
    Se você olhar bem todos vão ser conectados em paralelo por utilizarem os mesmos pontos. O +5V é o mesmo para todos os sensores e todos os terminais de dados estarão unidos também para que seja feita a leitura por apenas um pino do Arduino, então quanto mais resistores colocarmos menor a resistência equivalente pois todos estarão em paralelo.

    Isso não afetaria negativamente o sistema? Parece mais lógico que se mantenha sempre apenas um resistor de 4.7k.

    Obrigado!

    ResponderExcluir
    Respostas
    1. Boa tarde !

      Boa questão, vou ver se consigo mais sensores para fazer um teste.

      Abraço e obrigado!

      Excluir
  27. Olá, parabéns pelo artigo!!!! Qual sensor vc indica para trabalhar com o arduino que consiga ler até 200°C. Obrigado

    ResponderExcluir
  28. Olá, como o arduino consegue identificar a alteração de tensão na saída do sensor, ligado diretamenteo na entrada digital do mesmo? não usaria uma entrada analogica para isso?

    ResponderExcluir
    Respostas
    1. Oi Vitor,

      Não é pela variação de tensão na saída do sensor. Ele usa OneWire: http://playground.arduino.cc/Learning/OneWire

      Abraço!

      Excluir