[solved] DS18B20 always giving 85.0000

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I found this code which seems to be simple enough to fit tiny controllers (this was the main reason to using this code): LINK.

Any way, the code was originally for atmega1284, and I modified it to work with atmega16, main changes were actually in uart.c because atmega16 has only one USART module. I replaced the makefile because the original one was not displaying the resulting code size. I added some lines in main.c to modify TH and TL registers as well.

First of all, I tried the code with DS1820, and it works fine. The problem appears with DS18B20 that constantly displays 85.0000, I am able to modify scratchpad TH and TL registers and I can read the scratchpad without problems. I tried changing the way code waits for DS18B20 to finish conversion in ds18b20ReadTemperature function, but this has not changed anything, I also tried ignoring the search for sensors on the bus and used skip rom command instead, but this has also never changed anything. I looked at the datasheets, but could not find what could cause this error condition.

I have also tried 4.7K and 10K pullup resistors, Vcc and GND are connected to the sensor as the datasheet pin assignment showed, so technically speaking I don't have connection problems. DS18B20 sensors I have are all working already.

Here is a sample from the output of DS18B20:

5  80

Temperature: 85.0000

scratch[2]: 85

scratch[3]: 0

scratch[4]: 127

scratch[5]: 255

scratch[6]: 12

scratch[7]: 16

scratch[8]: 33

5 and 80 represent temperature MSB and LSB, respectively. Then the actual temperature is displayed, followed by the rest of the scratchpad registers values. Values are in decimal representation, of course.

I am using STK500 and WinAVR.

Attachment(s): 

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

Last Edited: Mon. Jan 21, 2013 - 06:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That 85*C is a reset value. You didn't trigger a conversion start.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In main.c there is ds18b20ReadTemperature function, you can find:

// Send start conversion command.
oneWireSendByte(DS18B20_START_CONVERSION, bus);

Where you can also find
#define DS18B20_START_CONVERSION 0x44

Is that what you mean?

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
// Bus line is held low until conversion is finished.

I do not like this line. Are you sure data line has to be floating then?

Are you using ONEWIRE_USE_PARASITIC_POWER? Conversion takes some and >1mA so perhaps that moment resets your DS, when power line sags.. Perhaps apply Vcc permanently for tests.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

interesting and annoying thing I found today, after 4 days of work, I tried the parasitic mode, and it did not work. I read somewhere that 4.7K will not work, so I tried 2.2K, and I started seeing the room temperature.

What makes me appear more silly now, is that the sensors I had were DS18B20P, not DS18B20. This sensor only works in parasitic mode(!)

Brutte, thanks for trying to help, the code is just fine :) I am really annoyed I did not see the P on my sensors.

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

metal wrote:
I tried the parasitic mode, and it did not work.

I am afraid you didn't get the idea. There is nothing wrong in parasitic mode.
The pull-up resistor of 4,7k is just fine. Leave it as it was.
All you need to do is to drive data line high for about 750ms after you issue DS18B20_START_CONVERSION command.
I believe an IO drive strength of an AVR (Rds is about 20ohms) is enough so instead of:

// Bus line is held low until conversion is finished.

you should do:

//Bus line is held high until conversion is finished

You need to do it instantly (no ISRs in between). Then your chip will convert data as designed so that you could read it out by uC 750ms later.

Good luck to you.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This comment is related to the normal power mode, not parasite. It is actually the sensor that is holding the line LOW when it is in normal power mode.

When in parasitic mode, you are right, I have to drive the pin high to feed the sensor.

This is what I read in the datasheet:

Quote:
If the device is being used in parasite power mode, within 10μs (max) after this command is issued the master must enable a strong pullup on the 1-Wire bus for the duration of the conversion (tCONV). If the DS18B20 is powered by an external supply, the master can issue read time slots after the Convert T command and the DS18B20 will respond by transmitting a 0 while the temperature conversion is in progress and a 1 when the conversion is done.

I noticed that the current supplied by 4.7K is enough to run the sensor, but not to enable it convert the temperature. A strong pull up i.e. pin -> HIGH during conversion is a must. I will change the resistor back to 4.7K and drive the pin HIGH during conversion.

Thank you Brutte :)

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You were right, 4.7K works fine now, it was a good feeling to heat the soldering iron again :) It was a forgotten step in the code from the beginning then.. I modified the function as follows, I added ONEWIRE_PULL_BUS_HIGH(bus) for the parasite mode and moved ONEWIRE_RELEASE_BUS(bus) to be in the normal mode, this is where it actually belongs:

    // Wait until conversion is finished.
    // Bus line is held low until conversion is finished. Normal power mode only
#ifdef ONEWIRE_USE_PARASITIC_POWER
	ONEWIRE_PULL_BUS_HIGH(bus);
	_delay_ms(800);
#else
	ONEWIRE_RELEASE_BUS(bus);
   while (!oneWireReadBit(bus))
    	;
#endif	

I wanted to ask you, which way is better:

#define ONEWIRE_PULL_BUS_HIGH(bitMask) \
            ONEWIRE_DDR 	|=  bitMask; \
            ONEWIRE_PORT 	|= bitMask;

or this:

#define ONEWIRE_PULL_BUS_HIGH(bitMask) \
            ONEWIRE_PORT 	|= bitMask; \
            ONEWIRE_DDR 	|=  bitMask; 

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I wanted to ask you, which way is better:

You have got plenty of time (10us) to do the trick so I do not think if that sequence matters..
As you may know there is no way to force an AVRs' IOs from input (HighZ) to output HI in one go. You need to change (DDR then PORT) or (PORT then DDR).
However..
Your design implies there is a pull-up permanently applied to the line so it is not a problem to keep the IO with an internal pull-up permanently enabled during transmission. Those internal pull-ups are about 20k -40k IIRC so you can tweak the external resistor so that it is effective 4,7k if you want to be realllllly precise.

Just initialize ONEWIRE_PORT with bitMask set.

Then you just need to do:

#define ONEWIRE_PULL_BUS_HIGH(bitMask) \
            ONEWIRE_DDR    |=  bitMask;

I would also suggest to stick:

assert(ONEWIRE_PORT & bitMask); 

just before that :D

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Brutte,

This works while interrupts enabled:

#define ONEWIRE_PULL_BUS_HIGH(bitMask) \
     ONEWIRE_PORT 	|= bitMask; \
     ONEWIRE_DDR 	|=  bitMask;

The other way around doesn't actually work and causes DS18B20P to read 85 all the time. Hoprfully may be someone find it useful, it took me some time to find where the problem was till I recalled that step!

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
This works while interrupts enabled:

What I meant that in between

oneWireSendByte(DS18B20_START_CONVERSION, bus);

and

ONEWIRE_PULL_BUS_HIGH(bitMask)

you have to keep a 10us constraint.
This could be violated by some ISR raised in between.
The 10us is 80 clocks in your case (which is a lot for two "sbi" but not for raising ISR and return).
So instead "This works while interrupts enabled" should be "This sometimes works while interrupts enabled" IMHO.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Reading one bit of one-wire protocol is only a few microseconds. Disable interrupts for this period. You can always re-enable interrupts between bits.

You can service the interrupts between the one-wire bits.

Let's face it, you will suffer a possible interrupt latency of 'one-bit-time'. Hey-ho, you have to weigh this up against the convenience of using only one GPIO pin. I2C or SPI have hardware that handles 8 bits at a time and generally never needs interrupts to be disabled.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a project with DS18B20, this is a good stuff but with convertion time this make me so crazy. on my project i made a timer,from timer1 on ATMega 16. unfortunately, DS18B20 take so many time for delay. i need to show time on microsecond form, but with delay time about 800us it waste lot time. anyone can help me? Sorry for bad english, i am from indonesia. thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Welcome to AVRFreaks.

I am confused. The DS18B20 is a temperature sensor. So what does temperature have to do with displaying "time on microsecond form".

And I should also say that your question has nothing to do with the original post, so it would have been better to start your own thread/topic.

Ross McKenzie ValuSoft Melbourne Australia