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.

Arduino C - Konwersja temperatury DS18B20 na ludzką postać

lukas_gab 26 Mar 2015 21:07 1137 8
  • #1 26 Mar 2015 21:07
    lukas_gab
    Poziom 15  

    Witam ! Dokonuje odczytu temperatury z ds18b20. Otrzymuje dwa bajty danych. Te bajty to nie są takie normalne bajty, bo jak wiecie pierwsze 4 bity młodszego bajtu, to część ułamkowa, 5 najstarszych bitów starszego bajtu to znak, a cała reszta, to temperatura, gdzie najmłodszy jej bit ma wagę 2^0. Teraz mam problem jak dokonać konwersji. Bo jak użyję konwersji na np. system dziesiętny, to w młodszym bajcie potraktuje kompilator najmłodszy bit jako 2^0 a tak nie jest bo tam jest waga 2^-4. Mogę teoretycznie czytać każdy z młodszych bitów i ręcznie liczyc wartość ułamkową, potem wartość całkowitą i sprawdzić znak. Powiedzcie mi, czy to jest dobre podejście (pewnie bym to zrobił w pętli licząc kolejne potęgi)czy istnieje jakiś sprytniejszy sposób, żeby odciąć te 4 młodsze bity i policzyć część ułamkową i potem całkowitą, bez takiego brute force. Dzięki jeszcze raz z góry za pomoc !

    0 8
  • Pomocny post
    #2 26 Mar 2015 21:23
    M. S.
    Poziom 34  

    Otrzymane 2 bajty łączę w liczbę 16 bitową. Mnożę ją przez 10 i dzielę przez 16 (tj. przesuwam o 4 bity w prawo). Mam w wyniku temperaturę 10x większą niż w rzeczywistości. Ewentualne obliczenia i ustawienia wewnątrz programu robię na liczbach 10x większych. Dla procesora to żadna różnica. Wyświetlaniem zaś zajmuje się za każdym razem ten sam podprogram, który wstawia przecinek przed liczbą jedności. W ten sposób prosto uzyskuję rozdzielczość na poziomie 0,1°C.

    I jak kolega niżej napisał pamiętaj o znaku.

    1
  • Pomocny post
    #3 26 Mar 2015 21:30
    michcior
    Poziom 30  

    Kod: c
    Zaloguj się, aby zobaczyć kod


    "buf" to odczyt "scratchpad" termometru. Zmienna tTemp zawiera temperaturę w 0.1st, to znaczy np. 13.5 to będzie 135.
    Potem, jak chcesz to dziel przez 10 i na float albo dzielenie przez 10 z resztą i bez reszty, tylko trzeba znaku pilnować:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    [/code]

    1
  • #5 26 Mar 2015 22:46
    lukas_gab
    Poziom 15  

    Usiadłem z kartką i wymyśliłem część całkowitą

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Tylko nie wiem jak sobie poradzić z obliczeniem części dziesiętnej (może zaraz wymyślę).

    Widzę, że wasze rozwiązanie jest prostsze, ale które - moje czy wasze jest "lżejsze" dla procesora ?

    Dodatkowo, o ile rozumiem przesuwanie bitowe o 4, to nie za bardzo wiem, po co tam się mnoży razy 10 i jak niby osiąga się wartość dzisietną, bo skoro mnożycie * 10 ( przesuwam o bit) i dziele przez 16 ( przesuwam 4 bity), to pierwszy bit części dziesiętnej ma wage 2^0... Zabardzo nie rozumiem - możecie rozbić to na kroki - wyłącznie w celu dydaktycznym, bo czegoś nie łapie.

    Dzięki z góry za pomoc.

    Dodano po 34 [minuty]:

    Dzieki bardzo. Zaczynam pomału rozumieć. Ocencie proszę tylko jeszcze mój kod, jeżeli macie chwilkę czasu.

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Z góry dzięki

    0
  • Pomocny post
    #6 26 Mar 2015 23:19
    BlueDraco
    Specjalista - Mikrokontrolery

    No niezupełnie, dla ujemnych temperatur to nie zadziała, a dla dodatnich dość pokręcone.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    1
  • #7 27 Mar 2015 06:51
    lukas_gab
    Poziom 15  

    Ok, masz racje, znaku nie uwzględniłem w tej wersji ( w kolejnej już tak). A ten mój pokręcony sposób, po analizie widzę, że jest taki sam jak wasz, z tym, że ja odpowiednio przesuwam i wybieram określone półbajty a potem robię sumę logiczną, a wy to robicie w jednej linijce nie martwiąc się, żeby, powstały czyste półbajty i widzę, że to słuszne, bo liczy sie efekt, a nie czynniki pośrednie. Teraz NIEMAL, wszystko rozumiem, tylko powiedzcie mi jak można zrobić operacje ulamek = (temp & 0xf) * 5 / 8; bez użycia liczb dziesiętnych tylko same przesunięcia bitowe ? Kombinowałem, ale mi nie wyszło... Swoją drogą, jak ja robię takie operacje, to procesor dokonuje niejawnej konwersji podczas wykonywania programu co wiąże sie z nakładem taktów, czy może kompilator tłumaczy już liczby podczas kompilacji do zjadliwej przez procesor formy ?

    0
  • Pomocny post
    #8 27 Mar 2015 09:00
    zumek
    Poziom 39  

    lukas_gab napisał:
    ... tylko powiedzcie mi jak można zrobić operacje
    Kod: c
    Zaloguj się, aby zobaczyć kod
    bez użycia liczb dziesiętnych tylko same przesunięcia bitowe ?


    Np.
    Kod: c
    Zaloguj się, aby zobaczyć kod

    1
  • #9 27 Mar 2015 09:17
    lukas_gab
    Poziom 15  

    Ok, super dzieki. Źle przesuwałem .. ech ;) Kłania sie system binarny. Dzieki za pomoc !

    0
  Szukaj w 5mln produktów