Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Pomiar temperatury czujnikiem DS18b20 przy użyciu procesora 89c4051

19 Lut 2007 21:07 2349 27
  • Poziom 19  
    Witam szanownych kolegów,tym razem postanowiłem sobie zrobic termometr na pieciu układach ds18b20 wynik pomiaru mialbybyc wyswietlany na lcd 2*16 a calóscia by sterował procek 89c4051,i tu moje pytanie moze ktoś zWas ma cos podobnego w swoich zbiorach (program napisany w jezyku BASCOM) goglowałem ale niestety nic nie znalazłem,za pomoc z góry bardzo dziekuje i pozdrawiam.
  • Poziom 19  
    tak tylko nie wiem jak to ugryść z jednym czujnikiem nie ma problemu???
  • Poziom 19  
    Szkoda ze nikt mi nie chce pomóc ,jakoś sobie bede musiał sam poradzic:(
  • Pomocny post
    Poziom 21  
    Siemka!

    Nie ma większego problemu i z paroma czujnikami. Rozwiązania tego problemu są conajmniej dwa.

    1. Wrzucasz czujniki każdy na innym pinie portu mikrokontrolera i odczytujesz wynik korzystając właśnie z algorytmu dla jednego czujnika. Jedyna kwestia to tylko sekwencyjne przełączanie interface'u 1-Wire pomiędzy połączonymi z czujnikami pinami portu. Zaletą tej metody jest łatwiejsza identyfikacja czujników, konkretny czujnik, konkretny port.

    2. Podłączasz wszystkie czujniki na jednym pinie i algorytm nieco sie komplikuje. Najpierw przeszukujesz magistralę 1-Wire, zapamiętujesz w jakiejś zmiennej tablicowej adresy czujników, najlepiej kopiujesz do EEPROM i potem te same algorytmy odczytu i konwersji z tym że wszystko zapętlasz w pętli for next i wykonujesz tyle razy ile masz czujników. Kłopotliwa jest konfiguracja, bo funkcje Bascom wykrywają po kolei numery czujników, co nie koniecznie musi odpowiadać ich hierarchii w rzeczywistości.

    Ja zrobiłem urządzenie które obsługuje 9 czujników z tym że na AVR ATmega8 i powiem Ci że 4k pamięci w Twoim kontrolerze na obsługe tego sprzętu w Bascom, to może być trochę mało. Ale próbuj :)

    Miłej zabawy życzę i w razie problemów pytać, rozgryzłem parę problemów w tej dziedzinie więc służę pomocą :)

    Pozdrawiam Electix
  • Poziom 19  
    Dziękuje koledze Electix za wskazówki i mam prosbe czy mógłbyś udostępnic mi wsad na atmege bo gdy 89c4041 okaze sie za mały to mam atmege8535 do której sie przymierzam poraz pierwszy i moze mógłbym program troche przerobic na swoje potrzeby,jeszcze raz wielkie dzieki i pozdrawiam.
  • Poziom 19  
    Pomimo przekopania tego forum i goglowania oraz waszej pomocy nic mi nie wyszło chyba sie poddam z tymi kilkoma czujnikami.
  • Poziom 19  
    Panowie ,mam propozycje dla Was,rozumiem ze nie ma nic za darmo wiec prosze zaproponowac cene za napisanie dla mnie programu w bascomie na cztery czujniki DS1820 i na procesor 89c4051 jesli 4kB pamieci za mało to moze byc dołączona pamiec zewnetrzna 24cxx.Ewentualne oferty na forum lub prywatnie.
  • Poziom 14  
    Witam

    a z czym masz konkretnie problem bo pewnie da sie rozwiazac (tymbardziej, ze bascom) ??

    pozdrawiam
    l
  • Poziom 19  
    Dziekuja za zainteresowanie mój problem jest taki jak większości z odczytaniem jednego czujnika nie ma problemu ale z kilkoma sie zaczynają schody nie wiem jak sie zabrac do zapisu numerów seryjnych które nastepnie bedą służyły do odczytu poszczególnych czujników,
  • Poziom 14  
    Njprosciej bedzie zaczac od czytania polskiego helpa do bascoma (znajdziesz w sieci bez problemu)

    do przechowywania numerow polecam uzyc pamieci eeprom, spora czesc procesorow ma ja wbudowana - z poziomu bascoma chyba najprostszym sposobem jej uzycia jest :

    Code:
    Dim store as eram byte, b as byte
    
    b = 10         'przypisujemy wartosc do b
    store = b     'wartosc z b trafia do eepromu
    b = store     'odczytujemy wartosc z eepromu

    Jak opanujesz uzycie eepromu chocby w tej formie poszukaj w hephie na okolo 110 stronie polecenia 1wsearchfirst() oraz 1wsearchnext() dowiesz sie z ich opisu jak znalezc uklady podlaczone do magistrali pozniej to juz prosta sprawa :) zaadresowac, odczytac i wyswietlic, i jeszcze uwaga praktyczna poczytaj tez o timerze i przerwaniach no chyba ze czas dostepu do wybranej temperatury nie jest krytyczny i moze trwac okolo 5 sekund :)

    pozdrawiam
  • Poziom 19  
    Skleciłem cos takiego pomiar z trzech czujników,odczyt z poszczególnego czujnika odbywa sie za pomocą przycisku podłączonego do pinu p3.7 procesora 89c4051,wynik dodatkowo przesyłam do komputera,czujniki sa na stałe wpisane,i tu moje pytanie co można w tym programie zoptymalizować może deklaracje czujnikó próbowałem za pomoca czegos takiego ale mi nie wychodzi:
    1wwrite adr
    adr:
    data tu numer seryjny czujnika
    a oto cały program:
    $crystal = 11059200
    $large 'konfiguruje magistralę 1wire na P1.0 (Open Colector)
    Config Lcd = 16 * 2
    $baud = 9600

    Deflcdchar 1, 4, 10, 4, 32, 32, 32, 32, 32
    Dim T1 As Single
    Dim T2 As Single
    Dim B1 As Byte, B2 As Byte
    Dim Tmp As String * 6
    Dim Adr(8) As Byte
    Dim Znak As String * 1
    Dim I As Byte
    Dim Adr1(8) As Byte
    Dim Adr3(8) As Byte
    Dim M As String * 6
    Dim L As Byte

    L = 0
    Cursor Off
    Adr(1) = &H10
    Adr(2) = &HEC
    Adr(3) = &HA1
    Adr(4) = &H25
    Adr(5) = &H1
    Adr(6) = &H8
    Adr(7) = &H0
    Adr(8) = &H7D

    Adr1(1) = &H10
    Adr1(2) = &H90
    Adr1(3) = &HDE
    Adr1(4) = &H25
    Adr1(5) = &H1
    Adr1(6) = &H8
    Adr1(7) = &H0
    Adr1(8) = &H9A

    Adr3(1) = &H10
    Adr3(2) = &H94
    Adr3(3) = &HD0
    Adr3(4) = &H25
    Adr3(5) = &H1
    Adr3(6) = &H8
    Adr3(7) = &H0
    Adr3(8) = &HE4




    Config 1wire = P1.0
    Cls

    Do
    1 wreset
    1 wwrite &HCC
    1 wwrite &H44

    Wait 1



    1 wreset
    1 wwrite &H55

    If P3.7 = 0 Then
    Incr L
    End If
    If L > 2 Then L = 0

    If L = 0 Then
    1 wwrite Adr(1), 8
    M = "Tem1"
    End If

    If L = 1 Then
    1 wwrite Adr1(1), 8
    M = "Tem2"
    End If

    If L = 2 Then
    1 wwrite Adr3(1), 8
    M = "Tem3"
    End If




    1 wwrite &HBE
    B1 = 1wread()
    B2 = 1wread()
    1 wreset


    If B2 >= 248 Then
    B1 = 255 - B1
    B2 = 255 - B2
    Znak = "-"
    Else
    Znak = "+"
    End If
    T1 = B1 / 2
    T2 = B2 * 10
    T1 = T1 + T2

    Tmp = Fusing(t1 , ###.&)


    Cls
    Lcd Znak ; Tmp ; Chr(1) ; "C"
    Locate 2, 3
    Lcd M
    Print Tmp

    Wait 1

    Loop
  • Pomocny post
    Poziom 39  
    scal12 napisał:
    ... i tu moje pytanie co można w tym programie zoptymalizować może deklaracje czujnikó próbowałem za pomoca czegos takiego ale mi nie wychodzi:
    1wwrite adr
    adr:
    data tu numer seryjny czujnika

    Numer ID DS-a wystarczy umieścić w pamięci programu , tak jak zamierzałeś.
    Code:

    'jest
    1wwrite Id(1) , 8
    '...
    'popraw na

    For x=0 to 7
       y=Lookup(x,adr)
       1wwrite y
    next

    adr:
    data tu numer seryjny czujnika

    Pozbądź się również zmiennych Single , bo Ci jak nic flash-u braknie ;)
    Pamiętaj również , o niepowielaniu niemal identycznych ciągu instrukcji.
    Jedna pętla For ... Next wystarczy do zaadresowania wielu DS-ów , tylko trzeba ... jak zwykle pomyśleć :D

    Piotrek
  • Poziom 19  
    Bardzo dziekuje za podpowiedz i juz sie zabieram do zmiany programu
  • Pomocny post
    Poziom 21  
    Siemka!

    A ja mam troszkę inną propozycję dla Ciebie.

    Nie zapisuj numerów czujników w pamięci programu. Poza tym lepiej jest mieć uniwersalny termometr gdzie jak uszkodzi się jeden czujnik, to z łatwością można zastąpić go innym.
    Zadeklaruj sobie takie zmienne:
    Code:

    dim dsid(40) as eram byte ' zmienna tablicowa (EEPROM) dla 5 czujników
    dim dstmp(8) as byte ' zmienna tymczasowa S/N czujnika
    dim ptr as byte ' wskaźnik do pierwszego bajtu każdego adresu w dsid
    dim i as byte ' zmienna do petli
    dim i as byte ' zmienna do petli

    Pierwsza znajduje się w pamięci EEPROM i przechowuje wszystkie numery seryjne podpiętych do układu czujników. Druga zmienna służy do czasowego przechowywania adresu czujnika aktualnie obsługiwanego.
    i teraz procedurka zapisu adresów do pamięci eeprom:

    Code:

    sub zapis
    for i=1 to 5 step 1
    cls
    lcd "podłącz czujnik:" ; I ;
    do
    1wreset
    lowerline
    if err= 0 then
    lcd "1 wire test    ok"
    else
    lcd "1 wire test error"
    wait 1
    loop until err=0
    dstmp(1)=1wsearchfirst
    locate 2,1
    for a= 8 to 1 step -1
    lcd hex(dstmp(a)
    next a
    wait 1
    ptr=I-1
    ptr=ptr*8
    incr ptr
    for a=1 to 8 step 1
    dsid(ptr)=dstmp(a)
    incr ptr
    next a
    wait 1
    next i
    end sub

    Tak wygląda napisana na kolanie procedurka do zapisu adresów czujników w pamięci EEPROM mikrokontrolera. Przeanalizuj ją, może zmień coś w razie potrzeb (ja to pisałem w BASCOM AVR), a jakbyś miał jeszcze jakieś pytania to wal śmiało.

    Pozdrawiam Electix
  • Poziom 39  
    Mam jedno "zastrzeżenie" , jeśli chodzi o powyższy przykład.
    Ta procedura zapisze pięciokrotnie , pierwszy odnaleziony SN i to bez względu na ilość DS-ów na magistrali , czyli nawet dla jednego.Natomiast z samą ideą zgadzam sie w pełni :D

    Piotrek
  • Poziom 19  
    Dziekuje za kolejna podpowiedz i mam pytanie może dziecinne ale dla mnie to moze byc spory problem jak zrealizować procedure odczytu numeru seryjnego danego czujnika z pamieci eprom?
  • Poziom 21  
    Siemka!

    Apropos wypowiedzi Zumka. Tak będzie jak mówisz jeżeli nie będzie się podłączało kolejnych czujników to będzie zapisywany wciąż ten sam:) ale można dopisać jeden warunek z badaniem wykrytego kolejnego numeru czy nie jest taki sam jak jakikolwiek zapisany poprzednio i po kłopocie :). To jest tylko wyrwana z kontekstu całego programu procedurka, która całkiem nieźle się spisuje. Ja obsługuję w tym programie też wyświetlacz 4x20 znaków i tak komunikaty ekranowe prowadzą przez procedurę konfiguracyjną co pomaga:)
    Jeżeli chodzi o Twoje pytanie scal12:
    Jak zrealizować procedurę odczytu numeru seryjnego danego czujnika z pamięci eprom?
    Jest to proste w mojej procedurce widnieje zapis
    Code:

    ptr=I-1
    ptr=ptr*8
    incr ptr
    for a=1 to 8 step 1
    dsid(ptr)=dstmp(a)
    incr ptr
    next a

    w celu odczytu pamięci eeprom robisz odwrotnie czyli przepisujesz zawartość odpowiednich bajtów z pamięci eeprom do tymczasowej pamięci numeru S/N. Próbowałem w swoim programie bezpośrednio adresować z pamięci eeprom, ale to nie za bardzo działało nie wiedzieć czemu. W helpie do bascoma
    http://www.mcselec.com/index.php?option=com_docman&task=cat_view&gid=86&Itemid=54
    masz fajnie opisane przykłady obsługi pamięci eeprom...
  • Poziom 39  
    Electix napisał:
    ... masz fajnie opisane przykłady obsługi pamięci eeprom...

    Jest tylko 1 problem , bo Ty mówisz o AVR-ach , a postodawca używa 89c4051 , który nie posiada "w sobie" eepromu :(

    :arrow: Scal12 - masz kolejne zadanie do zaliczenia , czyli magistrala I2C i komunikacja z zewnętrzną pamięcią eeprom np. 24c02 :D

    Piotrek
  • Poziom 21  
    HELOŁ :)

    No tak zapędziłem się trochę i zapomniałem że kolega pisze w BASCOM '51, ale wspominał coś wcześniej też o ATmega8515 że ewentualnie może realizować projekt na tym kontrolerze. No chyba że pomyliłem coś...

    Pozdrawiam! :)
  • Poziom 19  
    Procedure zapisu i odczytu z zewnetrznej pamieci znam tylko mam kłopot z zastosowaniem jej do konkretnego zadania z przykładami nie ma problemu a dzieki podpowiedziom z Waszej strony nawet nieżle mi idzie nauka:)Atmege8535 juz mam tylko nigdy jeszcze jej nie programowałem dopiero sie przymierzam.
  • Poziom 19  
    Panowie mam pytanie dodałem do programu procedurke zapisu max i min temperatury:
    If Tmin > T1 Then
    Tmin = T1
    End If

    If Tmax < T1 Then
    Tmax = T1
    End If
    program sie kompiluje bez problemu ale po uruchomieniu urzadzenia na wyswietlaczu nic sie nie pojawia tak jak by termometr był martwy.
    Doszedłem do wniosku ze to sprawka deklaracji
    dim tmax as integer
    dim tmin as integer
    Gdy zadeklaruje je jako byte wtedy mi wyskakuja błedy a gdy usune całkowicie procedure zapisu max i min temperatury wraz z deklaracjami wszystko gra co jest przyczyna lub ewentualnie w jaki inny sposów zapisac min i max
  • Poziom 16  
    typ float chyba powinien być..
    Te czujniki zapisują dane z przecinkiem ze wzgledu na ich dokladnosć do 0,1 albo 0,5 st c.
  • Poziom 19  
    Nie bardzo rozumiem czy mógłbys rozwinać podpowiedz,wystarczy ze w programie zadeklaruje jakąś zmienna jako integer i juz nic na lcd nie widać.
  • Poziom 16  
    dobra.. mała pomyłka wcale nie musi być zaden float.
    Czujnik wysyła dane trochę inaczej.
    Polecam ten topic on dosyć duzo wnosi do tematu mimo że zawarta tam wiedza dotyczy obsługi tego czujnika w c.
    [AVR GCC] DS18B20 i temperatury ujemne.
  • Poziom 21  
    Siemka!

    Hm, troszeczkę mało podałeś informacji o tym jak realizujesz problem. Pomiar min i max temperatury wraz z zapisem rozwiązałbym tak:
    1. deklarujesz sobie 3 zmienne
    - T to zmienna z aktualnym odczytem temperatury
    - Tmin to zmienna z minimalnym odczytem temperatury
    - Tmax to zmienna z maksymalnym odczytem temperatury
    oczywiście wszystkie muszą być tego samego typu, jak wcześniej w postach była prezentowana procedurka odczytu najlepiej gdyby to była zmienna integer, chyba że się uprzesz na zmiennoprzecinkowe to będzie potrzeba zadeklarować single, ale to jest strasznie pamięciożerne i nie to jest celem naszej debaty. :)

    2. gdy masz nasze zmienne w programie przy każdej inicjacji rejestrowania temperatury minimalnej i maksymalnej, np co godzinę, raz na dobę czy raz na tydzień lub jednorazowo przy starcie programu, zależy jak sobie przyjmiesz, inicjalizujesz sobie zmienne Tmin i Tmax wpisując do nich aktualną temperaturkę od której rozpoczynasz pomiar.
    Dlaczego tak? Zapytasz. Dlatego że np gdy zainicjujesz obie jako 0°C to w sytuacji gdy będziesz miał temperaturę aktualną powiedzmy 20°C i temperatura mierzona nie spadnie poniżej 0° to będziesz miał cały czas wskazanie Tmin = 0° bo defakto porównywana temperatura nie spełni warunku i nie zostanie wpisana do zmiennej jako najniższa temperatura w zadanym okresie czasu. I to samo jeżeli chodzi o temperatury Tmax jeżeli byśmy mieli do czynienia z temperaturami poniżej 0°C. Natomiast inicjując zmienne Tmax i Tmin wartością temperatury od której rozpoczynasz pomiar tego typu sytuacja się nie powinna pojawić.

    3. W pętli głównej programu odpalasz sobie procedurkę Tminmax która przeliczy dane i odpowiednio zaktualizuje zmienne. Działa to tak że aktualana zmierzona temperatura jest porównywana do Tmax i jeżeli jest od niej większa to Tmax jest aktualizowana do tej wartości. Tak samo z Tmin, gdy zmierzona T jest mniejsza od Tmin to do Tmin przepisywana jest wartość T.

    PRZYKŁAD:
    Code:


    dim T as integer
    dim Tmin as integer
    dim Tmax as integer

    declare sub Tminmax

    Tmin=T
    Tmax=T
    do
    ...
    ...
    ...
    loop
    end

    sub Tminmax
    if T<Tmin then Tmin=T
    if T>Tmax then Tmax=T
    end sub

    Jeżeli chodzi o braki wskazań wartości w Twoim programie to sprawdź czy dobrze masz napisaną procedurę odczytu czujników, czy dobrze sformatowałeś dane przed wyświetleniem itd.
    Na ten temat chyba już wystarczy pisania. Jakby pojawiły się kolejne problemy PYTAĆ!! :)

    Pozdrawiam Electix!!
  • Poziom 19  
    I tak własnie robie bez funkcji zapisu max i min temperatury wszystko ładnie smiga z 4 czujników na jednej lini, wszystko partaczy deklaracja np dim tmax as integer gdy próbuje zadeklarowac t jako integer a nie byte to wywala mi błąd,chyba zrezygnuje z tej funkcji
  • Poziom 21  
    A mam jeszcze taki jeden pomysł. Bo błędy będzie Ci wywalać przy próbie operacji na zmiennych różnych typów. Wszystkie zmienne w BASCOM które poddajesz operacjom muszą mieć zgodne typy. Więc prześledź jeszcze raz program lub podaj go tu na stronce może my conieco wypatrzymy :)