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

[Atmega162][Bascom] 8 * DS18B20 na osobnych pinach bez ID.

adambehnke 07 Sty 2011 18:06 3045 12
  • #1 8972586
    adambehnke
    Poziom 24  
    Witam

    Muszę stworzyć układ w którym bedę używał 8 czujników DS18B20 , i każdy musi pracować na osobnym pinie. Nie mogę podpiąć wszystkich na jednej linii i odpytywać ich po ich ID.
    Kiedyś robiłem sterownik w którym odczyty robiłem w ten sposób:

    Sub Odcz_temp1                                                                                                                                       
     Config 1wire = Portb.0
    1wreset                                                                                                  1wwrite &HCC                                                                                                                                           'opuszczenie zapisu numeru ID
     1wwrite &H44                                                                                                                                           'start pomiaru temperatury
     'Waitms 150                                                 'opóźnienie na czas pomiaru
     1wreset                                                                                                                                                'reset magistrali 1-Wire
     1wwrite &HCC                                                                                                                                           'opuszczenie zapisu numeru ID
     1wwrite &HBE                                                                                                                                           'komenda odczytu zmierzonej temperatury
     Temperatura(1) = 1wread(2)                                                                                                                             'odczyt zmierzonej temperatury do tablicy Temperatura
     1wreset                                                                                                                                                'reset magistrali 1-Wire
     If Temperatura(2) > 0 Then                                                                                                                             'jeśli zmienna Temperatura(2)
          '> 0, to temperatura ujemna
          'przeliczenie temperatury
          'ujemnej
      Temperatura(1) = 256 - Temperatura(1)
     End If                                                                                                                                                 'koniec warunku
     Temperatura(1) = Temperatura(1) / 2
          'dalsze przeliczenie odczytanej
          'temperatury dodatniej jak
          'i ujemnej
    End Sub                                                                                                                                                 'koniec procedury pomiaru
    
    
    
    
    Sub Odcz_temp2                                                                                                                                          'procedury pomiaru temperatury
    
     Config 1wire = Portb.1
    
     1wreset                                                                                                                                                'reset magistrali 1-Wire
     1wwrite &HCC                                                                                                                                           'opuszczenie zapisu numeru ID
     1wwrite &H44                                                                                                                                           'start pomiaru temperatury
     'Waitms 150                                                 'opóźnienie na czas pomiaru
     1wreset                                                                                                                                                'reset magistrali 1-Wire
     1wwrite &HCC                                                                                                                                           'opuszczenie zapisu numeru ID
     1wwrite &HBE                                                                                                                                           'komenda odczytu zmierzonej temperatury
     Temperatura(3) = 1wread(4)                                                                                                                             'odczyt zmierzonej temperatury do tablicy Temperatura
     1wreset                                                                                                                                                'reset magistrali 1-Wire
     If Temperatura(4) > 0 Then                                                                                                                             'jeśli zmienna Temperatura(2)
          '> 0, to temperatura ujemna
          'przeliczenie temperatury
          'ujemnej
      Temperatura(3) = 256 - Temperatura(3)
     End If                                                                                                                                                 'koniec warunku
     Temperatura(3) = Temperatura(3) / 2
          'dalsze przeliczenie odczytanej
          'temperatury dodatniej jak
          'i ujemnej
    End Sub                                                                                                                                                 'koniec procedury pomiaru
    
    Sub Odcz_temp3


    itd.
    Czyli za każdym razem na nowo konfigurowałem port pod odpowiedni czujnik:

    Config 1wire = Portb.1



    Wiem że wg. bascomowego helpa nie powinno się tak robić ale mi to działało i to nawet bez oczekiwania na konwersję 750ms.

    Jak powinienem zrobić odczyt z takich czujników. Muszę zacząć projektować PCB (na wczoraj) i nie chciałbym popełnić serii błędów.

    Urządzenie będzie miało "dopinane" czujniki pod każdy port. Tak że w razie uszkodzenia czujnika po prostu odpina się jeden i wpina zapasowy.
  • #3 8974329
    adambehnke
    Poziom 24  
    Nawet nie wiedziałem że nowych wersjach Bascoma można robić takie rzeczy.
    Czyli , czy miało by to wyglądać tak: ?

    'DS-y na pinach B.0 - B.7
    
    
    
    '***********************************************************************************'
    '*********************************1 WIRE SET****************************************'
    '***********************************************************************************'
    Ds1_set:
    
        1wreset Pinb , 0
        1wwrite &HCC , 1 , Pinb , 0                                                                                                                         'pominięcie podania adresu  .Czyli do ALL
        1wwrite &H44 , 1 , Pinb , 0                                                                                                                         'Polecenie konwersji temperatury
    
    Return
    '***********************************************************************************'
    
    
    
    
    
    '***********************************************************************************'
    '*********************************1 WIRE READ***************************************'
    '***********************************************************************************'
    Ds1_read:
    
         1wreset Pinb , 0                                                                                                                                   'reset magistrali 1WIRE
         1wwrite &HCC , 1 , Pinb , 0
         1wwrite &HBE , 1 , Pinb , 0                                                                                                                        'rozkaz READ_SCRATCHPAD
    
        1w_i1 = 1wread(2)                                                                                                                                   'Odczyt
        1w_i1 = 1w_i1 * 10                                                                                                                                  'Konwersja
        '1w_i1 = 1w_i1 / 16                                       '18b20
        1w_i1 = 1w_i1 / 2                                                                                                                                   '1820
        Ss = Str(1w_i1)
        Ss = Format(ss , "00.0")
    
    Return
    '***********************************************************************************'


    Oczywiście przed odczytem czekam 750ms. W którym miejscu mam jeszcze błąd. Dodam że 1W nie jest moją mocną stroną :/
  • #5 8974496
    adambehnke
    Poziom 24  
    '***********************************************************************************'
    '*********************************1 WIRE READ***************************************'
    '***********************************************************************************'
    Ds1_read:
    
         1wreset Pinb , 0                                                                                                                                   'reset magistrali 1WIRE
         1wwrite &HCC , 1 , Pinb , 0
         1wwrite &HBE , 1 , Pinb , 0                                                                                                                        'rozkaz READ_SCRATCHPAD
    
        1w_i1 =1wread(1 , Pinb , 0)                                                                                                                                 'Odczyt
        1w_i1 = 1w_i1 * 10                                                                                                                                  'Konwersja
        '1w_i1 = 1w_i1 / 16                                       '18b20
        1w_i1 = 1w_i1 / 2                                                                                                                                   '1820
        Ss = Str(1w_i1)
        Ss = Format(ss , "00.0")
    
    Return
    '***********************************************************************************'  



    Czy taka forma jest poprawna? Docelowo zrobie odczyt wszystkich DS-ów w pętli , gdyż spoglądając na Helpa widzę że jest to możliwe. Oczywiście jak pozbędę się błędów z tego kodu :)
  • Pomocny post
    #6 8974862
    piotrva
    VIP Zasłużony dla elektroda
    Wygląda ok.
    A z ciekawości dlaczego nie może być na jednej linii?
  • #7 8974893
    adambehnke
    Poziom 24  
    Gdyż musiałbym znać ich seriale i według nich odpytywać dany układ . A tak wiem która linii idzie do danego zbiornika i mogę odczytać temperaturę z tego układu nie znając jego ID. Dodatkowo w każdej chwili mogę wymienić taki układ na nowy i bez problemu zadziała.
  • #8 8993094
    adambehnke
    Poziom 24  
    Niestety jakoś mi ten sposób odczytu nie chce działać.

    Obecnie używam takiego sposobu odczytu:

     Config 1wire = Portc.6
    
     1wreset                                                                                                                                                'reset magistrali 1-Wire
     1wwrite &HCC                                                                                                                                           'opuszczenie zapisu numeru ID
     1wwrite &H44                                                                                                                                           'start pomiaru temperatury
    Waitms 750                                                                                                                                               'opóźnienie na czas pomiaru
     1wreset                                                                                                                                                'reset magistrali 1-Wire
     1wwrite &HCC                                                                                                                                           'opuszczenie zapisu numeru ID
     1wwrite &HBE                                                                                                                                           'komenda odczytu zmierzonej temperatury
    1w_i1 = 1wread(2)
        1w_i1 = 1w_i1 * 10                                                                                                                                  'Konwersja
        1w_i1 = 1w_i1 / 16                                                                                                                                  '18b20
        '1w_i1 = 1w_i1 / 2                                                                                                                                   '1820
        Ss(2) = Str(1w_i1)
        Ss(2) = Format(ss(2) , "00.0")


    Ale czasami odczyty przyjmują na moment jakieś dziwne wartości a potem wracają do normy.
    Czy problemem mogą być jakieś przerwania ? Używam na razie tylko przerwania od TIMERA3. W sumie cały kod to tylko jak na razie obsługa LCD 2*16 i 7 ds18b20.

    Co może być problemem?
  • Pomocny post
    #11 8993497
    piotrva
    VIP Zasłużony dla elektroda
    Cóż coś za coś. 1w opiera się na różnicach czasu i każde zakłócenie powoduje błędy.
  • #12 8993526
    xury
    Specjalista automatyka domowa
    Spróbuj znaleźć, dokładnie które przerwanie ci przeszkadza. Mnie np przeszkadzało tylko INT0 przy jedoczesnym odczycie RC5 więc na czas wysyłania wyłączałem tylko to przerwanie:
    
    Disable Int0
    1wreset
    1wwrite &H55
    1wwrite Dsadres1(1) , 8
    1wwrite &HBE
    Enable Int0
    Tempw = 1wread(2)
    Tempw = Tempw * 10
    Tempw = Tempw / 16
    Tekst1 = Str(tempw)
    Tekst1 = Format(tekst1 , "+0.0")
    Disable Int0
    1wreset
    1wwrite &H55
    1wwrite Dsadres2(1) , 8
    1wwrite &HBE
    Enable Int0
    Tempw = 1wread(2)
    Tempw = Tempw * 10
    Tempw = Tempw / 16
    Tekst2 = Str(tempw)
    Tekst2 = Format(tekst2 , "+0.0")
    
  • #13 8993568
    adambehnke
    Poziom 24  
    Poszedłem po rozum do głowy i zastosowałem sprawdzanie CRC8 . Okazało się że konwersja temperatury w układach DS18b20 przebiegała poprawnie a uszkodzeniu ulegały dane podczas zczytywania ich z układów. Po sprawdzaniu sumy kontrolnej pomijam błędne dane i wyświetlam tylko prawidłowe dane.
    Chociaż tym przerwaniom także muszę się przyjrzeć.

    Zatem zrobiłem tak;



          1wreset
          1wwrite &HCC
          1wwrite &HBE
          Sc(1) = 1wread(9)                                                                                                                                 'odczytujemy wszystkie bajty z czujnika
    
          If Sc(9) = Crc8(sc(1) , 8) Then          'obliczamy CRC i porownujemy z przyslanym przez czujnik
    
               Temperatura = Makeint(sc(1) , Sc(2))                                                                                                         'tu laczymy dwa bajty zawierajace temperature
               Temperatura = Temperatura * 10                                                                                                               'obliczamy temperature
               Temperatura = Temperatura / 16                                                                                                               'nie bylo bledu CRC
               Reset Blad_crc                                                                                                                               'wiec zerujemy flage bledu CRC
               T(6) = Str(temperatura)
               T(6) = Format(t(6) , "00.0")
          Else                                                                                                                                              'jesli byl blad CRC
             Set Blad_crc                                                                                                                                   'ustawiamy flage bledu CRC
          End If




    Dzięki



    edit:
    A najlepsze jest to że działa mi to nawet bez oczekiwania 750ms. Dziwne ale działa poprawnie .
REKLAMA