DS18B20 zu hoher Temperaturwert!
Hallo Leute,
Hab schon in ganzen Forum geschaut aber leider hat bis jetzt noch keiner so was geschrieben!
Habe an einem ATmega8-16 einen DS18B20 1-Wire Temperatursensor angeschloss, leider bekomme ich aber nicht den richtigen Wert von dem Sensor. Wenn ich den Sensor länger in der Hand halte zeit er mehr als 100 Grad an. Kann es sein, dass sich der Sensor selber aufheitzt, denn heute früh wurde die Reumtemperatur angezeit und nach ein paar Secunden ist sie wieder auf mehr als das doppelte angestiegen.
Den verwendeten Code habe ich aus der Elektor Zeitschrift:
Code:
$regfile = "m8def.dat"
$baud = 19200
$hwstack = 32
$swstack = 32
$framesize = 32
$crystal = 8000000
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
Config Lcd = 16 * 2
Cls
'Config Portd.5 = Output 'LED 1
'Portd.5 = 1
'Led1 Alias Portd.5
'Config Portd.6 = Output 'LED 2
'Portd.6 = 1
'Led2 Alias Portd.6
'Config Portd.7 = Output 'LED 3
'Portd.7 = 1
'Led3 Alias Portd.7
'Config Portd.2 = Output 'Motor1, Pin 1 und 2 am Motorboard
'Portd.2 = 0
'Config Pinb.0 = Input 'Taster 1
'Portb.0 = 1
'Taster1 Alias Pinb.0
'Config Pinb.1 = Input 'Taster 2
'Portb.1 = 1
'Taster2 Alias Pinb.1
'Config Pinb.2 = Input 'Taster 3
'Portb.2 = 1
'Taster3 Alias Pinb.2
Config 1wire = Portd.2
Dim Rom(8) As Byte
Dim Temp1 As Single
Dim Temp2 As Single
Dim Tempdif As Single
Dim Id1(8) As Byte
Dim Id2(8) As Byte
Dim I As Integer
Id1(1) = 1wsearchfirst()
Id2(1) = 1wsearchnext()
I = 1wirecount()
Lcd I
For I = 1 To 8
Locate 1 , 1
Lcd Hex(id1(i));
Next
For I = 1 To 8
Locate 2 , 1
Lcd Hex(id2(i));
Next
Wait 1
Do
1wreset
1wwrite &HCC
1wwrite &H44
Ddrd.2 = 1
Waitms 800
Ddrd.2 = 0
1wreset
1wwrite &H55
For I = 1 To 8
1wwrite Id1(i)
Next I
1wwrite &HBE
Rom(1) = 1wread(1)
Temp1 = Rom(1) / 2
Locate 1 , 4
Lcd "T1: " ; Temp1
1wreset
1wwrite &H55
For I = 1 To 8
1wwrite Id2(i)
Next I
1wwrite &HBE
Rom(1) = 1wread(1)
Temp2 = Rom(1) / 2
Locate 2 , 4
Lcd "T2: " ; Temp2
Loop
End
Ich Verwende ein externes Crystal und die Fusebits hab ich auch richtig eingestellt!
Hat von euch jemand eine Idee woran das liegen kann?
Gruss Douser
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,
ich habe folgende Konfiguration der Fuse Bits:
(in PonyProg)
BOOTSZ1
BOOTSZ0
SUT0
CKSEL3
CKSEL2
CKSEL1
Häcken drin, was beutet: BIT = 0
Bei den Andern FuseBits ist nichts aktiviert was BIT =1 bedeutet.
An meinem Pollin Board habe ich ein zweizeiliges LCD dran, diese funktioniert auch.
Ich habe verwende den internen Quarz, hoffe ich jedenfalls.
Nach dem ich jetzt das Programm (siehe unten) hochgeladen habe, erhalte ich auch die Seriennummern der Sensoren.
Wenn ich einen Sensor abklemme erhalte ich auch die Fehlermeldung, das der entsprechende Sensor nicht am Bus ist.
Leider erhalte ich nur irgendwelche Werte als Min, MAX und aktuelle Temperatur.
Kann es sein, dass der Code mit der Umwandlung der 9 Bits falsch ist?
oder muss ich einen speziellen Quarz verwenden?
Im Anhang ist die LCD Ausgabe.
Das Beispiel ist von dem BASCOM Hersteller MCS.
Folgenden Code habe ich drin:
Code:
$regfile "m8def.dat"
$crystal = 1000000
Declare Sub Init
Declare Sub Convallt ' Convert T on ALL sensors
Declare Function Decigrades(byval Sc(9) As Byte) As Integer
Config Lcd = 16 * 2 'wir verwenden ein 16*2 Zeichen Display
' Im I/O Mode wird jeder Prozessor Pin einzeln angegeben
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portd.5 , Rs = Portd.6
Cursor Off Noblink
Config 1wire = Portd.4 '0,1,2 NOP 3,4,5,6,7 works good ON MY Equipment
'Temp variables
Dim B As Byte
Dim W As Word
'Program variables
'Implicit Err created by compiler
Dim Dg As Integer 'DECIgrades, I call it, cause I have no space for commas on the display....
Dim Min1 As Integer
Dim Min2 As Integer
Dim Max1 As Integer
Dim Max2 As Integer
Dim Dsid1(8) As Byte 'Dallas ID 64 bits incl CRC
Dim Dsid2(8) As Byte
'When used like this : DsId(1) = 1wread(8)
'DsId(1) = family code 'Ds1820 10h, DS18B20 28h, Ds18s20 10h
'DsId(2) '48 Bits Serial, LSB
'DsId(3)
'DsId(4)
'DsId(5)
'DsId(6)
'DsId(7) '48 Bits Serial, MSB
'DsId(8) '8 CRC
Dim Sc(9) As Byte
'Scratchpad 0-8 72 bits incl CRC, explanations for DS18b20
'Sc(1) 'Temperature LSB
'Sc(2) 'Temperature MSB
'Sc(3) 'TH/user byte 1 also SRAM
'Sc(4) 'TL/user byte 2 also SRAM
'Sc(5) 'config also SRAM x R1 R0 1 1 1 1 1 - the r1 r0 are config for resolution - write FF to byte for 12 bit - others dont care
'Sc(6) 'res
'Sc(7) 'res
'Sc(8) 'res
'Sc(9) '8 CRC
'DALLAS DS18B20 ROM and scratchpad commands''''''''''''''''''''''''''1wwrite....
'&H 33 read rom - single sensor
'&H 55 match rom, followed by 64 bits
'&H CC skip rom
'&H EC alarm search - ongoining alarm >TH <TL
'&H BE read scratchpad
'&H 44 convert T
Cls
Lcd "This is a 2sensor DS18B20 thermometer"
Locate 2 , 1
Lcd " by gote@sys-op.com"
For B = 1 To 20
Shiftlcd Left
Waitms 250
Next
Cls
W = 1wirecount()
' Here I assume 2 sensors - no errorcontrol made, but would be easy to do with the "Err"-variable
' Getting the two sensors IDs.
Dsid1(1) = 1wsearchfirst()
Do
Dsid2(1) = 1wsearchnext()
Loop Until Err = 1
' If displayed, everything went well.
' First sensor identified and stored in variable
If Dsid1(8) = Crc8(dsid1(1) , 7) Then ' Control that the received CRC match the calculated
Locate 1 , 1
Lcd "CRC OK Sensor 1 ID"
Wait 1
Locate 1 , 1
For B = 1 To 8
Lcd Hex(dsid1(b))
Next
End If
' Second sensor
If Dsid2(8) = Crc8(dsid2(1) , 7) Then
Locate 2 , 1
Lcd "CRC OK Sensor 2 ID"
Wait 1
Locate 2 , 1
For B = 1 To 8
Lcd Hex(dsid2(b))
Next
End If
Wait 1
Cls
Init
' Main loop
Do
Convallt ' "Convert ALL T on the 1w-bus"
Waitms 800 'if you use 2-wire, could be reduced to 200us
1wverify Dsid1(1) 'Issues the "Match ROM "
Locate 1 , 1
If Err = 1 Then
Lcd "Err " 'Err = 1 if something is wrong
Elseif Err = 0 Then 'lcd " Sensor found"
1wwrite &HBE
Sc(1) = 1wread(9) 'read bytes into array
If Sc(9) = Crc8(sc(1) , 8) Then
Dg = Decigrades(sc(9))
If Min1 > Dg Then Min1 = Dg
If Max1 < Dg Then Max1 = Dg
Lcd Dg : Locate 1 , 7 : Lcd Min1 : Locate 1 , 14 : Lcd Max1
End If
End If
1wverify Dsid2(1)
Locate 2 , 1
If Err = 1 Then
Lcd "DsId2 not on bus "
Elseif Err = 0 Then ' lcd " Sensor found "
1wwrite &HBE
Sc(1) = 1wread(9)
If Sc(9) = Crc8(sc(1) , 8) Then
Dg = Decigrades(sc(9))
If Min2 > Dg Then Min2 = Dg
If Max2 < Dg Then Max2 = Dg
Lcd Dg : Locate 2 , 7 : Lcd Min2 : Locate 2 , 14 : Lcd Max2
End If
End If
Wait 1
Loop
End 'end program
'Sets variables and LCD for further use'''''''''''''''''''''''''''''''''''''''''
Sub Init
Cls
Lcd " Min Max"
Locate 2 , 1
Lcd " Min Max"
Min1 = 999 ' to get a real value from start
Min2 = 999
End Sub
'Makes the Dallas "Convert T" command on the 1w-bus configured in "Config 1wire = Portb. "
'WAIT 200-750 ms after issued, internal conversion time for the sensor''''''''''
'SKIPS ROM - so it makes the conversion on ALL sensors on the bus simultaniously
'When leaving this sub, NO sensor is selected, but ALL sensors has the actual
'temperature in their scratchpad ( within 750 ms )
Sub Convallt
1wreset ' reset the bus
1wwrite &HCC ' skip rom
1wwrite &H44 ' Convert T
End Sub
'Makes a integer value of the first two bytes in scratchpad'''''''''''''
'Works on DS18 B 20 , observe "B". The R0 and R1 in Sc(5) tells you how many bits are accurate
Function Decigrades(byval Sc(9) As Byte)
Decigrades = 0
Decigrades = Makeint(sc(1) , Sc(2))
Decigrades = Decigrades * 10
Decigrades = Decigrades / 16
End Function
' If you have DS1820 or DS18 S 20 , you can use this algo instead:
' Observe that DsId1(1) contains the info value of which sensor is used.
'(
Function Decigrades(byval Sc(9) As Byte)
Dim Tmp As Byte , T As Integer , T1 As Integer
Tmp = Sc(1) And 1 ' 0.1C precision
If Tmp = 1 Then Decr Sc(1)
T = Makeint(sc(1) , Sc(2))
'Print Hex(t)
'Print T
T = T * 50 'here we calculate the 1/10 precision like
T = T - 25 'DS18S20 data sheet
T1 = Sc(8) - Sc(7)
T1 = T1 * 100
T1 = T1 / Sc(8)
T = T + T1
Decigrades = T / 10
'As integer, this routine gives T*10, with 1/10 degree precision
End Function
')
[/code]