Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] ds18B20 and PIC18F4550

Status
Not open for further replies.

K33rg4t3

Full Member level 3
Joined
Aug 2, 2015
Messages
165
Helped
7
Reputation
14
Reaction score
7
Trophy points
1,298
Activity points
2,607
Hey guys
I am going to use it in weather station.
I use pIC18F4550 and DS18B20
Can anyone tell me few things?
1. Do I have to write One-wire code myself or is there a library in MikroC ?
2. Can I use any digital pin for communication or does it have to be a specific one like with TX/RX ?
Thanks in advance!
 

I have a copy but do not use it for programming. It appears there is a library with reset, write and read functions and it can be used on any pin.

Brian.
 
I have searched and found library with OW_Read, OW_Reset, OW_Write... but I need to use those functions myself to communicate with ds18B20?
 

Well, you don't HAVE to use them, you can write your own routines if you like, 1-Wire isn't difficult to program. If they are there already in the library you might as well use them though. There is no other way to use a DS18B20 than through a 1-Wire interface.

Brian.
 

It edoes not work - output is always a zeros string.
I have connected VCC to VCC, GND TO GND, and signal to port D2 with 4.7k pullup to VCC.

Code:
Code:
        OW_Reset(&PORTD, 2); // 'Reset command to initialize One-Wire
         OW_Write(&PORTD, 2, 0xCC); // 'Skip ROM Command
         OW_Write(&PORTD, 2, 0x44); // 'Convert_T command
         delay_ms(1200); // 'Provide delay for conversion


         OW_Reset(&PORTD, 2); // 'Reset command to initialize One-Wire
         OW_Write(&PORTD, 2, 0xCC); // 'Skip ROM Command
         OW_Write(&PORTD, 2, 0xBE); // 'Read Scratchpad Command
         TempL = OW_Read(&PORTD,2); //Read Temperature low byte
         TempH = OW_Read(&PORTD,2); //Read Temperature high byte
         DP = TempL & 0x01; // 'Check if Temperature is integer or fractional
         if (TempH){ //If reading is negative
            vDisp[0] = '-';
            TempL = ((~TempL) + 1) >> 1;
         }
         else{
             vDisp[0] = '+';
             TempL = TempL >> 1; // 'Shift one position right (divide by 2) to get integer reading and get rid of decimal point
         }
         vDisp[1] = (TempL / 100) + 48; // 'Get hundreds and convert to ASCII
         vDisp[2] = ((TempL / 10) % 10) + 48; // 'Get tens and convert to ASCII
         vDisp[3] = (TempL % 10) + 48; // 'Get units and convert to ASCII
         if (DP){ // 'If reading is fractional, ie has 0.5 at end
            vDisp[5] = '5';
         }
         else{ // 'If reading is a whole number
            vDisp[5] = '0';
         }

Please help...
 

This code work 100%. I wrote it few years ago and used many times in different project based on STM8 and STM32.
Header for 1-wire
Code:
#define Time_Pulse_Delay_Low	        10      //10
#define Time_Pulse_Delay_High	        40      //40
#define Time_Reset_Low			500
#define Time_After_Reset		350
#define Time_Hold_Down			10

#define One_Wire_Read_ROM		0x33
#define One_Wire_Skip_ROM		0xCC
#define One_Wire_Search_ROM		0xF0
#define One_Wire_Match_ROM		0x55

#define One_Wire_Success		0x00
#define One_Wire_Error_No_Echo	        0x01
#define One_Wire_Bus_Low_Error	        0x02
#define One_Wire_Device_Busy	        0x03
#define One_Wire_CRC_Error		0x04

unsigned int One_Wire_Reset(void);
void One_Wire_Write_Byte(unsigned char Byte);
unsigned char One_Wire_Read_Byte(void);
unsigned char One_Wire_Read_Bit (void);
void One_Wire_Write_Bit (unsigned char Bit);
Low level routines:
Code:
unsigned int One_Wire_Reset(void)								
{
	unsigned int tmp;
	if ((PIN_SYG(One_Wire_RX)))	return One_Wire_Bus_Low_Error;
	PIN_OFF(One_Wire_TX);
	delay_us(250);
        delay_us(250);
	PIN_ON(One_Wire_TX);
	delay_us(Time_Pulse_Delay_High);
	if ((PIN_SYG(One_Wire_RX))) tmp = One_Wire_Success;
		else tmp = One_Wire_Error_No_Echo;
	delay_us(250);
        delay_us(200);
	return tmp;
}

void One_Wire_Write_Byte(unsigned char Byte)
{
	unsigned char cnt;
	for (cnt=0;cnt!=8;cnt++) One_Wire_Write_Bit(Byte&(1<<cnt));
}

void One_Wire_Write_Bit (unsigned char Bit)
{
	PIN_OFF(One_Wire_TX);
	if (Bit==0)
	{
		delay_us(Time_Pulse_Delay_High);
		PIN_ON(One_Wire_TX);
		delay_us(Time_Pulse_Delay_Low);
	}
	else
	{
		delay_us(Time_Pulse_Delay_Low);
		PIN_ON(One_Wire_TX);
		delay_us(Time_Pulse_Delay_High);
	}
} 

unsigned char One_Wire_Read_Byte(void)
{
	unsigned char tmp=0;
	unsigned char cnt;
	for (cnt=0;cnt!=8;cnt++)
		if (One_Wire_Read_Bit()!=0)	tmp|=(1<<cnt);
	delay_us(Time_Pulse_Delay_High);
	return tmp;
}

unsigned char One_Wire_Read_Bit (void)
{
		unsigned char tmp;
		PIN_OFF(One_Wire_TX);
		delay_us(Time_Hold_Down);
		PIN_ON(One_Wire_TX);
		delay_us(Time_Pulse_Delay_Low);
		if ((PIN_SYG(One_Wire_RX))!=0)	tmp = 0;
			else tmp = 1;
		delay_us(Time_Pulse_Delay_High);
		return tmp;
}
DS18b20 communication:
Code:
unsigned char DS1822_Start_Conversion_Skip_Rom (void)			 
{	
	unsigned char tmp; 											
	tmp=One_Wire_Reset();
	if (tmp!=One_Wire_Success) return tmp;												
	One_Wire_Write_Byte(One_Wire_Skip_ROM);
	One_Wire_Write_Byte(DS1822_CONVERT_T_CMD);
	if (One_Wire_Read_Byte()==0)	return One_Wire_Success;
		else	return One_Wire_Device_Busy;
}
and reading values after conversion:
Code:
unsigned char DS1822_Read_Temp_NoCRC_Skip_Rom (unsigned int * temperatura)				 
{
	unsigned char tmp; 											
	tmp=One_Wire_Reset();
	if (tmp!=One_Wire_Success) return tmp;
	One_Wire_Write_Byte(One_Wire_Skip_ROM);
	One_Wire_Write_Byte(DS1822_READ_STRATCHPAD_CMD);
	* temperatura = One_Wire_Read_Byte()|(One_Wire_Read_Byte()<<8);
	return One_Wire_Success;
}
 

What is PIN_ON, PIN_SYG, PIN_OFF?
 

Why are there two pins?
One_Wire_RX
One_Wire_TX
?
My DS18B20 has only one data bi-directional pin.
 

Good notice! That was made for optical isolated 1-wire.
For single wire use this code:
Code:
unsigned int One_Wire_Reset(void)								
{
	unsigned int tmp;
        PIN_ON(One_Wire_Pin);
        PIN_OUT_OD(One_Wire_Pin);
	if ((PIN_SYG(One_Wire_Pin)==0))	return One_Wire_Bus_Low_Error;
        PIN_OFF(One_Wire_Pin);       	
	delay_us(250);
        delay_us(250);
        PIN_ON(One_Wire_Pin);
	delay_us(Time_Pulse_Delay_High);
	if ((PIN_SYG(One_Wire_Pin))) tmp = One_Wire_Error_No_Echo;
		else tmp = One_Wire_Success;
	delay_us(250);
        delay_us(200);
	return tmp;
}

void One_Wire_Write_Byte(unsigned char Byte)
{
	unsigned char cnt;
	for (cnt=0;cnt!=8;cnt++) One_Wire_Write_Bit(Byte&(1<<cnt));
}

void One_Wire_Write_Bit (unsigned char Bit)
{                
        PIN_OFF(One_Wire_Pin);
	if (Bit==0)
	{
		delay_us(Time_Pulse_Delay_High);
		PIN_ON(One_Wire_Pin);
		delay_us(Time_Pulse_Delay_Low);
	}
	else
	{
		delay_us(Time_Pulse_Delay_Low);
		PIN_ON(One_Wire_Pin);
		delay_us(Time_Pulse_Delay_High);
	}
} 

unsigned char One_Wire_Read_Byte(void)
{
	unsigned char tmp=0;
	unsigned char cnt;
	for (cnt=0;cnt!=8;cnt++)
		if (One_Wire_Read_Bit()!=0)	tmp|=(1<<cnt);
	delay_us(Time_Pulse_Delay_High);
	return tmp;
}

unsigned char One_Wire_Read_Bit (void)
{
		unsigned char tmp;              
		//PIN_OUT_PP(One_Wire_Pin);
                PIN_OFF(One_Wire_Pin);
		delay_us(Time_Hold_Down);
		PIN_ON(One_Wire_Pin);
		delay_us(Time_Pulse_Delay_Low);
		if ((PIN_SYG(One_Wire_Pin))!=0)	tmp = 1;
			else tmp = 0;
		delay_us(Time_Pulse_Delay_High);
		return tmp;
}
 

what is
DS1822_CONVERT_T_CMD
?
and
DS1822_READ_STRATCHPAD_CMD
?
Can you check my code?
Code:
// Easyrider83's code
           #define Time_Pulse_Delay_Low	        10      //10
#define Time_Pulse_Delay_High	        40      //40
#define Time_Reset_Low			500
#define Time_After_Reset		350
#define Time_Hold_Down			10

#define One_Wire_Read_ROM		0x33
#define One_Wire_Skip_ROM		0xCC
#define One_Wire_Search_ROM		0xF0
#define One_Wire_Match_ROM		0x55

#define One_Wire_Success		0x00
#define One_Wire_Error_No_Echo	        0x01
#define One_Wire_Bus_Low_Error	        0x02
#define One_Wire_Device_Busy	        0x03
#define One_Wire_CRC_Error		0x04
        #define One_Wire_Pin 0
void PIN_ON(int ignoreme)
{   // IS IT OK?                            //
        TRISD = 0xFF;
        PORTD.B2 = 1;
}
void PIN_OFF(int ignoreme)
{     // IS IT OK?
        TRISD = 0xFF;
        PORTD.B2 = 0;
}
void PIN_OUT_OD(int ignoreme)
{     // IS IT OK?
        TRISD = 0x00;
}
int PIN_SYG(int ignoreme)
{    // IS IT OK?
    return PORTD.B2;
}
     unsigned int One_Wire_Reset(void)
{
	unsigned int tmp;
        PIN_ON(One_Wire_Pin);
        PIN_OUT_OD(One_Wire_Pin);
	if ((PIN_SYG(One_Wire_Pin)==0))	return One_Wire_Bus_Low_Error;
        PIN_OFF(One_Wire_Pin);
	delay_us(250);
        delay_us(250);
        PIN_ON(One_Wire_Pin);
	delay_us(Time_Pulse_Delay_High);
	if ((PIN_SYG(One_Wire_Pin))) tmp = One_Wire_Error_No_Echo;
		else tmp = One_Wire_Success;
	delay_us(250);
        delay_us(200);
	return tmp;
}


void One_Wire_Write_Bit (unsigned char Bit)  ;

void One_Wire_Write_Byte(unsigned char Byte)
{
	unsigned char cnt;
	for (cnt=0;cnt!=8;cnt++) One_Wire_Write_Bit(Byte&(1<<cnt));
}

void One_Wire_Write_Bit (unsigned char Bit)
{
        PIN_OFF(One_Wire_Pin);
	if (Bit==0)
	{
		delay_us(Time_Pulse_Delay_High);
		PIN_ON(One_Wire_Pin);
		delay_us(Time_Pulse_Delay_Low);
	}
	else
	{
		delay_us(Time_Pulse_Delay_Low);
		PIN_ON(One_Wire_Pin);
		delay_us(Time_Pulse_Delay_High);
	}
}

unsigned char One_Wire_Read_Bit (void)
{
		unsigned char tmp;
		//PIN_OUT_PP(One_Wire_Pin);
                PIN_OFF(One_Wire_Pin);
		delay_us(Time_Hold_Down);
		PIN_ON(One_Wire_Pin);
		delay_us(Time_Pulse_Delay_Low);
		if ((PIN_SYG(One_Wire_Pin))!=0)	tmp = 1;
			else tmp = 0;
		delay_us(Time_Pulse_Delay_High);
		return tmp;
}
unsigned char One_Wire_Read_Byte(void)
{
	unsigned char tmp=0;
	unsigned char cnt;
	for (cnt=0;cnt!=8;cnt++)
		if (One_Wire_Read_Bit()!=0)	tmp|=(1<<cnt);
	delay_us(Time_Pulse_Delay_High);
	return tmp;
}

unsigned char DS1822_Start_Conversion_Skip_Rom (void)
{
	unsigned char tmp;
	tmp=One_Wire_Reset();
	if (tmp!=One_Wire_Success) return tmp;
	One_Wire_Write_Byte(One_Wire_Skip_ROM);
	One_Wire_Write_Byte(DS1822_CONVERT_T_CMD);
	if (One_Wire_Read_Byte()==0)	return One_Wire_Success;
		else	return One_Wire_Device_Busy;
}

           unsigned char DS1822_Read_Temp_NoCRC_Skip_Rom (unsigned int * temperatura)
{
	unsigned char tmp;
	tmp=One_Wire_Reset();
	if (tmp!=One_Wire_Success) return tmp;
	One_Wire_Write_Byte(One_Wire_Skip_ROM);
	One_Wire_Write_Byte(DS1822_READ_STRATCHPAD_CMD);
	* temperatura = One_Wire_Read_Byte()|(One_Wire_Read_Byte()<<8);
	return One_Wire_Success;
}
 

Simpler MikroC project attached.

Most of the code is for GLCD - what is left is simple use of one-wire library

oops - this is DS1820 code - change resolution to 12 for DS18B20

Code:
const unsigned short TEMP_RESOLUTION = 12;
 

Attachments

  • DS1820.zip
    49.8 KB · Views: 63

Sorry, forgot
Code:
#define DS1822_CONVERT_T_CMD				0x44
#define DS1822_WRITE_STRATCHPAD_CMD			0x4E
#define DS1822_READ_STRATCHPAD_CMD			0xBE
#define DS1822_COPY_STRATCHPAD_CMD			0x48
#define DS1822_RECALL_E_CMD					0xB8
#define DS1822_READ_POWER_SUPPLY_CMD		0xB4

#define DS1822_STRATCHPAD_SIZE				0x09
#define DS1822_SERIAL_NUM_SIZE				0x08

- - - Updated - - -

what is
DS1822_CONVERT_T_CMD
?
and
DS1822_READ_STRATCHPAD_CMD
?
Can you check my code?
Code:
// Easyrider83's code
           #define Time_Pulse_Delay_Low	        10      //10
#define Time_Pulse_Delay_High	        40      //40
#define Time_Reset_Low			500
#define Time_After_Reset		350
#define Time_Hold_Down			10

#define One_Wire_Read_ROM		0x33
#define One_Wire_Skip_ROM		0xCC
#define One_Wire_Search_ROM		0xF0
#define One_Wire_Match_ROM		0x55

#define One_Wire_Success		0x00
#define One_Wire_Error_No_Echo	        0x01
#define One_Wire_Bus_Low_Error	        0x02
#define One_Wire_Device_Busy	        0x03
#define One_Wire_CRC_Error		0x04

unsigned char One_Wire_Reset(void)
{
	unsigned char tmp;
        TRISD.B2 = 1; //switch for input
	if (PORTD.B2 == 0)	return One_Wire_Bus_Low_Error;
        TRISD.B2 = 0; //switch for output
        PORTD.B2 = 0; //force to low
	delay_us(500);        
        TRISD.B2 = 1; //switch for input
	delay_us(Time_Pulse_Delay_High);
	if (PORTD.B2) tmp = One_Wire_Error_No_Echo;
		else tmp = One_Wire_Success;
	delay_us(450);
	return tmp;
}

void One_Wire_Write_Byte(unsigned char Byte)
{
	unsigned char cnt;
	for (cnt=0;cnt!=8;cnt++) One_Wire_Write_Bit(Byte&(1<<cnt));
}

void One_Wire_Write_Bit (unsigned char Bit)
{
        TRISD.B2 = 0;
        PORTD.B2 = 0;
	if (Bit==0)
	{
		delay_us(Time_Pulse_Delay_High);
		PORTD.B2 = 1;
		delay_us(Time_Pulse_Delay_Low);
	}
	else
	{
		delay_us(Time_Pulse_Delay_Low);
		PORTD.B2 = 1;
		delay_us(Time_Pulse_Delay_High);
	}
}

unsigned char One_Wire_Read_Bit (void)
{
		unsigned char tmp;
		TRISD.B2 = 0;
                PORTD.B2 = 0;
		delay_us(Time_Hold_Down);
		TRISD.B2 = 1;
		delay_us(Time_Pulse_Delay_Low);
		if (PORTD.B2)	tmp = 1;
			else tmp = 0;
		delay_us(Time_Pulse_Delay_High);
		return tmp;
}
unsigned char One_Wire_Read_Byte(void)
{
	unsigned char tmp=0;
	unsigned char cnt;
	for (cnt=0;cnt!=8;cnt++)
		if (One_Wire_Read_Bit()!=0)	tmp|=(1<<cnt);
	delay_us(Time_Pulse_Delay_High);
	return tmp;
}

unsigned char DS1822_Start_Conversion_Skip_Rom (void)
{
	unsigned char tmp;
	tmp=One_Wire_Reset();
	if (tmp!=One_Wire_Success) return tmp;
	One_Wire_Write_Byte(One_Wire_Skip_ROM);
	One_Wire_Write_Byte(DS1822_CONVERT_T_CMD);
	if (One_Wire_Read_Byte()==0)	return One_Wire_Success;
		else	return One_Wire_Device_Busy;
}

           unsigned char DS1822_Read_Temp_NoCRC_Skip_Rom (unsigned int * temperatura)
{
	unsigned char tmp;
	tmp=One_Wire_Reset();
	if (tmp!=One_Wire_Success) return tmp;
	One_Wire_Write_Byte(One_Wire_Skip_ROM);
	One_Wire_Write_Byte(DS1822_READ_STRATCHPAD_CMD);
	* temperatura = One_Wire_Read_Byte()|(One_Wire_Read_Byte()<<8);
	return One_Wire_Success;
}

Fixed something
 
Last edited:

it returns "One_Wire_Error_No_Echo"....
 

Does it give any pulse at all? Can you replace sensor with led? You should see how it blinks.
 

Yes it blinks a bit.
I have no idea what's wrong.
I have also tried several other examples and none of them works.
 

Code:
unsigned char One_Wire_Reset(void)
{
	unsigned char tmp;
        TRISD.B2 = 1; //switch for input
	if (PORTD.B2 == 0)	return One_Wire_Bus_Low_Error;
        TRISD.B2 = 0; //switch for output
        PORTD.B2 = 0; //force to low
	delay_us(500);        
        TRISD.B2 = 1; //switch for input
	delay_us(Time_Pulse_Delay_High);
[COLOR="#00FF00"]	if (PORTD.B2) tmp = One_Wire_Error_No_Echo;[/COLOR]
		else tmp = One_Wire_Success;
	delay_us(450);
	return tmp;
}
One_Wire_Error_No_Echo comes from marked green section. I think that means that delays are working wrong - incorrect oscillator configuration is used.
Try to implement 1s led blinking based on delay_ms(1000) function. Does it blinks each second?
 

Are you 100% sure?

This chip is using USB and USB is working OK.
Can USB work OK with wrong timings?

BTW: I've tested both normal DS18B20 and PAR version, and they don't work. They don't work with your code, don't work with sample code, nor any other code....
\

 

Try to switch off usb temporary. 1-wire communication requere very precicly time slots, which can be extended during interrupt routine being used.
 

Then I'd have no way to communicate out the result, wouldn't I?

But I did something like this:

Code:
main()
{
      --- WAIT A WHILE
     --- READ TEMPERATURE RIDERS METHOD TWICE
     --- INIT USB
      --- SEND DATA

}

but it still's returns that error of yours on in case of other code garbage data - something like 0.00064
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top