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

DS18B20---- rozdzielczosc ??

grabek_radek 03 Wrz 2006 13:34 2560 11
  • #1 03 Wrz 2006 13:34
    grabek_radek
    Poziom 21  

    Wita!
    Mam problem z termometrem dziwnie wskazuje w pokoju mam 29 stop. ?? i mu nie wierze bo jest max 24 patrzylem na zwyklym termometrze, czytam czytam i kazdy cos wspomina o rozdzielczosci dla serii b
    moj programik

    Code:

    ...
    config 1wire=portb.0
    declare sub odczyt_temp
    dim temperatura(2) as byte

    do
        call odczyt_temp
         cls
         lcd "temp:" ; temperatura(1)
    Loop

    sub odczyt_temp
         1wreset
          1wwrite  &hcc
          1wwrite  &h44
          waitms 100
          1wreset
          1wwrite  &hcc
          1wwrire  &hbe

           temperatura(1)=1wread(2)
           1wreset
           
           temperatura(1)=temperatura(1)/2
    end sub



    oczywiscie to jest glowny program bo jeszcze dodalem pomiar ujemniej ale tez cos nie gra i wiec chcialem sie dowiedziec odnosnie tego glownego programu co napisalem wyzej

    a i jeszcze jedno dlaem rezystor 3,3 k miedzy vcc DQ i oczywiscie vcc do zasilanie +5 v i mase(1) do masy

    0 11
  • #2 03 Wrz 2006 14:55
    cackoarek
    Poziom 25  

    Po pierwsze Twój kod do obliczania temperatury jest zły. Polecam użyć "SZUKAJ" i znajeźć poprawny. Temat był wałkowany tyle razy że znajdziesz na 100%

    0
  • #4 03 Wrz 2006 18:01
    Electix
    Poziom 20  

    Siemka!
    Tak jak napisali koledzy wyżej masz skopcony algorytm obliczania temperatury, który zależy też od wspomnianej przez Ciebie w temacie rozdzielczości. Załóżmy że będziesz używał 12bitowej, bo taką układ ustawia po resecie jeżeli nie jest wpisane inne ustawienie do wewnętrznego eepromu. Wynik przetwarzania jest zapisany w słowie (16 bitów) które możesz wczytać tak jak to robiłeś w swoim programie do zmiennej tablicowej. Słowo to jest przesyłane z termostatu do procesora w odwrotnej kolejności. Czyli, do pierwszego bajtu Twojej zmiennej tablicowej będzie wpisana młodsza część wyniku przetwarzania, a do bajtu drugiego Twojej zmiennej zostanie wprowadzona starsza część wyniku. Zatem trzeba zamienić je kolejnością przed dalszą obróbką. Najlepiej jest zadeklarować kolejną zmienna typu integer ponieważ ona pomieści całe słowo z wartością temperatury i zmienna ta uwzględni też znak wartości (temperatura może być ujemna). Czyli do zmiennej integer wpisujesz najpierw bajt z drugiej zmiennej tablicowej, gdy już tam jest musisz przesunąć go na starszą pozycję zmiennej bo zostanie on wpisany na młodszej pozycji. Tą operację możesz wykonać za pomocą komendy "shift". Przesuwasz w lewo o 8 bitów. I teraz do tej starszej części pomiaru w zmiennej integer dodajesz bajt przechowywany w pierwszej zmiennej tablicowej. I już masz poukładane słowo z przetwarzania. Jako że pomiar ma dokładność 0,0625°C przy rozdzielczości 12 bitów a zmienna integer nie przechowuje liczb zmiennoprzecinkowych wynik w tej zmiennej jest przesunięty o 4 rzędy (dwójkowo) w górę. Zatem aby otrzymać wynik rzeczywisty temperatury należy wartość ze zmiennej integer podzielić przez 16 i wynik zapisać w zmiennej "single" ponieważ ta przechowuje informacje o liczbach zmiennoprzecinkowych a takową jest zmierzona temperatura. I na tym kończy się algorytm obliczania temperatury mierzonej przez DS18B20.
    wspomnę jeszcze o jednej rzeczy, wstawiłeś opóźnienie 100ms pomiędzy przetwarzaniem a odczytem wyniku. Obawiam się że może to być za mało, tymbardziej że producent podaje max czas przetwarzania 750ms. Co prawda dotyczy się to zasilania czujnika z szyny 1-Wire, ale jednak. Pozatym 1 pomiar/s to i tak wystarczająco często, więc najlepiej jest zrobić sobie przerwanie co 1s które uruchomi cały pomiar, który możesz zrobić np tak:

    Code:

    declare sub odczyt_t

    dim Rd(2) as byte ' zmienna tablicowa do odczytu wyniku przetwarzania
    dim Rdp as integer ' zmienna integer do ułożenia odczytanych danych
    dim T as single ' obliczona temperatura

    do
    call odczyt
    loop
    end

    sub odczyt_t
    1wreset
    1wwrite &HCC
    1wwrite &H44
    waitms 750
    1wreset
    1wwrite &HCC
    1wwrite &HBE
    Rd(1) = 1wread(2)
    Rdp = Rd(2)
    Shift Rdp , Left , 8
    Rdp = Rdp + Rd(1)
    T = Rdp / 16
    end sub

    Na koniec wspomnę też jak koledzy wyżej, temat wiele razy był przerabiany i używając opcji "szukaj" znalazłbyś dużo na ten temat.
    Życzę przyjemnej zabawy i POZDRAWIAM!!

    0
  • #5 03 Wrz 2006 18:13
    Granat :)
    Poziom 34  

    hmmm a ja muszę jeszcze coś dodać :)
    dane odczytujemy ze scratchpad'u (RAM)
    "słowo jest przesyłane w odwrotnej kolejności"... w funkcję makeint() też wpisujemy z odwrotnej kolejności (najpierw LSB) więc idealnie sięona do tego nadaje
    zmienna stypu single zabiera aż 4 cenne bajty ramu i potem trzeba jeszcze dodawać fusin co znacznie zwiększa ilość generowanego przez kompilator kodu, a można to zrobić prościej. wstarczy użyć dodatkowej zmiennej bajtowej i użyć operacji "mod" :)
    przyposywanie do siebie zmiennych różnego typu w bascomie avr nie działa prawidłowo więc mogą być problemy, zalecam uzyć jednak makeint :)

    więcej informacji jest w linku, którego Ci wysłałem

    0
  • #6 03 Wrz 2006 18:41
    Electix
    Poziom 20  

    Kolego Granat:)
    Dla Twojej informacji zacytuję Ci fragmenty noty aplikacyjnej układu DS18B20
    "MEMORY
    The DS18B20’s memory is organized as shown in Figure 7. The memory consists of an SRAM
    scratchpad with nonvolatile EEPROM storage for the high and low alarm trigger registers (TH and TL)
    and configuration register. Note that if the DS18B20 alarm function is not used, the TH and TL registers
    can serve as general-purpose memory. All memory commands are described in detail in the DS18B20
    FUNCTION COMMANDS section."

    Data in the EEPROM registers is retained when the device is powered down; at power-up the EEPROM
    data is reloaded into the corresponding scratchpad locations. Data can also be reloaded from EEPROM to
    the scratchpad at any time using the Recall E2 [B8h] command. The master can issue read time slots
    following the Recall E2 command and the DS18B20 will indicate the status of the recall by transmitting 0
    while the recall is in progress and 1 when the recall is done."
    A tu jest schemat organizacji scratchpad
    DS18B20---- rozdzielczosc ??

    Jak podaje naota aplikacyjna DS18B20 zawiera pamięć EEPROM, więc albo nas chciałeś nakłamać ;) albo nie dokońca poznałeś ten ciekawy układ... :)

    Zatem odsyłam do lektury noty aplikacyjnej DS18B20 :)
    http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2812

    Pozdrawiam!!

    0
  • #7 03 Wrz 2006 19:33
    zumek
    Poziom 39  

    Kolego Electix :D
    Ja (dla odmiany) przyczepie się do Twojego kodu:
    Temperaturę obliczasz jak poniżej ...

    Code:

    Rd(1) = 1wread(2)
    Rdp = Rd(2)
    Shift Rdp , Left , 8
    Rdp = Rdp + Rd(1)
    T = Rdp / 16

    ... i niepotrzebnie wyręczasz kompilator.A na samą myśl o SINGLE, dostaję drgawek ;)
    Podaję 2 najprostsze sposoby , na obliczenie całkowitej temperatury dla DS18B20.
    a)
    Code:

    Dim T As Integer
       T = 1wread(2)
       T = T / 16

    b)Jeśli potrzebujemy wczytać kompletny scratchpad.
    Code:

    Dim Bt(9) As Byte , T As Integer At Bt Overlay
       Bt = 1wread(9)
       T = T / 16

    Prościej już sie nie da :D

    Piotrek

    0
  • #8 03 Wrz 2006 19:41
    grabek_radek
    Poziom 21  

    Electix nie rozumien tego

    Code:
    Shift Rdp , Left , 8
    czy to jest przesuniecie o 8 bitow w lewo ??

    0
  • #9 03 Wrz 2006 20:17
    Electix
    Poziom 20  

    Tak grabek_radek to jest przesunięcie o 8 bitów w lewo zawartości zmiennej Rdp. Czyli jak na początku miałeś tam wisaną wartość np:

    0000000010101011

    to po wykonaniu tego polecenia będziesz miał

    1010101100000000

    Szczegóły masz opisane w helpie do Bascom np. tu:
    http://www.mcselec.com/index.php?option=com_docman&task=cat_view&gid=86&Itemid=54

    To jest dla wersji Bascom Avr, nie wiem czy Ty używasz akurat tej czy Bascom '51. Generalnie te jezyki niewiele sie różnią.

    Do kolegi zumek

    Jezeli komuś wystarcza pomiar z dokładnością do 1°C to Twój sposób jest jak najbardziej stosownym i zdecydowanie szybszym. Ale wydaje mi sie ze wtedy mie na sensu stosować przetwarzania 12bitowego bo to spowalnia odpowiedź DS18B20. Ja podałem przykład dla uzyskania jak najwyższej dokładności wyniku pomiaru. :)

    Ale co dwie metody to nie jedna:)

    Pozdrawiam!!

    0
  • #11 03 Wrz 2006 20:31
    zumek
    Poziom 39  

    Electix napisał:

    ... Ja podałem przykład dla uzyskania jak najwyższej dokładności wyniku pomiaru. :)

    Coś pokręciłeś :D
    Rozdzielczość a nie dokładność , masz też 8 -bitową , bo czyż nie "odrzucasz" 4 najmłodszych bitów:?:
    Code:

    T = Rdp / 16

    Electix napisał:

    Ale co dwie metody to nie jedna:)
    ...

    Tu się zgadzam :D

    Piotrek
    PS
    Naprawdę wyższą rozdzielczość znajdziesz np. w tym poście

    0
  • #12 03 Wrz 2006 21:05
    Electix
    Poziom 20  

    Tak Granat:), dane odczytujemy z ramu kości. :) To fakt zumek. Rozdzielczość i dokładność to dwie różne rzeczy. Sam czujnik DS18B20 ma dokładność ±0,5°C, a przy próbkowaniu 12 bitów daje rozdzielczość 0,0625°C. W niektórych zastosowaniach warto jest z tego skorzystać, tymbardziej że układ daje taką możliwość bo przy dalszej obróbce wyniku też dokładamy błąd, chociażby ucinając końcówkę po przecinku, a te błedy dodają się do błędów samego czujnika.
    Zmienna integer zachowuje tylko wartości całkowite i tak jak mówisz po podzieleniu przez 16 i zapisaniu wyniku dalej w zmiennej integer będziesz będziesz miał tylko całkowitą wartość temperatury a to co po przecinku zostanie ucięte. Można tak jak sugerował wyżej kolega Granat :)pokąbinować z resztą z dzielenia MOD. Natomiast gdy wynik operacji zapiszesz w zmiennej single (która Ci o drgawki przyprawia :) ) otrzymasz wynik zmiennoprzecinkowy, a miejsca po przecinku nie zostaną stracone. Jeżeli chodzi o to co wcześniej pisałem można jak się okazuje pominąć te kombinacje z tablicami i przesuwaniem bo

    Code:

    dim Rdp as integer
    dim Tzw as single

    1wreset
    1wwrite &HCC
    1wwrite &HBE
    Rdp = 1wread(2)
    Tzw = Rdp / 16

    też działa:) Heh ile to się można dowiedzieć :) Ja programuję dopiero od miesiąca i sugerowałem się książkami M. Wiązani czy P. Góreckiego z których niedowiedziałem się że bezpośredni zapis do zmiennej integer w tym wypadku będzie poprawny i nie trzeba nic więcej kombinowacć:)

    Za co serdeczne DZIĘX!! Wszystkim :)

    0
  Szukaj w 5mln produktów