logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak obsłużyć 3 czujniki DS18B20 w Bascom na Atmega8? Szukam działającego kodu.

pmmisiek 10 Lip 2006 00:20 3713 5
  • #1 2806153
    pmmisiek
    Poziom 15  
    Posty: 234
    Pomógł: 7
    Ocena: 4
    Witam.
    Szukałem już duuuużo na forum i nie znalazłem działającego kodu do obsługi trzech czujników ds18b20 (nie działa mi nawet obsługa dwóch)

    Jeśli ktoś wie jak to zrobić to prosiłbym o pomoc.

    PS. Jeden czujnik obsługuje się w miare prosto.
    Wynik wyświetla z rozdzielczością do 0.1 st C i działa OK
    
    $regfile = "m8def.DAT"
    $crystal = 1000000
    '$lib "mcsbyte.lib"
    
    
    
    Config Lcdbus = 4
    
    Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.6 , Rs = Portd.4
    
    
    Config 1wire = Portc.5
    Dim I As Integer , Ss As String * 6
    'Dim S As Single
    Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
    Cursor Off
    Cls
    Do
       1wreset
       1wwrite &HCC
       1wwrite &H44
       Waitms 800
       1wreset
       1wwrite &HCC
       1wwrite &HBE
       I = 1wread(2)
       I = I * 10
       I = I / 16
       Ss = Str(i)
       Ss = Format(ss , "  0.0")
       Locate 1 , 1
       Lcd "Temp:" ; Ss ; Chr(0) ; "C"
    Loop
    


    byłbym wdzięczny za modyfikację tego kodu lub wskazówki, tak żeby działał na 3 czujniki i nie był za bardzo skomplikowany (ten jest ok ) ale niektóre kody na forum do obsługi jednego czujnika są dużo dłuższe, a co dopiero do dwóch

    Pozdrawiam
  • #2 2806690
    pmmisiek
    Poziom 15  
    Posty: 234
    Pomógł: 7
    Ocena: 4
    
    $regfile = "m8def.DAT"
    $crystal = 1000000
    '$lib "mcsbyte.lib"
    
    Declare Sub Init
    Declare Sub Convallt                                        ' Convert T on ALL sensors
    Declare Function Decigrades(byval Sc(9) As Byte) As Integer
    
    Config Lcdbus = 4
    
    Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.6 , Rs = Portd.4
    
    
    Config 1wire = Portc.5
    '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
    Dim Dsid3(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 "Pomiar temp."
    Locate 2 , 1
    Lcd "dwa czujniki"
    Wait 1
    
    'Wait 2
    Cls
    W = 1wirecount()
    Lcd W
    Wait 1
    Cls
    
    ' 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
    
    Do
     Dsid3(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
    Wait 2
    
    ' 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 2
    
    If Dsid3(8) = Crc8(dsid3(1) , 7) Then
     Locate 2 , 1
     Lcd "CRC OK Sensor 3 ID"
     Wait 1
     Locate 2 , 1
     For B = 1 To 8
     Lcd Hex(dsid3(b))
     Next
    End If
    Wait 2
    
    Wait 1
    Cls
    
    Init
    
    ' Main loop
    Do
     Convallt                                                   ' "Convert ALL T on the 1w-bus"
     Wait 1                                                     '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
    

    obsługa dwóch DS-ów już działa, ale nie wiem jak dodać trzeciego. Przy sprawdzaniu ID 3 czujnika jest ono takie same jak ID 2, tak to próbowałem odczytać:

    Dsid1(1) = 1wsearchfirst()
    Do
     Dsid2(1) = 1wsearchnext()
    Loop Until Err = 1
    
    Do
     Dsid3(1) = 1wsearchnext()
    Loop Until Err = 1
    
  • Pomocny post
    #3 2807134
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    pmmisiek napisał:

    DS-ów już działa, ale nie wiem jak dodać trzeciego. Przy sprawdzaniu ID 3 czujnika jest ono takie same jak ID 2, tak to próbowałem odczytać:
    Dsid1(1) = 1wsearchfirst()
    Do
     Dsid2(1) = 1wsearchnext() 'nadpisuje ID2 , ID3
    Loop Until Err = 1
    
    Do
     Dsid3(1) = 1wsearchnext()
    Loop Until Err = 1
    

    Ja zaryzykuję stwierdzenie , że ID2 jest takie jak ID3
    Najprościej to:
    
    Dsid1(1) = 1wsearchfirst()
    Dsid2(1) = 1wsearchnext()
    Dsid3(1) = 1wsearchnext()
    ...
    

    Jeśli chciałbyś by program "wykrywał" ilość DS-ów i zapisywał ich ID, to musisz zbudować odpowiednią pętlę ;)

    Piotrek
  • #4 2807471
    pmmisiek
    Poziom 15  
    Posty: 234
    Pomógł: 7
    Ocena: 4
    Dzięki kolego Zumek za wskazówki, teraz już dzialają 3 czujniki, jeśli byś mógł to doradź coś o optymalizacji kodu, bo w takiej wersji wsad zajmuje 7,77KB a chce coś jeszcze do tego dorzucić i nie wiem czy sie zmieszcze w 8KB

    
    $regfile = "m8def.DAT"
    $crystal = 1000000
    '$lib "mcsbyte.lib"
    
    
    
    Config Lcdbus = 4
    
    Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.6 , Rs = Portd.4
    
    
    Config 1wire = Portc.5
    Dim I1 As Integer , Ss As String * 6
    Dim I2 As Integer
    Dim I3 As Integer
    'Dim S As Single
    
    Dim Dsid1(8) As Byte                                        'Dallas ID 64 bits incl CRC
    Dim Dsid2(8) As Byte
    Dim Dsid3(8) As Byte
    Dim B As Byte
    Dim W As Byte
    
    Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
    Cursor Off
    Cls
    Lcd "Pomiar temp."
    Cls
    W = 1wirecount()
    Lcd W
    Wait 1
    Cls
    Dsid1(1) = 1wsearchfirst()
    Dsid2(1) = 1wsearchnext()
    Dsid3(1) = 1wsearchnext()
    '*******************wyipisanie ID***************************
    If Dsid1(8) = Crc8(dsid1(1) , 7) Then  ' 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
    Wait 2
    
    ' 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 2
    
    If Dsid3(8) = Crc8(dsid3(1) , 7) Then
     Locate 2 , 1
     Lcd "CRC OK Sensor 3 ID"
     Wait 1
     Locate 2 , 1
     For B = 1 To 8
     Lcd Hex(dsid3(b))
     Next
    End If
    Wait 2
    Cls
    '********koniec wypisania ID*********************
    
    Do
       1wreset
       1wwrite &H55
       1wverify Dsid1(1)
       1wwrite &HBE
       I1 = 1wread(2)
    '---------------------------------
       1wreset
       1wwrite &H55
       1wverify Dsid2(1)                                        'wysylam adres drugiego czujnika
       1wwrite &HBE
       I2 = 1wread(2)
    '---------------------------------
       1wreset
       1wwrite &H55
       1wverify Dsid3(1)                                        'wysylam adres trzeciego czujnika
       1wwrite &HBE
       I3 = 1wread(2)
    '--------konwersja temp dla wszystkich dsow
       1wreset                                                  ' reset the bus
       1wwrite &HCC                                             ' skip rom
       1wwrite &H44                                             ' Convert T
    Wait 1
    
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , "  0.0")
       Locate 1 , 1
       Lcd "1" ; Ss ; Chr(0) ; "C"
    
       I2 = I2 * 10
       I2 = I2 / 16
       Ss = Str(i2)
       Ss = Format(ss , "  0.0")
       Locate 2 , 1
       Lcd "2" ; Ss ; Chr(0) ; "C"
       'Wait 2
       I3 = I3 * 10
       I3 = I3 / 16
       Ss = Str(i3)
       Ss = Format(ss , "  0.0")
       Locate 1 , 9
       Lcd "3" ; Ss ; Chr(0) ; "C"
    
    
    Loop
    
    


    Mam jeszcze małe pytanko:
    Do zaadresowania ds-a użyłem:
    1wverify Dsid1(1)
    bo kompilator zgłaszał błąd, gdy chciałem wysłać adres poleceniem:
    1wwrite Dsid1(1), 8
  • #6 3847661
    pawlo002
    Poziom 11  
    Posty: 12
    hej niech ktoś podpowie czy dobrze rozumiem wywoływania jednego ds-a
    1)RESET() - 1wire
    2)wysłanie 0x55
    3)wysłanie adresds18b20[0x28] -0 bit
    4)wysłanie adresds18b20[0x..]-1 bit
    5)wysłanie adresds18b20[0x..]-2 bit
    6)wysłanie adresds18b20[0x..]-3 bit
    7)wysłanie adresds18b20[0x..]-4 bit
    8)wysłanie adresds18b20[0x..]-5 bit
    9)wysłanie adresds18b20[0x..]-6 bit
    10)wysłanie adresds18b20[0x..]-7 bit
    11)wysłanie 0xBE
    12)odczytanie temperatura[0]
    13)odczytanie temperatura[1]

    i już powinien odezwać sie konkretny czujnik ???? a Conver_T 0x44?????????????
REKLAMA