GraffZeppelin
New Member
Hello all,
In the last three days I was struggling to read temperature data from a single DS18B20 when using non-parasitic OneWire protocol and a PIC18F4550. Finally I had a break-trough (at least I think I have), when I decided to take baby steps and : 1. Read a presence pulse; 2. Read device family code; 3. Attempt to read temperature data. So far points 1 and 2 were accomplished successfully, I was able to read the presence pulse (0) and a family code (0x28). But the last point, I am still struggling bad. I understand that in order to read temperature values, I first need to write a command to convert temperature (0x44), then reset the OneWire, give a 0.75s delay for the conversion to be completed, and then write to the scratchpad 0xBE to read from the register. I've tried combining the codes I found in maxim website and as well some other codes I found all over the web. LCD now displays Temperature: 11, when my room temperature is currently ~27 degrees C. Please can someone check my codes to see whether there is an issue somewhere? Thanks!
DS18B20 config.h
And the main code:
In the last three days I was struggling to read temperature data from a single DS18B20 when using non-parasitic OneWire protocol and a PIC18F4550. Finally I had a break-trough (at least I think I have), when I decided to take baby steps and : 1. Read a presence pulse; 2. Read device family code; 3. Attempt to read temperature data. So far points 1 and 2 were accomplished successfully, I was able to read the presence pulse (0) and a family code (0x28). But the last point, I am still struggling bad. I understand that in order to read temperature values, I first need to write a command to convert temperature (0x44), then reset the OneWire, give a 0.75s delay for the conversion to be completed, and then write to the scratchpad 0xBE to read from the register. I've tried combining the codes I found in maxim website and as well some other codes I found all over the web. LCD now displays Temperature: 11, when my room temperature is currently ~27 degrees C. Please can someone check my codes to see whether there is an issue somewhere? Thanks!
DS18B20 config.h
Code:
#define __XTAL_FREQ 8000000
#define Data_pin RB2
#define Data_bus TRISB2
#define Skip_ROM 0xCC // 0b11001100
#define Convert_temperature 0x44 // 0b01000100
#define Read_scratchpad 0xBE // 0b10111110
#define Read_deviceFamily 0x33
int OneWire_reset()
{
Data_bus = 0; //Set as output
Data_pin = 0; //Drive Low
__delay_us(480);
Data_bus = 1; //Release, Set back as input
__delay_us(70);
if (Data_pin == 0) // Sample bus
{
__delay_us(410);
return 0; // Device present
}
else
{
__delay_us(410);
return 1; // No device present
}
}
int OneWire_readByte(void)
{
int l, result = 0;
for(l=0;l<8;l++)
{
result >>= 1;
if(OneWire_readBit())
result |= 0x80;
}
return result;
}
int OneWire_readBit(void)
{
unsigned int Read_state = 0;
Data_bus = 0; //Set as output
Data_pin = 0; //Drive low
__delay_us(6);
Data_bus = 1; //Release, set as input
__delay_us(9);
Read_state = Data_pin;
return Read_state;
}
void OneWire_writeBit(unsigned int b)
{
Data_bus = 0; //Set as output
Data_pin = 0; //Drive low
if(b == 1)
{
__delay_us(3);
Data_bus = 1; //Release, set as input
__delay_us(62);
}
else
{
__delay_us(57);
Data_bus = 1; //Release, set as input
__delay_us(7);
}
}
void OneWire_writeByte(unsigned int data)
{
int l;
for(l=0;l<8;l++)
{
OneWire_writeBit(data & 0x01);
data >>= 1;
}
}
And the main code:
Code:
#define _XTAL_FREQ 8000000
#include <xc.h>
#include <stdio.h>
#include "LCD_4bit_config.h"
#include "DS18B20_config.h"
#include "delay.h"
OneWire_init()
{
int i;
char buf1[10];
char buf2[10];
LCD_setCursor(1,1);
LCD_writeString("Presence:");
i = OneWire_reset();
sprintf(buf1,"%d",i);
LCD_setCursor(2,1);
LCD_writeString(buf1);
delay_ms(3000);
LCD_clr();
OneWire_reset();
LCD_setCursor(1,1);
LCD_writeString("Device family:");
OneWire_writeByte(Read_deviceFamily);
i = OneWire_readByte();
sprintf(buf2,"%d",i);
LCD_setCursor(2,1);
LCD_writeString(buf2);
delay_ms(3000);
LCD_clr();
OneWire_reset();
}
void main()
{
char temp_lsb,temp_msb,temp;
char buf3[10];
char getBit[10];
int k;
OSCCON = 0b11110010; // Set PIC18F4550 internal oscillator at 8MHz
ADCON1 = 0x0F; // Set all pins as digital I/O
CMCON = 0x07; // Set all comparators as digital I/O
LATD = 0; // Clear port D
TRISD = 0b00000000; // Set all port D pins as digital outputs
LATB = 0;
TRISB = 0x00;
LCD_init(); // Initialize LCD
OneWire_init();
while(1)
{
if (!OneWire_reset())
{
LCD_setCursor(1,1);
LCD_writeString("Temperature:");
OneWire_writeByte(Skip_ROM);
OneWire_writeByte(Convert_temperature);
OneWire_reset();
delay_ms(750);
OneWire_writeByte(Skip_ROM);
OneWire_writeByte(Read_scratchpad);
for (k=0;k<9;k++)
{
getBit[k] = OneWire_readByte();
}
temp_msb = getBit[1];
temp_lsb = getBit[0];
temp = (temp_msb << 8) + temp_lsb;
temp = temp >> 4;
sprintf(buf3,"%d",temp);
LCD_setCursor(2,1);
LCD_writeString(buf3);
delay_ms(1000);
}
}
}