Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
March 28, 2024, 05:53:58 17:53


Login with username, password and session length


Pages: [1] 2  All
Print
Author Topic: DS18B20 one wire communication with PIC  (Read 39449 times)
0 Members and 1 Guest are viewing this topic.
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« on: February 16, 2013, 12:43:27 12:43 »

Hello,
I am using for first time one wire protocol. I searched on the internet and I found some functions but I can't manage them. I found a code for PIC in assembly for one wire communication at the below link and I converted to C language but doesn't work. Also, I saw on DS18B20 datasheet at "function command set" and I change the values of command that I send but it stills doesn't work. I want to use DS18B20 with parasite power on C18 compiler with PIC18F2550. Could anyone help me to solve this.
  
One wire communication application note : http://www.maximintegrated.com/app-notes/index.mvp/id/2420
« Last Edit: February 17, 2013, 10:57:07 10:57 by diamadiss » Logged
pickit2
Moderator
Hero Member
*****
Offline Offline

Posts: 4639

Thank You
-Given: 823
-Receive: 4194


There is no evidence that I muted SoNsIvRi


« Reply #1 on: February 16, 2013, 01:00:27 13:00 »

a site I visit from time to time
http://www.pic_examples.byethost3.com/DS18B20.html
Logged

Note: I stoped Muteing bad members OK I now put thier account in sleep mode
xpress_embedo
Active Member
***
Offline Offline

Posts: 173

Thank You
-Given: 122
-Receive: 254


« Reply #2 on: February 16, 2013, 02:32:09 14:32 »

I had made a project based on One-Wire Protocol.
I used DS1822 and PIC16F877A Micro-Controller

Hi-Tech C Compiler v9.83

Please find the attached the link to download the project with proteus simulation file.
Logged
jamesbond
Newbie
*
Offline Offline

Posts: 23

Thank You
-Given: 50
-Receive: 9


« Reply #3 on: February 17, 2013, 09:35:10 09:35 »

I use these functions for all my one wire applications.
May be you can use it.
Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #4 on: February 17, 2013, 09:42:26 09:42 »

Hello,
Thanks for replies. I would to create my own function so I can to understand one wire communication with parasite power. Please, could anyone guide my to fix it? Thanks.
« Last Edit: February 17, 2013, 10:56:46 10:56 by diamadiss » Logged
flo0319
Junior Member
**
Offline Offline

Posts: 81

Thank You
-Given: 7
-Receive: 17


« Reply #5 on: February 17, 2013, 11:28:38 11:28 »

1-wire protocol is based on time slots, so you need to make samples for bits when you are sure that the line is stabilized, and also you need to implement an external filter to eliminate parasites  from the line. in general you need to put a delay between normal time (1us or 5us)  and the moment when you read value form pin


Be careful with the pull-up resistor from line, at a dsPIC just with internal pull-up enabled worked 
« Last Edit: February 17, 2013, 11:37:51 11:37 by flo0319 » Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #6 on: February 17, 2013, 08:59:13 20:59 »

I made some changes according to operation example from DS18B20 datasheet. But now always it shows on display the value "-1". Please could anyone see the attached picture which shows the "operation example" from datasheet because I think that I must sent wrong data. Also, I have attached my code so to see it.
  
Datasheet DS28B20 :  
http://datasheets.maximin....com/en/ds/DS18B20.pdf  
  
1-Wire® Communication with a Microchip PICmicro Microcontroller :
http://www.maximintegrate...otes/index.mvp/id/2420
  
Logged
flo0319
Junior Member
**
Offline Offline

Posts: 81

Thank You
-Given: 7
-Receive: 17


« Reply #7 on: February 18, 2013, 12:52:50 12:52 »

Hi again,
you need to make some changes in your code :
look at my code first:

Code:

void prvWireInit(void)
{
CNPU1=64; // for pull-up resistors
WireDir=1;
WirePin=1;
};
void prvWireReset(void)
{
WireDir=0;
WirePin=0;
delayus(550); // more then 500
WirePin=1;
WireDir=1;
delayus(70);
};

int prvWirePresence(void)
{ int i;
int Bit=0;
WireDir=1;
for(i=480;i>0;i--)
{
delayus(1);
if (WirePin==0) Bit=1;
};
return Bit;
};

void prvWireSendBit(unsigned portCHAR Bit)
{
WireDir=0;
WirePin=0;
delayus(2);
WirePin=Bit;
delayus(TSlot); // 60us
WireDir=1;
delayus(2);
};

portCHAR prvWireGetBit(void)
{ portCHAR Bit;
WireDir=0;
WirePin=0;
delayus(2);
WireDir=1;
delayus(20);
Bit=WirePin;
delayus(100);
return Bit;
};

void prvWireWriteByte(unsigned portCHAR Byte)
{
int i;
for (i=0;i<8;i++)
{
prvWireSendBit( Byte&0x01);
Byte=Byte>>1;
};
};

char  prvWireReadByte(void)
{
int i;
char Byte;
Byte=0;
for(i=0;i<8;i++)
Byte=Byte|((1&prvWireGetBit())<<i);
return Byte;
};


it's better in this case to use PORT register and not LAT register for read and write to pin.

you need to insert more delays in your code, and very important is how receive the presence impulse from sensor.

also look at how is initiate a communication between mcu and sensor (is not for parasite power but is similar)

Code:
//reinitializare si startare citire temp
prvWireReset(); 
prvWirePresence();
prvWireWriteByte(0xCC);
prvWireWriteByte(0x44);

vTaskDelay(300); // 300ms delay (but this can be a short time >10ms )

//comanda citire temperatura
prvWireReset();
prvWirePresence();
delayus(70);

prvWireWriteByte(0xCC);
prvWireWriteByte(0xBE);

WireDir=0;
WirePin=0;

test1=prvWireReadByte();
delayus(70);
test2=prvWireReadByte();
vTemp=(unsigned int)(test2<<8)+ (unsigned int) test1;
prvWireReset();
prvWirePresence();
 

after reset you need to wait 480us for presence impulse response

you have on display -1 because your data is 0xFF  (from pull-up) and "%d" is for signed decimal , for unsigned you need to use %u . 
Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #8 on: February 18, 2013, 01:17:04 13:17 »

Hello,
I am trying to make compile in your code but compile failed (syntax error). I have attach a txt with your code with my code. Thanks a lot for your help.
Logged
flo0319
Junior Member
**
Offline Offline

Posts: 81

Thank You
-Given: 7
-Receive: 17


« Reply #9 on: February 18, 2013, 01:50:18 13:50 »

It's normal to have this problem :

add to your code this:

#define delayus(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define delayms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))

#define WirePin        PORTAbits.PORTA0 // or _PA0
#define WireDir        TRISAbits.TRISA0         // "DQ_TRIS = 0;" This must included in the main program
 
and change:

delayus(TSlot); // 60us with delayus(60);

vTaskDelay(300); // 300ms delay (but this can be a short time >10ms ) with
delayms(300); // 300ms delay (but this can be a short time >10ms )

delete from prvWireInit(void) CNPU1 = 64;

and declare test1,test2 as unsigned char and vTemp as integer

if other errors occur , you can manage it by yourself

until to go in while(1), call prvWireInit() to initiate the port pin
Logged
ehnonymouse
Newbie
*
Offline Offline

Posts: 28

Thank You
-Given: 15
-Receive: 13


« Reply #10 on: February 19, 2013, 03:15:12 15:15 »

I don't know whether this will help, but this is some sample code I modified to read the serial number from a DS2411. It's for the MPLAB C30 compiler and a PIC24. Tested, and working in the application.
Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #11 on: February 19, 2013, 06:33:34 18:33 »

I magage to make compile with flo0319 code but doesn't work. Always it shows on display the value 255. Also, I replace "portCHAR" with "char" so to make a successful compile. I see on datasheet of "DS18B20 operation example 2" which is for parasite power that we don't send all the commands. Is this possible to be the cause of the problem? In txt file I have attached the code which it does succesful compile. Thanks.
« Last Edit: February 19, 2013, 08:52:49 20:52 by diamadiss » Logged
LithiumOverdosE
Senior Member
****
Offline Offline

Posts: 350

Thank You
-Given: 374
-Receive: 568


« Reply #12 on: February 19, 2013, 06:42:30 18:42 »

Check out Dallas 1-Wire application notes. They enclosed C code that can be easily ported to PIC compilers with modification of bit read/write procedures.

Also check out AVR318 App Note.
Logged
flo0319
Junior Member
**
Offline Offline

Posts: 81

Thank You
-Given: 7
-Receive: 17


« Reply #13 on: February 19, 2013, 07:22:08 19:22 »

diamadiss, tell me how you have connected your ds18b20 to uC and try to communicate with it in normal power mode
after you can view that your sensor work(with external power) you can change and can try to communicate with it in parasite mode
if you can make a picture with your schematic and hardware we can view if is something wrong there
Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #14 on: February 19, 2013, 07:28:43 19:28 »

I use it without parasite power for now but it doesn't work. In picture you can see my schematic.
Logged
flo0319
Junior Member
**
Offline Offline

Posts: 81

Thank You
-Given: 7
-Receive: 17


« Reply #15 on: February 19, 2013, 08:30:40 20:30 »

your problem is form pin configuration

Note: On a Power-on Reset, RA5 and RA3:RA0
are configured as analog inputs and read
as ‘0’. RA4 is configured as a digital input.

you need to configure RA0 as digital pin  (after reset this pin si analog)

ADCON1 = 0x0F ; // to do all pins digital
this instruction you need to add on initiation (in main() )


Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #16 on: February 19, 2013, 08:52:27 20:52 »

I have already add these "commands" on my code but didn't work.

    ADCON0 = 0x00;
    ADCON1 = 0x0F;
    CMCON = 0x07;                //Disable Comporators
Logged
flo0319
Junior Member
**
Offline Offline

Posts: 81

Thank You
-Given: 7
-Receive: 17


« Reply #17 on: February 19, 2013, 09:30:34 21:30 »

I think that your sensor is the problem, try to change with another one
Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #18 on: February 19, 2013, 09:42:23 21:42 »

I replace the sensor with new but it stills show 255.
Logged
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #19 on: February 19, 2013, 10:26:54 22:26 »

Your sensor has P at the end? Like in DS18B20P?
Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #20 on: February 19, 2013, 10:29:10 22:29 »

Yes, the code is "DS18B20 + PAR"
Logged
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #21 on: February 19, 2013, 10:35:10 22:35 »

The reason for your reading is that after you issue the read command, you are not pulling the pin connected to DS18B20P high, it really needs a strong pull and can be done by setting the pin itself high and as an output, which means you are not providing supply for the DS18B20P. Look at this:

Code:
void therm_read_temperature(int16_t *temperature){
//Reset, skip ROM and start temperature conversion
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
cli();
therm_write_byte(THERM_CMD_CONVERTTEMP);
//Wait until conversion is complete
#ifdef ONEWIRE_USE_PARASITIC_POWER
THERM_HIGH();  
THERM_OUTPUT_MODE();
sei();
//THERM_INPUT_MODE();
_delay_ms(751);
//THERM_INPUT_MODE();
#else
THERM_INPUT_MODE();
sei();
while(!therm_read_bit());
#endif
//Reset, skip ROM and send command to read Scratchpad
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_RSCRATCHPAD);
//Read Scratchpad (only 2 first bytes)
*temperature = therm_read_byte();
*temperature |= therm_read_byte() << 8;
therm_reset();
}

After issuing "therm_write_byte(THERM_CMD_CONVERTTEMP);", you have to ensure that you controller has done its homework:

// Write 1 to pin connected to DS18B20P
THERM_HIGH();
// Pin is output
THERM_OUTPUT_MODE();


Also ensure that interrupts are disables before you execute the above two operations. Look at your code, and seek where you should do this modification.



Logged
diamadiss
Junior Member
**
Offline Offline

Posts: 69

Thank You
-Given: 202
-Receive: 4



« Reply #22 on: February 20, 2013, 07:25:06 19:25 »

I make high for 100us the pin which connected DS18B20 and I disable all interupts "INTCONbits.GIE = 0; // Disable global interrupts" but it stills show the value "255". I have attached my code so to see where I make the DS18B20 pin high. Also, I tried to work with xtal 4MHz instead 20MHz but nothing. Thanks.
Logged
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #23 on: February 20, 2013, 10:14:57 22:14 »

it should be high for 750ms, not 100us, look at my code: _delay_ms(751);
Logged
flo0319
Junior Member
**
Offline Offline

Posts: 81

Thank You
-Given: 7
-Receive: 17


« Reply #24 on: February 21, 2013, 07:50:17 07:50 »

diamadiss, have you an oscilloscope or something to view exactly what is happened on this line? 
Logged
Pages: [1] 2  All
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC