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

[Xmega128A4U] [Xmega128A4U][BMP180][C] - błędne odczyty kalibracji w BMP180_init()

prm_ex 23 Mar 2015 13:05 1224 4
REKLAMA
  • #1 14554415
    prm_ex
    Poziom 9  
    Witam
    Mam problem z odczytem z BMP180, już na samym początku przy próbie odczytu kalibracji w funkcji BMP_init().

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Moje TWI inicjuję tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    A funkcja odczytu jest taka:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Nie chcę używać kombajnów w postaci gotowych bibliotek dla TWI i BMP.
    Siedzę nad tym trzeci dzień i byłbym wdzięczny za wszelkie sugestie co mogę mieć skopane lub czego jeszcze spróbować. To jest moje pierwsze podejście do TWI więc całkiem możliwe że tutejsi fachowcy od Xmeg od razu zobaczą jakiegoś mojego babola.
    (Przez lornetkę widzę że modulik na którym siedzi BMP ma podciągnięte SCL i SDA do Vdd poprzez 2x10k gdyby ktoś chciał spytać).
    pozdrawiam
    Przemo
  • REKLAMA
  • #2 14554836
    tmf
    VIP Zasłużony dla elektroda
    Generalnie jeśli odblokowuje się jakieś przerwanie to wypadałoby napisać jego handler. Ty odblokowujesz przerwanie odczytu i zapisu, a jednocześnie kod ich nie obsługuje i z jakiegoś powodu jest napisany tak, żeby z przerwań nie korzystać... Poza tym w TWI trzeba obsługiwać różne stany magistrali, które masz opisane w nocie procka. Mieszasz też rejestr Data z Addr.
  • REKLAMA
  • #3 14563443
    prm_ex
    Poziom 9  
    Witam
    Tak czułem, że Tomasz zaraz mnie zdzióbie - i słusznie.
    Dzięki za kopnięcie w d i ustawienie we właściwą stronę.
    Spędziłem kolejne dwa wieczorki z datasheet'ami i AS6 i zacząłem rozmawiać ze slave'em. Ale chyba nie do końca się ze slave'em rozumiemy. Albo oba moduły GY-68 są walnięte (0%) albo wciąż mam babola w kodzie (100%).

    Zanim zajmę się weryfikacją poprawności obliczeń i w nich konwersji typów (bo otrzymuję setki stopni i ciśnienie raczej z kompresora :D, dodatkowo mocno pływają z każdym naciśnięciem przycisku (nowy pomiar)), ale chciałbym uprzejmie prosić o weryfikację stanu aktualnego jeśli chodzi o komunikację. Za dalsze zdzióbanie i sugestie z góry uprzejmie dziękuję ;)

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Tak czytam spod adresu readAddr ze slave'a o adresie BMP180_ADDR:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Czytane dane kalibracyjne wyglądają na poprawne i powtarzalne. Więc zakładam, że o ile nie wygląda to pięknie, to działa.

    Pomiar temperatury surowej (ut):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    I pomiar ciśnienia surowego (up):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Jak już wspomniałem wyniki są nierealne ale najgorsze że naciskając przycisk kolejnego pomiaru wyniki dryfują w którąś stronę do jeszcze bardziej kosmicznych.
    Podejrzewam, że albo gdzieś mam babola albo jednak nie panuję nad komunikacją w pełni i zgarniam kolejnym razem jakieś pozostałości z bus'a.

    pozdrawiam
    Przemo
  • REKLAMA
  • #4 14565108
    tmf
    VIP Zasłużony dla elektroda
    Konstrukcja (long)(msbt << 8) może być błędna, jeśli np. msbt jest 8-bitowe, to najpierw przesuwasz o 8 bitów (otrzymasz 0) po czym konwertujesz do long -czyli zawsze masz zero. Nie zagłębiałem się w sam czujnik ale twoja funkcja twi_read_data chyba za każdym razem wysyła repeated start? Czujnik to może dziwnie interpretować i nie wysyłać kolejnych bajtów tak, jak tego oczekujesz. Ale tu się mopże mylę, bo nie oglądałem DS tego czujnika. Najprościej prześlij sobie po RS surowe dane z czujnika i napiechotkę policz czy mają one sens. Bedziesz widział, czy błąd jest w kodzie, czy w komunikacji.
  • #5 14565603
    prm_ex
    Poziom 9  
    No właśnie na terminal chcę puszczać cały zestaw zmiennych i monitorować porównując policzone na papierze. Jednak najpierw muszę odjść do ładu z kompem bo nawet połączone na echo UART<>USB cokolwiek wyślę dostaję null ;) Jak wspomniałem wcześniej obliczeniom i konwersjom typów na bank muszę się przyjrzeć. Tyle, że bzdurne wyniki jakie by one nie były powinny się utrzymywać a nie dryfować po kilku wymuszonych pomiarach.
    Stąd wnioskuję że jednak komunikacja jest do dopieszczenia.
    Cytat:

    Nie zagłębiałem się w sam czujnik ale twoja funkcja twi_read_data chyba za każdym razem wysyła repeated start?

    Każda stała kalibracyjna jest pobierana póki co osobno poprzez tą funkcję. Wydaje mi się że starty są dwa
    TWIE.MASTER.ADDR = BMP180_ADDR;
    i
    TWIE.MASTER.ADDR = BMP180_ADDR | 0x01;
    Tyle, że pierwsza część nie jest zakończona TWIE.MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc; bo drugi start kończy pierwszy. No chyba że się mylę i trzeba dać stopa przed drugim startem.

    Procedura komunikacji z czujnikiem w sumie jest prosta.
    [Xmega128A4U] [Xmega128A4U][BMP180][C] - błędne odczyty kalibracji w BMP180_init()

    edit@ 01.04.2015 (ale nie Prima Aprilis :D ) aby nie pisać posta pod postem.

    Podgiglałem funcję read w zakresie sprawdzania statusów, flag i ACK'ów:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Pobierane dane kalibracyjne zaczęły przypominać bardziej przykładowe z noty katalogowej BMP'a. Kompletne debuggowanie wszystkich zmiennych ślę na terminal USARTem i porównuję z liczbami w obliczeniach dokonywanych w excelu.
    Pokrywają się, zatem wnioskuję że konwersje i obliczenia mam już poprawne.
    I wszystko byłoby ok gdyby nie to że wyniki są nierealne. Temp pokojowa jest ok 95*C a ciśnienie ok 900hPa.
    Ktoś powie może moduł GY-68 jest wadliwy, ale mam dwa, lekko różnią się stałymi kalibracyjnymi ale wyniki temp i ciśn. są bardzo podobne.
    Więc jednak gdzieś jeszcze jakiś szczegół raczej siedzi w kodzie.
    No chyba że dopuszczalne jest "kalibrowanie" dodatkowe przez zniwelowanie wyników (coś jak offset), ale wątpię skoro są indywidualnie kalibrowane.

    edit 2015-04-19
    Problem rozwiązany.
    Delay'a oczekującego na konwersję BMP'a miałem po ostatnim ACKu od slave'a po zapisie do rejestru po czym następował restart.
    Rozwiązaniem okazało się użycie stop zamiast restart, po nim wymagany delay i odczyt wyników z nowym startem.

    dziękuję za udział w temacie
    pozdrawiam
    Przemo
REKLAMA