PDA

View Full Version : DS1820 headache



Calco
- 7th August 2004, 13:31
Hi all,

Ive got a small problem with a DS1820 setup.
Iam using a 16F819 with its internal osc at 8mhz.
I have modified the onewire.bas so as to send the data serially.
My display simply reads 85.0 C constantly. It doesnt alter when temperature is applied either.
Occasionally it will read 26.89 C but only briefly and only just after power up.

My question is, is timing accuracy critical on these?, What am I missing?

Iam currently unable to put an LCD module direct to the PIC.

Iam running a serial LCD module.

Hope someone can ppoint me in the right direction.

Regards

Darryl

Melanie
- 7th August 2004, 14:19
Is 85 the raw value retuned from the device (which would be absolute zero and a meaningless result), or is this the converted value to something meaningful like degrees C or F?

Might help if we saw the OWIN/OWOUT code part where you interrogate the sensor.

edwards_jt
- 9th August 2004, 00:09
Hi, I might be having the same problem as well, i am using the ds18b20.

I am not sure yet, i think my problem might be with the timing pof the Tx/Rx. I couldn't get the owin and owout routines to work so i wrote new ones based on the example at http://www.rentron.com/PICX4.htm

with some timing tweaks based on the datasheet for the ds18b20.

I havn't managed to get an lcd working so there is led flashing to illustrate different steps in the program cycle as well as to output the raw two's compliment data.

No matter what i do the results for all 9 bytes of the scratchpad are the same (including taking a soldering iron to the ds18b20!) and the crc byte (9th byte). I have checked this program with two ds18B20's (all i have) and both output exactly the same data, so like i said probably a timing error in the tx/rx.

btw - i wrote the program using the mikroelectronica mikrobasic compiler since it was free, after some frustration i bought PBP 2.45 and now am trying to migrate this program to PBP, you should be able to follow it well enough, the syntax is extremely similar. I am programming a pic 16f684.

let me know what you think, it may be useful to compare what i am doing wrong to what you are doing wrong :)

cheers,

James

NavMicroSystems
- 9th August 2004, 02:17
The following example works just fine

http://www.rentron.com/PICX4.htm


make sure yor DS1820 has +5V on Pin 3

If you are using the "Parasite Power" Option
you need to set DQ high right after starting the conversion

regards

edwards_jt
- 9th August 2004, 06:11
Thanks, actually where i went wrong on the reynolds example was the cmcon0 register was incorrectly set for the 16f684 (needed update from melabs 2.45 --> 2.45a)

so i have a program that seems to read the 12 bit temperature from the ds18b20 ... only one problem, when i convert from twos compliment it reads garbage, but if i leave the data as is and output it, it makes perfect sense, accurate as well as i can tell without a full blown calibration and its responsive to stimuli (body temp and soldering iron)

now I usually follow the motto in electronics 'if it works, don't ask' (i only have a year of electronics from university and i never covered microcontrollers, so its a good motto) but i find this disconcerting. Any ideas why this set-up would read the data in this way? I have attached the code but nothing i can see in it reverses the data ?

so any ideas?

Thanks

James

edwards_jt
- 9th August 2004, 06:18
sorry, the attachment doesn't seem to want to go, this is the working code i have for the 16f684

'circuit

'a0 to pin2 of ds1820 with 4.7k pullup to vdd
'portc 0-->5 connected to LEDs in series with 100 Ohm resistor
'porta(1,2) connect to LEDs in series with 100 Ohm resistor

'chip specific definitions

@ DEVICE pic16F684, INTRC_OSC_NOCLKOUT
' System Clock Options (Internal)
@ DEVICE pic16F684, WDT_on
' Watchdog Timer
@ DEVICE pic16F684, PWRT_ON
' Power-On Timer
@ DEVICE pic16F684, MCLR_OFF
' Master Clear Options (Internal)
@ DEVICE pic16F684, BOD_Off
' Brown-Out Detect
@ DEVICE pic16F684, CPD_OFF
' Data Memory Code Protect
@ DEVICE pic16F684, PROTECT_OFF
' Program Code Protection
@ DEVICE pic16F684, extrc_osc_noclkout




' set sfr
intcon=%00000000 ' disables cpu interupts
pie1=%00000000 ' disables all periphrial interupts
ansel=%00000000 ' diables analog inputs
TRISC=%00000000 ' sets port c to output
TRISA=%00000000 ' sets port a
cmcon0=7
ADCON1 = 7 ' disables a/d
wpua = 6 ' enables weak pull ups on pins a1 and a2




' Allocate variables
command VAR BYTE ' Storage for command
i VAR BYTE ' Storage for loop counter
temp VAR WORD ' Storage for temperature
DQ VAR PORTA.0 ' Alias DS1820 data pin
DQ_DIR VAR TRISA.0 ' Alias DS1820 data direction pin


' main program loop

main:

GoSub flash ' shows loop start
Pause 1000


GoSub init1820 ' Init the DS1820

command = $cc ' Issue Skip ROM command
GoSub write1820

command = $44 ' Start temperature conversion
GoSub write1820

Pause 2000 ' Wait 2 seconds for conversion to complete

GoSub init1820 ' Do another init

command = $cc ' Issue Skip ROM command
GoSub write1820

command = $be ' Read the temperature
GoSub write1820
GoSub read1820


GoSub flash ' shows loop end
Pause 1000

' outputs lower byte on LEDs
For i=1 TO 200
IF temp.0 = 1 Then
PORTC.0 = 1
EndIF
IF temp.1 = 1 Then
PORTC.1 = 1
EndIF
IF temp.2 = 1 Then
PORTC.2 = 1
EndIF
IF temp.3 = 1 Then
PORTC.3 = 1
EndIF
IF temp.4 = 1 Then
PORTC.4 = 1
EndIF
IF temp.5 = 1 Then
PORTC.5 = 1
EndIF
IF temp.6 = 1 Then
PORTA.1 = 1
EndIF
IF temp.7 = 1 Then
PORTA.2 = 1
EndIF
Pause 10
PORTC=0
PORTA.1=0
PORTA.2=0
Pause 200
Next i

'flashes LEDs between bytes
PORTC=0
PORTA.1=0
PORTA.2=0

PORTC=%111111
PORTA.1=1
PORTA.2=1
Pause 2000
PORTC=0
PORTA.1=0
PORTA.2=0




'outputs upper byte on LEDs
For i=1 TO 200
IF temp.8 = 1 Then
PORTC.0 = 1
EndIF
IF temp.9 = 1 Then
PORTC.1 = 1
EndIF
IF temp.10= 1 Then
PORTC.2 = 1
EndIF
IF temp.11= 1 Then
PORTC.3 = 1
EndIF
IF temp.12= 1 Then
PORTC.4 = 1
EndIF
IF temp.13= 1 Then
PORTC.5 = 1
EndIF
IF temp.14= 1 Then
PORTA.1 = 1
EndIF
IF temp.15= 1 Then
PORTA.2 = 1
EndIF
Pause 5
PORTC=0
PORTA.1=0
PORTA.2=0
Pause 200
Next i




GoTo main ' Do it forever


' Initialize DS1820 and check for presence
init1820:
Low DQ ' Set the data pin low to init
PauseUs 500 ' Wait > 480us
DQ_DIR = 1 ' Release data pin (set to input for high)

PauseUs 100 ' Wait > 60us
IF DQ = 1 Then
PORTC=%00000011
PORTA.1=1
PORTA.2=1
Pause 2000
PORTC=0
PORTA.1=0
PORTA.2=0
GoTo main ' Try again

Else
PORTC=%11111111
PORTA.1=1
PORTA.2=1
Pause 2000
PORTC=0
PORTA.1=0
PORTA.2=0
EndIF
PauseUs 400 ' Wait for end of presence pulse
Return


' Write "command" byte to the DS1820
write1820:
For i = 1 TO 8 ' 8 bits to a byte
IF command.0 = 0 Then
GoSub write0 ' Write a 0 bit
Else
GoSub write1 ' Write a 1 bit
EndIF
command = command >> 1 ' Shift to next bit
Next i
Return

' Write a 0 bit to the DS1820
write0:
Low DQ
PauseUs 60 ' Low for > 60us for 0
DQ_DIR = 1 ' Release data pin (set to input for high)
Return

' Write a 1 bit to the DS1820
write1:
Low DQ ' Low for < 15us for 1
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
PauseUs 60 ' Use up rest of time slot
Return


' Read temperature from the DS1820
read1820:
For i = 1 TO 16 ' 16 bits to a word
temp = temp >> 1 ' Shift down bits
GoSub readbit ' Get the bit to the top of temp
Next i
Return

' Read a bit from the DS1820
readbit:
temp.15 = 1 ' Preset read bit to 1
Low DQ ' Start the time slot
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
IF DQ = 0 Then
temp.15 = 0 ' Set bit to 0
EndIF
PauseUs 60 ' Wait out rest of time slot
Return

End
flash:

For i=1 TO 20
PORTC=%11111111
PORTA.1=1
PORTA.2=1
Pause 50
PORTC=0
PORTA.1=0
PORTA.2=0
Pause 200
Next i
Return

Calco
- 9th August 2004, 09:09
Melanie,

Thanks, I have managed to sort it out now, it turns out that 85 is the default value stored in the DS1820 and if you do not connect 5v to pin 3 as had been previously suggested then it is unable to alter the value. Im certain all my other units ran with just the 2 connections. I guess you live and learn.

Regards

Darryl

NavMicroSystems
- 9th August 2004, 14:50
Here is short example for DS1820 using OWIN and OWOUT

'----------------------------------------------
DQ var PortD.2
temp var word

loop:
owout DQ,1,[$cc]
owout DQ,0,[$44]
Pause 2000
owout DQ,1,[$cc]
owout DQ,0,[$be]
owin DQ,0,[temp.byte0,temp.byte1]
lcdout $FE,1
temp=temp*5
lcdout " Temp = ",DEC2 temp/10,".", dec1 temp," ",$DF,"C"
goto loop
'----------------------------------------------

regards

actionplus
- 11th August 2004, 15:52
NavMicroSystems

the short that you posted, will that just do it? I will have to try it.
I am try to buildS one using a thermistor since I need to go up to about 250F. DS18S20 will not go up there.

Still trying to figure out the codes

NavMicroSystems
- 11th August 2004, 16:57
actionplus

the short version is tested and works.
It does not check the presence of a DS1820, it assumes it is just there.

If you would like to check the presence of the sensor youl will need some more code.

actionplus
- 11th August 2004, 20:19
I shall try it.

anj
- 12th August 2004, 00:28
The following code will read a single DS18B20 sensor ( non parasite powered ), and will check for sensor being present/unplugged during conversion. It also deals with negative temps, and i get around this by adding 50degC to the result, and removing it later as required.
Ps It will also trap sensor errors where there is a pullup but no sensor, as well as no pullup and no sensor ( as they give different results.)
-------------------------------------------------------------------
tempAir VAR WORD ' Air Temp ( ambient )
temp1 Var Word ' Temperature storage
tempx var word
temp2 Var Word ' Temperature storage
dummy VAR BYTE

TmpPos var Byte 'Temp pos or neg
Tmp var Word 'Temp
OWPORT var BYTE 'Pin the sensor is on
NoSens var BIT 'Byte to check for sensors
'-------------------------------------------------------------------------------
' Main loop
loop:
' Get AIR temp
OWPORT = 13 ' Pins 13 maps to C.5 in a 28pin device
GOSUB ReadOW
tempAir = temp1 'now has corrected ( temp + 50deg ) << 4 to beat minus signs

' Get next temp
OWPORT = ??
etc etc
goto loop
end
'-------------------------------------------------------------------------------
' Routine to read a one wire device ( Assumes single unit in full powered mode, not Parasite )
' Checks for sensors ( pulldowns on switched inputs detect if sensor in place )
ReadOW:
temp1 = 0 ' ( Temp + 50 ) * 16
NoSens = 0 ' Sensor check failed bit
TmpPos = 0 ' Sensor check

OWOut OWPORT, 1, [$CC, $44] 'Start conversion process
waitloop:
OWIn OWPORT, 4, [dummy] ' Check for still busy converting
temp1 = temp1 + 1 ' Need next bit to cover probe unplugging after conversion starts
pause 10 ' max conversion time for 12bit temp is 750mSec max
if temp1 > 75 then ' hence if get this far, abort so she doesnt hang
NoSens = 1
goto waitlost
endif
If dummy = 0 Then waitloop ' Not finished converting

OWOut OWPORT, 1, [$CC, $BE] ' Request read of the temperature
OWIn OWPORT, 0, [temp1.LOWBYTE, temp1.HIGHBYTE, TmpPos, Skip 5 ]
if TmpPos = %11111111 then 'If pullup is there but no sensor
NoSens = 1 'TmpPos comes back as all 1s
endif
waitlost:
if NoSens then
temp1 = 9999 'Ie failed
else
' DS18B20 in full 12 bit mode returns temp as a binary value in 1/16th deg C ( 0.0625 )
' We must check MSB of temp1. If it is 1 we have a neg value and this requires
' different processing. We calc this using temp2 = ~temp1 + %1
' To get rid of negatives in later processing, we send temp1 back moved up by 50 degrees
' as such all processing in further code requires no negative nos
if temp1.bit15 = 1 then 'negative
Lcdout "-"
tempx = ~temp1 + %1 ' needed to calc correct display
temp1 = ( 50 << 4 ) - tempx ' add 50 to ensure we always get positive nos
else
tempx = temp1
temp1 = ( 50 << 4 ) + temp1 ' add 50 to keep sweet with neg nos
endif
endif
RETURN
------------------

As a bit of further info, there are probs with the later version DS18B20s which may also be coming into it, which is why they were pulled from the market.
The B6 die units have variable timing probs, and the B7 dies can lose their internal calibrations.
Andrew