Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Fibaro Fibaro
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

MikroC - PIC16F628A - formowanie wyniku z DS18B20 do wysłania po UART

mariomario 30 Cze 2016 07:58 3345 15
  • #1 30 Cze 2016 07:58
    mariomario
    Poziom 18  

    Witam,

    czy ktoś mógłby mnie nakierować co muszę zmienić w poniższym kodzie aby otrzymać po UART poprawny wynik temperatury odczytanej z DS18B20 ?

    Kod (MikroC, PIC16F628A)

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wyświetlany wynik po UART:
    MikroC - PIC16F628A - formowanie wyniku z DS18B20 do wysłania po UART

    gdzie w pomieszczeniu mam ok 25C (wg wskazań innego termometru).

    Kombinowałem też z poniższym kodem i też wysyła niepoprawne wyniki:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    poniżej wyświetlane wyniki (niepoprawne):
    MikroC - PIC16F628A - formowanie wyniku z DS18B20 do wysłania po UART

    0 15
  • Fibaro
  • Pomocny post
    #2 30 Cze 2016 17:01
    JacekCz
    Poziom 33  

    ze szczegółów to użycie zmiennej text masz nieprawidłowe, piszesz po stałych.
    Wskaźnik na jakiś string (sekwencję literek) a bufor na literki, choć w kodzie C pisze się to formalnie prawie tak samo, są głębokie różnice.

    To jest sławny w C Undefined Behaviour.

    Po drugie wite(13) lepiej wygląda write('\r')
    a coś+48 to nie lepiej temu będzie coś+'0' jeśli zgaduję dobrze zamiar kodu?

    EDIT: a takie coś

    Kod: c
    Zaloguj się, aby zobaczyć kod
    to proszenie się o strzał w stopę (dokładniej to w dwie z dwóch powodów). Sam wiem, że również w notach kontrolerów są straszne przykładu kodu, powinni za nie kołem łamać

    Zależnie od wersji standardu C bezpiecznie jest coś takiego
    Kod: c
    Zaloguj się, aby zobaczyć kod


    ew mniej straszne #define
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Nie pomogłem ci z tematem ściśle uP ale to moje oczy wychwytują

    0
  • Fibaro
  • Pomocny post
    #3 30 Cze 2016 17:03
    pierzogad
    Poziom 2  

    Z opisu DS18B20 rozumiem, że on zawsze zwraca część ułamkową w najmłodszych 4 bitach LSB - niezależnie od rozdzielczości.

    Tak więc wystarczy zmienić w Display_Temperature() pierwszą linię na

    unsigned short RES_SHIFT = 4;

    Wynik będzie o 3 bity (8 razy) mniejszy - więc zamiast 207.5 uzyskasz 25.9

    0
  • #4 30 Cze 2016 18:38
    BlueDraco
    Specjalista - Mikrokontrolery

    A temat wraz z odpowiedziami powaraca na forum co miesiąc - wystarczy poszukać.

    0
  • #5 30 Cze 2016 22:07
    mariomario
    Poziom 18  

    JacekCz napisał:
    ze szczegółów to użycie zmiennej text masz nieprawidłowe, piszesz po stałych.
    Wskaźnik na jakiś string (sekwencję literek) a bufor na literki, choć w kodzie C pisze się to formalnie prawie tak samo, są głębokie różnice.


    Zamiast:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Zrobiłem tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Niestety kompilator wywalił błąd, że wskaźnik niezadeklarowany (coś w ten deseń)

    pierzogad napisał:
    Z opisu DS18B20 rozumiem, że on zawsze zwraca część ułamkową w najmłodszych 4 bitach LSB - niezależnie od rozdzielczości.

    Tak więc wystarczy zmienić w Display_Temperature() pierwszą linię na

    unsigned short RES_SHIFT = 4;

    Wynik będzie o 3 bity (8 razy) mniejszy - więc zamiast 207.5 uzyskasz 25.9


    Dzięki Twojej poradzie udało się wyświetlić poprawny wynik :)

    Kod prezentuje się teraz następująco [MikroC, PIC16F628A]:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    a wysyłane po UART wyniki tak:
    MikroC - PIC16F628A - formowanie wyniku z DS18B20 do wysłania po UART
    widać temperaturę 27C, która pokrywa się z temperaturą w pomieszczeniu, dalej złapałem palcami za czujnik :D

    PS. Pierwszy wysłany wynik to 85 - ale zauważyłem go kiedyś zarówno na Arduino jak i na ESP8266 przy odczytywaniu temperatury z DS18B20 - więc ten błąd przyjmuję za "normalkę".

    0
  • Pomocny post
    #7 01 Lip 2016 07:54
    JacekCz
    Poziom 33  

    mariomario napisał:
    JacekCz napisał:
    ze szczegółów to użycie zmiennej text masz nieprawidłowe, piszesz po stałych.
    Wskaźnik na jakiś string (sekwencję literek) a bufor na literki, choć w kodzie C pisze się to formalnie prawie tak samo, są głębokie różnice.


    Zamiast:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Zrobiłem tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Niestety kompilator wywalił błąd, że wskaźnik niezadeklarowany (coś w ten deseń)


    Zdziwiony jestem, że rozmawiamy na tematy z pierwszych kartek podręcznika C (oraz zupełnie na chłopski rozum projektowania).

    Kod: c
    Zaloguj się, aby zobaczyć kod
    lub
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Już by kompilator nie krzyczał.

    Deklaruje to bufor (o długości inicjatora+1) za pierwszym razem zainicjowany wartością, ale dostępny do zapisu.

    Ale, myśląc "projektowo", czy kiedykolwiek chcemy użyć tych zer? Nigdy. Więc prawidłowy zapis by był - przy okazji mamy oszczędności - jak poniżej.
    Kod: c
    Zaloguj się, aby zobaczyć kod


    EDIT: zapis z char * = "stała" jakbym był twórcą kompilatora na uP bym przemieszczał do ROM/flasha. Ciągły problem gdzie ubywa RAM itd by się skończył

    Drobny "szczegół" miliony linii kodu nie trzymającego standardu by przestały działać, więc w realnym świecie pewnie taka decyzja producentów kompilatorów nie powstanie.

    0
  • Fibaro
  • #8 01 Lip 2016 12:12
    BlueDraco
    Specjalista - Mikrokontrolery

    JacekCz napisał:

    EDIT: zapis z char * = "stała" jakbym był twórcą kompilatora na uP bym przemieszczał do ROM/flasha. Ciągły problem gdzie ubywa RAM itd by się skończył

    Drobny "szczegół" miliony linii kodu nie trzymającego standardu by przestały działać, więc w realnym świecie pewnie taka decyzja producentów kompilatorów nie powstanie.


    I dokładnie tak robi to większość przyzwoitych kompilatorów dla przyzwoitych procesorów (np. ARM), natomiast nie da się tego zrobić bez dodatkowych zaklęć typu PROGMEM dla architektur z rozdzielonymi pamięciami danych i kodu (AVR, PIC), dlatego na AVR taki kod jak powyżej (z modyfikacją "stałego" łańcucha wskazywanego przrz wskaźnik) zadziała, chociaż zgodnie ze standardem C nie powinien.

    0
  • #9 01 Lip 2016 13:13
    JacekCz
    Poziom 33  

    BlueDraco napisał:

    I dokładnie tak robi to większość przyzwoitych kompilatorów dla przyzwoitych procesorów (np. ARM), natomiast nie da się tego zrobić bez dodatkowych zaklęć typu PROGMEM dla architektur z rozdzielonymi pamięciami danych i kodu (AVR, PIC), dlatego na AVR taki kod jak powyżej (z modyfikacją "stałego" łańcucha wskazywanego przrz wskaźnik) zadziała, chociaż zgodnie ze standardem C nie powinien.


    Tak. Żeby się wyżyć "naukowo" to rozdzielone przestrzenie zwykle krótko nazywa się Harvard, a wspólną przestrzeń adresową jako architektura von Neumanna

    W nieco innej dziedzinie blisko obserwuję jak trudno producentowi oprogramowania na liczny rynek (tzn nie dedykowany 1-2 egzemplarze) wyjść z "drobnych błędów" polegających na akceptowaniu sytuacji której akceptować nie powinien. Jeśli nowa wersja zareaguje "prawidłowo" zgodnie ze standardami, kanonami itd i bardziej rygorystycznie, to może wysadzić w powietrze wiele kodu o którym producent przecież nawet nie ma pojęcia.

    0
  • #10 01 Lip 2016 13:15
    grko
    Poziom 32  

    Cytat:

    ...chociaż zgodnie ze standardem C nie powinien

    Zgodnie ze standardem to jest UB. Więc może działać albo nie działać. Przyzwoite kompilatory pozwalają umieścić .rodata gdzie się użytkownikowi podoba ;)

    Szkoda, że w C literały nie są typu const char *. Wtedy autor uniknąłby tego błędu.

    0
  • #11 01 Lip 2016 17:27
    BlueDraco
    Specjalista - Mikrokontrolery

    Naukowo to współczesne maszyny "Harvard" spełniają z grubsza postulaty von Neumanna i wcale nie przypominają tego, co skonstruowano na Harvardzie. Za to współczesne "vonNeumannowskie" wykazują dość istotne różnice koncepcyjne w stosunku do komputera von Neumanna, który jawnie rozróżniał dane od kodu. ;)

    Stąd moim skromnym zdaniem różnicowanie "Harvard - von Neumann" w odniesieniu do współczesnych komputerów małych ani dużych nie ma sensu.

    literały są typu const char *, tylko przypadku, o ktrym mowa, kompilator nie ma jak wygzekwować, bo modyfikujemy nominalnie stałą umieszczoną w pamięci RAM wskazywaną przez wskaźnik na zmienną.

    0
  • #12 01 Lip 2016 18:09
    grko
    Poziom 32  

    Cytat:

    literały są typu const char *, tylko przypadku, o ktrym mowa, kompilator nie ma jak wygzekwować, bo modyfikujemy nominalnie stałą umieszczoną w pamięci RAM wskazywaną przez wskaźnik na zmienną.


    To, że coś jest w pamięci FLASH nie znaczy, że jest typu const. W języku C literały nie są typu const char * w żadnym wypadku. Dlatego to:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    nie generuje warninga niezależnie od tego czy literał jest w RAM, FLASH czy gdziekolwiek.

    0
  • #13 01 Lip 2016 21:30
    mariomario
    Poziom 18  

    Dziękuję Wam za pomoc :) . Poniżej wstawiam już działający kod, wiem że nie jest on idealny, ale zajmuje bardzo mało pamięci RAM i Flash (50 bajtów RAM, 627 bajtów Flash, czyli mniej jak 1/3 pamięci i tak bardzo starego i słabego PIC16F628A ;) ).

    Kod:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    A wysyłane wyniki po UART:
    Kod: html
    Zaloguj się, aby zobaczyć kod

    0
  • #14 01 Lip 2016 22:35
    BlueDraco
    Specjalista - Mikrokontrolery

    int x = 5;

    też nie generuje ostrzeżenia, z tego samego powodu. :)
    A "5" jest stałą.

    Ciekawe, jak zadziała coś takiego:

    "abc"[1] = 'x';

    0
  • Pomocny post
    #15 02 Lip 2016 09:46
    p.kaczmarek2
    Poziom 23  

    JacekCz napisał:


    Kod: c
    Zaloguj się, aby zobaczyć kod
    lub
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Już by kompilator nie krzyczał.


    Te zapisy nie są równowazne. Skąd ci się ten drugi wziął? Sprawdziłem na ideone i się nie kompiluje. To nie C#...

    https://ideone.com/yqng7Y
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #16 02 Lip 2016 11:08
    JacekCz
    Poziom 33  

    p.kaczmarek2 napisał:
    JacekCz napisał:


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

    Już by kompilator nie krzyczał.


    Te zapisy nie są równowazne. Skąd ci się ten drugi wziął? Sprawdziłem na ideone i się nie kompiluje. To nie C#...

    https://ideone.com/yqng7Y


    W sumie racja. Mam przekonanie, to było legalne w jakiś wersjach na poziomie Kerrigan&Ritchie.
    Używam (w C/C++) wyłącznie pierwszej.

    0
TME logo Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
TME Logo