Skocz do zawartości

Kurs STM32L4 – #13 – czujnik ciśnienia, pomiar wysokości (I2C)


Komentator

Pomocna odpowiedź

Kurs STM32L4 – #13 – czujnik ciśnienia, pomiar wysokości (I2C)

Czujniki ciśnienia mają wiele zastosowań, można je np. wykorzystać do pomiaru wysokości – taką funkcję pełnią m.in. w zegarkach sportowych. W tej części kursu STM32 zajmiemy się obsługą popularnego czujnika LPS25HB, który pozwala na pomiar ciśnienia, wysokości oraz temperatury.

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Link do komentarza
Share on other sites

Przypominamy: w komentarzach do kursów rozmawiamy wyłącznie na tematy związane z konkretnym kursem. Mile widziane są również informacje od osób, które korzystały wcześniej z naszych poradników. Wszystko po to, aby kursanci, którzy mają zamiar korzystać z tego kursu nie musieli "przedzierać" się przez dziesiątki postów na inne tematy. Pytania na tematy, które nie są związane z kursem można zadawać na naszym forum o mikrokontrolerach.

Link do komentarza
Share on other sites

Mam nadzieję, że wzory i obliczenia nikogo nie przestraszą - nie taki był nasz cel 😉 Chcieliśmy jednak pokazać coś więcej oprócz "suchego" odczytu danych z czujnika. Mam nadzieję, że taka forma będzie dla wielu osób znacznie ciekawsza - życzę udanych eksperymentów! Pamiętajcie jednak, że wyniki, które będziecie uzyskiwać mogą być zupełnie inne od tych, które były widoczne w artykule - wszystko zależy od Waszej lokalizacji oraz od aktualnych warunków pogodowych ☀️

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Jak zwykle - kolejny ciekawy fragment możliwości zestawu.

Mam pytanie co do koprocesora matematycznego. Otóż w kursie jest napisane:

Cytat

Mamy jednak wydajny mikrokontroler STM32L4 z koprocesorem arytmetycznym, ........ . Najpierw musimy dodać bibliotekę math.h do naszego projektu.

Jak to naprawdę się odbywa. Kiedy załącza się ów koprocesor?

Czy przy każdej operacji na liczbach zmiennoprzecinkowych czy dopiero po dodaniu deklaracji typu #include <math.h>? 

Link do komentarza
Share on other sites

Dnia 20.06.2021 o 15:22, Elvis napisał:

Napisanie tej części kursu było bardzo ciekawym, chociaż niekoniecznie łatwym doświadczeniem. Okazało się, że pozornie prosty temat jak mierzenie ciśnienia atmosferycznego kryje w sobie wiele niespodzianek, a wykorzystywanie czujnika do pomiaru wysokości wcale nie jest takie oczywiste.

W każdym razie większość wniosków opisaliśmy w tej części kursu, ja dodam od siebie tylko, że podczas testów płytka Nucleo-L476RG wraz z wyświetlaczem TFT z naszego kursu, powerbankiem oraz czujnikiem LPS25HB trafiła do prowizorycznej, kartonowej obudowy. Następnie taki "przyrząd pomiarowy" został zabrany w miejsce gdzie łatwo było ustalić w miarę dokładne koordynaty:

1_ok.jpg

Tak, to Pałac Kultury i Nauki w Warszawie 😉 Na ekranie ostatnia linijka wyświetla wynik, czyli w przybliżeniu: h = 76,58 (m n.p.m). Niestety to był ten moment, kiedy okazało się jak ważna jest dodatkowa kalibracja (więcej w kursie). Następnie czujnik został zabrany na taras widokowy.

3_ok.jpg

Na górze odczyt wynosił 196,21 m n.p.m. Same wartości są obarczone znacznym błędem (przez brak kalibracji), ale ich różnica pokazuje, że pomiar jest poprawny: 196,21 - 76,58 = 115,63 m. Taras widokowy jest na wysokości 114 m, więc uzyskane wyniki są wręcz zaskakująco dokładne. Niestety brak kalibracji początkowej sprawił, że konieczne było poprawienie programu - ale ja już nie miałem ochoty na kolejną wycieczkę, więc ostatecznie "test terenowy" pozostał tylko ciekawostką.

Cześć @Elvis ,

Odczyt z rejestru REF_P_XL zwraca mi 0 🙂

Coś muszę robić nie tak, poniżej wstawiam fragment konfiguracjii programu proszę o pomoc:

#define LPS25HB_REF_P_XL         0x08

#define LPS25HB_INTERRUPT_CFG     0x24
#define LPS25HB_INT_SOURCE         0x25

HAL_StatusTypeDef lps25hb_init(void)
{
    if (lps_read_reg(LPS25HB_WHO_AM_I) != 0xBD)
         return HAL_ERROR;

    lps_write_reg(LPS25HB_CTRL_REG1,  0xC8);
    lps_write_reg(LPS25HB_CTRL_REG2,  0x40);
    lps_write_reg(LPS25HB_FIFO_CTRL,  0x1F);
    lps_write_reg(LPS25HB_INTERRUPT_CFG,  0x07);
    lps_write_reg(LPS25HB_INT_SOURCE,  0x07);

    return HAL_OK;
}



float lps25hb_read_reference_pressure(void)
{
     int32_t pressure = 0;

     if (HAL_I2C_Mem_Read(&hi2c1, LPS25HB_ADDR, LPS25HB_REF_P_XL | 0x80, 1, (uint8_t*)&pressure, 3, TIMEOUT) != HAL_OK)
         Error_Handler();

     return pressure;
}

 

Z góry dzięki za pomoc

Edytowano przez Szymon_Zet
dodatkowe informacje
Link do komentarza
Share on other sites

@Szymon_Zet a co się dzieje jak odczytujesz: REF_P_H i REF_P_L?

Cytat

The Reference pressure value is a 24-bit data subtracted from the sensor output measurement and it is composed of REF_P_H (0Ah), REF_P_L (09h) and REF_P_XL (08h). The value is expressed as 2’s complement.

 

Link do komentarza
Share on other sites

Witam,

Podczas próby komunikacji przez I2C dla omawianego tematu natknąłem się na problem w odczytaniu adresu modułu przez program. Mianowicie zdefiniowałem rejestr LPS25HB_WHO_AM_I na wartość 0x0f a adres modułu LPS25HB_ADDR na wartość 0xBD. Mimo to wartość zwracana przez rejestr wynosi 0 zamiast 0xBD, czyli czujnik nie jest wykrywany.

Poszukałem w internecie skanera pod i2c i jeżeli wierzyć mu na słowo to nie znajduje żadnych adresów na magistrali. Ale sprawdzałem podpięcia i zarówno SDA i SCL mam na prawidłowych pinach 😕

Próbowałem podłączyć obie linie do zasilania rezystorami 4,7k oraz zmienić interfejs i2c1 na i2c2 i przełączyć piny PB6, PB7 na PB10, PB11, jak również podpiąć inny czujnik komunikujący się po i2c, niestety bez większych rezultatów.

Miałby może ktoś pomysł, jaka może być przyczyna tego problemu

 

EDIT: Miałem błąd w skanerze, okazuje się że udało się znaleźć adres, trochę inny niż podaje producent, ale poszło. Dzięki, bardzo ciekawy kurs.

Edytowano przez fidelty
  • Lubię! 1
Link do komentarza
Share on other sites

Dnia 5.11.2022 o 21:30, fidelty napisał:

EDIT: Miałem błąd w skanerze, okazuje się że udało się znaleźć adres, trochę inny niż podaje producent, ale poszło. Dzięki, bardzo ciekawy kurs.

@fidelty witam na forum i dziękuję za miłe słowa - cieszę się, że kurs jest ciekawy 🙂 Czy możesz podasz z ciekawości jaki inny adres znalazłeś? Do tej pory nikt inny nie zgłaszał takiej sytuacji, więc warto byłoby to sprawdzić.

Link do komentarza
Share on other sites

Mam pytanie, czy przypadkiem w programie do kalibracji:

void lps25hb_set_calib(uint16_t value)
{
	lps_write_reg(LPS25HB_RPDS_L, value);
	lps_write_reg(LPS25HB_RPDS_H, value >> 8);
}

value nie powinno być typu int16_t?

Zakładam, że poprawka może być zarówno dodatnia, jak i ujemna (wtedy uint16_t(-5) = 0, a kompilator nic nie zgłasza, przynajmniej u mnie)? Chyba, że nie ma takiej możliwości?

Link do komentarza
Share on other sites

@gtx Gratuluję spostrzegawczości, oczywiście RPDS powinien być reprezentowany jako liczba ze znakiem, czyli int16_t. W artykule kod jest zaraz obok fragmentu dokumentacji, gdzie wyraźnie jest napisane, że RPDS jest w forumacie U2.

Na szczęście użycie uint16_t w tym miejscu, chociaż nieeleganckie, może działać o wiele lepiej niż się wydaje.

uint16_t(-5) to nie 0, ale 65531. Ale co ważniejsze int16_t(65531), to znowu -5.  Czyli jeśli wywołamy lps25hb_set_calib() z parametrem -5, to w rzeczywistości value będzie miało wartość 65531 i taka wartość zostanie poprawnie przesłana do czujnika, który potraktuje ją jako -5.

Byłoby więc o wiele ładniej zmienić typ na int16_t, ale nawet jeśli tego nie zrobimy, program powinien nadal działać zgodnie z oczekiwaniami.

  • Lubię! 2
Link do komentarza
Share on other sites

@Elvis  Dzięki za wyjaśnienie!

Mam jeszcze pytanie odnośnie "mnożenia przez 16". Dajcie proszę znać czy dobrze rozumiem:

- gdyby RPDS był 24-bitowy to wartość obliczonego offsetu trzeba by było pomnożyć przez 4096 (2^12), zgodnie z dokumentacją

- jednak RPDS jest 16 bitowy, dlatego wartość offsetu trzeba pomnożyć przez 2^12/2^(24-16) = 2^4 = 16

?

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.