Fork me on GitHub

21/09/13

PIC: DS18S20 e DS18B20

PIC: DS18S20 e DS18B20


Neste post mostrarei como utilizar o sensor de temperatura DS18B20 e DS18S20 com o PIC. Este sensor utiliza o protocolo One-Wire, e requer apenas um fio de comunicação.



Mostrarei o jeito mais simples de realizar a leitura do sensor. Criei uma função que faz a leitura e salva em uma string prontinha pra ser escrita num display de LCD.


BIBLIOTECA
#include <built_in.h>

#define RES9 3
#define RES10 2
#define RES11 1
#define RES12 0

static char resolution = 0;

void DS18B20_getTemp( char *DS18x20_PORT, char DS18x20_PIN, char *outTemp )
{
unsigned temp, Temp_f;
char i;

 Ow_Reset( DS18x20_PORT, DS18x20_PIN );
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0xCC );  //Skip ROM
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0x44 );  //Inicia a conversao
    
 //Espera o tempo da conversao
 for(i = 0; i < (1 << (3 - resolution)); i++)
    Delay_ms( 95 );
    
 Ow_Reset( DS18x20_PORT, DS18x20_PIN );
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0xCC );  //Skip ROM
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0xBE );  //Inicia a leitura
    
 Lo(temp) =  Ow_Read( DS18x20_PORT, DS18x20_PIN );
 Hi(temp) =  Ow_Read( DS18x20_PORT, DS18x20_PIN );
    
 outTemp[0] = 32;
 outTemp[4] = '.';

 if(Hi(temp).B7)
 {
     temp = ~temp + 1;
     outTemp[0] = '-';
 }
        
 temp <<= 4;
 Lo(temp) >>= ( 4 + resolution );
 Temp_f = Lo(temp) * 625;

 outTemp[1] = Hi(temp) / 100 + '0';
 outTemp[2] = (Hi(temp) / 10) % 10 + '0';
 outTemp[3] = Hi(temp) % 10 + '0';
 outTemp[5] = Temp_f / 1000 + '0';
 outTemp[6] = (Temp_f / 100) % 10 + '0';
 outTemp[7] = (Temp_f / 10) % 10 + '0';
 outTemp[8] = (Temp_f % 10) + '0';
 outTemp[9] = 223; //simbolo de graus 
 outTemp[10] = 'C';
 outTemp[11] = 0;
}

void DS18S20_getTemp( char *DS18x20_PORT, char DS18x20_PIN, char *outTemp )
{
unsigned temp;
 Ow_Reset( DS18x20_PORT, DS18x20_PIN );
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0xCC );  //Skip ROM
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0x44 );  //Inicia a conversao
    
 //Espera o tempo da conversao
 Delay_ms( 750 );
    
 Ow_Reset( DS18x20_PORT, DS18x20_PIN );
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0xCC );  //Skip ROM
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0xBE );  //Inicia a leitura
    
 Lo(temp) =  Ow_Read( DS18x20_PORT, DS18x20_PIN );
 Hi(temp) =  Ow_Read( DS18x20_PORT, DS18x20_PIN );
    
 outTemp[0] = 32;
 outTemp[4] = '.';
 
 if(Hi(temp).B7)
 {
   Lo(temp) = ~Lo(temp);
   outTemp[0] = '-';
 }
        
 outTemp[5] = (Lo(temp).B0 == 1) ? '5' : '0';
 Lo(temp) >>= 1;
 outTemp[1] = Lo(temp) / 100 + '0';
 outTemp[2] = (Lo(temp) / 10) % 10 + '0';
 outTemp[3] = Lo(temp) % 10 + '0';
 outTemp[6] = 223;
 outTemp[7] = 'C';
 outTemp[8] = 0;
}

void DS18B20_Set_Resolution( char *DS18x20_PORT, char DS18x20_PIN, char res )
{
 resolution = res;
 Ow_Reset( DS18x20_PORT, DS18x20_PIN );
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0xCC );  //Skip ROM
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0x4E );  //Write Scratchpad
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0 );  //Th
 Ow_Write( DS18x20_PORT, DS18x20_PIN, 0 );  //Tl
 Ow_Write( DS18x20_PORT, DS18x20_PIN, (0x1F | (res << 5)) );  //Config
 Ow_Reset( DS18x20_PORT, DS18x20_PIN );
}


DS18B20_getTemp( char *DS18x20_PORT, char DS18x20_PIN, char *outTemp )
DS18S20_getTemp( char *DS18x20_PORTchar DS18x20_PINchar *outTemp )
*DS18x20_PORT - Porta onde está conectado o sensor.
DS18x20_PIN - Pino onde está conectado o sensor.
*outTemp - String onde será salvo o valor da temperatura.

DS18B20_Set_Resolution( char *DS18x20_PORT, char DS18x20_PIN, char res )
res - Resolução:
RES9 - 9 Bits de resolução
RES10 - 10 Bits Bits de resolução
RES11 - 11 Bits Bits de resolução
RES12 - 12 Bits Bits de resolução



EXEMPLO:
MikroC PRO PIC
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;

//COPIE E COLE O CÓDIGO ACIMA AQUI!!!

char Temperatura[12];

void main()
{
   CMCON = 0x07;
   Lcd_Init();
   Lcd_Cmd( _LCD_CURSOR_OFF );
   
   while(1)
   {
      //Faz a leitura do sensor DS18B20 conectado no pino RA0
      Ds18B20_getTemp( &PORTA, 0, Temperatura );
      
      Lcd_Out( 1, 1, Temperatura );
      
      //Faz a leitura do sensor DS18S20 conectado no pino RA1
      Ds18S20_getTemp( &PORTA, 1, Temperatura );
      
      Lcd_Out( 2, 1, Temperatura );
   }
}

10 comentários:

  1. No caso eu quero utilizar o DS18B20 poderia me informar oq devo fazer? Estou utilizando C no HI-TECH

    ResponderExcluir
    Respostas
    1. se reparar no exemplo ele usa DS18B20_gettemp para obter temperatura do DS18B20! agora HITECH nao seria como ficaria o codigo! eu mexo mto com MIKROC

      Excluir
  2. Boa Noite, alguem já testou este codigo, copiei mais não estou conseguindo ler o ds18b20.

    ResponderExcluir
  3. Funcionou perfeitamente, muito obrigado !

    ResponderExcluir
  4. Boa tarde , obrigado pelo código, mas estou com um problema , no simulador a resolução funciona 12bist perfeitamente, mas quando jogo na placa ele mostra resolução de de 10bits ou seja de 0,5 a 0,5 ºc . Vc poderia mim ajudar. meu e-mail e gr1_automacao@hotmail.com

    ResponderExcluir
    Respostas
    1. recomendavel deixa em 10 bits na programacao pq ele da atrasos de leitura e/ou leituras incorretas!

      Excluir
  5. pessoal boa tarde, estou tendo dificuldade em algumas comandos dessa programação, na biblioteca do sensor DS18B20_getTemp( char *DS18x20_PORT, char DS18x20_PIN, char *outTemp )
    DS18S20_getTemp( char *DS18x20_PORT, char DS18x20_PIN, char *outTemp ), eu tenho que mudar o port, pin e outtempo certo? esse outtemp que numero ou qual comando tenho que colocar?
    e DS18B20_Set_Resolution( char *DS18x20_PORT, char DS18x20_PIN, char res ) eu tambem tenho que mudar o port, pin, e char res? se eu quero 10bits eu tenho que colocar RES10 ou só 10? estou utilizando o pic16f877A, e nao to conseguindo ler o valor dos sensores no PORTA RA1 e RA0, o que mais da biblioteca ou programação teria que mudar?

    ResponderExcluir
  6. boa noite; trabalho com um equipamento que tem sua temperatura monitorada por um sensor DS1820. O sensor queimou e subistitui pelo ds18b20, porem, os numeros mostrados no display estao muito estranhos; isto tem haver com a resolução?

    ResponderExcluir
  7. Olá, tudo bom? Cara eu não consigo de jeito nenhum mostrar a temperatura, sempre fica em 0.00. Já tentei de tudo e nada acontece, o meus sensor DS18B20 é encapsulado, por isso fica dificil a identificação do pino. Mas, fui testando de um a um e mesmo assim não consegui mostrar nenhuma temperatura, o que pode ser?

    ResponderExcluir
    Respostas
    1. Problema solucionado, encontrei a pinagem correta. Valeu por disponibilizar este incrível código!

      Excluir

Postagens Relacionadas!!