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_PORT, char DS18x20_PIN, char *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 ); } }
No caso eu quero utilizar o DS18B20 poderia me informar oq devo fazer? Estou utilizando C no HI-TECH
ResponderExcluirse 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
ExcluirBoa Noite, alguem já testou este codigo, copiei mais não estou conseguindo ler o ds18b20.
ResponderExcluirFuncionou perfeitamente, muito obrigado !
ResponderExcluirBoa 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
ResponderExcluirrecomendavel deixa em 10 bits na programacao pq ele da atrasos de leitura e/ou leituras incorretas!
Excluirpessoal 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 )
ResponderExcluirDS18S20_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?
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?
ResponderExcluirOlá, 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?
ResponderExcluirProblema solucionado, encontrei a pinagem correta. Valeu por disponibilizar este incrível código!
ExcluirOlá, tudo bem?
ResponderExcluirPrecisaria desse código, para um termostato (sem LCD)... Tentei adaptar uma leitura com bloco if da temperatura para ativar um cooler, mas não obtive sucesso... Quebrando cabeça aqui...
Teria como me ajudar?
Obrigado!
Alguem conseguiu usar esse código? Não está funcionando aqui.
ResponderExcluirBoa noite! Ótimo conteúdo! Tenho uma dúvida. Qual é o procedimento de atualização da resolução. No código, a atualização não é automática, ou seja, não existe nenhuma chamada da função "DS18B20_Set_Resolution( char *DS18x20_PORT, char DS18x20_PIN, char res )". Como então, por favor, atualizarei a resolução? Desde já, obrigado!
ResponderExcluir