fbpx

Tym razem będziemy jak tytułowy Chuck Norris bowiem będziemy mierzyć temperaturę obiektów w ogole ich nie dotykając. Pomoże nam w tym odległościowy czujnik temperatury MLX90614

Pirometr MLX90614

Jest to pirometr czyli czujnik, który pomiaru temperatury dokonuje na podstawie emitowanego przez obiekt promieniowania cieplnego. Każdy przedmiot emituje takie promieniowanie. Jest wyczuwalne przez człowieka(czujesz ciepło zbliżając się do gorącego przedmiotu). Przede wszystkim promieniowanie to emitowane jest najlsilniej w zakresie podczerwieni. Z tego wynika, że nie jest ono widoczne dla człowieka(o widmie światła widzialnego co nieco pisałem tutaj). Oczywiście są wyjątki – ciała rozgrzane powyżej 600ºC mogą emitować fale na tyle krótkie, że mogą znajdować się już w zakresie widzialnym, a dokładnie w czerwieni. To dlatego mocno rozgrzany metal świeci na czerwono.

Pirometr ma za zadanie przeanalizować te promieniowanie i na jego podstawie wyznaczyć temperaturę obiektu. W praktyce będzie to temperatura powierzchni.

Pole widzenia – FOV

Czujniki takie mają jedną, podstawową wadę(a może dla kogoś zaletę?). Posiadają pewien stały kąt widzenia. Stąd, ich pole pomiarowe uzależnione jest od odległości od badanego obiektu. Jest to dokładnie takie samo działanie jak ultradźwiękowego czujnika odległości(Tani dalmierz ultradźwiękowy HC-SR04) – im dalej znajduje się czujnik od obiektu, tym większy ten obiekt powien być, aby pomiar był wiarygodny.

Istnieje kilka wersji MLX90614 o różnych FOV. Zakresy dla różnych typów przedstawia poniższa tabela znajdująca się w dokumentacji.

Do dyspozycji mamy czujniki z jednym oraz dwoma polami aktywnymi. Posiadany przeze mnie moduł z Chin GY-906 posiada zamontowany MLX90614ESF-BAA, więc pole widzenia mojego egzemplarza to 72º. Jest to bardzo szeroki kąt dlatego należy pamiętać, aby temperaturę mierzyć z jak najmniejszej odległości od obiektu.

Trochę najważniejszych danych z dokumentacji( MLX90614 Datasheet ):

  • 17-bitowy przetwornik ADC – całkiem sporo tych bitów
  • Zakres pomiarowy temperatury otoczenia -40÷125ºC
  • Dla badanego obiektu temperaturę widzi w zakresie -70÷382,2ºC

Emisyjność

Niestety jak to z fizyką bywa – jest skomplikowana. Pomiar bezprzewodowy jest kuszący i może wyglądać na łatwy, ale jest pewien haczyk. Jest to zdolność emisyjna badanego obiektu. Jest to parametr mówiący o zdolności powierzchni ciała do emisji promieniowania cieplnego. Tłumacząc na polski – jedne materiały emitują promieniowanie cieplne lepiej, inne gorzej. Niestety należałoby to uwzględnić w pomiarach. Wielkość ta mieści się w zakresie 0÷1 i otrzymany wynik należy pomnożyć przez tą wartość. Na szczęście nie musimy robić tego sami, bo MLX90614 potrafi sam przeliczyć temperaturę na podstawie podanej emisyjności.

Każdy nowy czujnik ma ten parametr ustawiony na 1. Znajduje się on w pamięci EEPROM czujnika i można go oczywiście zmieniać. Tylko skąd mamy wiedzieć na ile zmienić? Przykładowo skóra ludzka posiada emisyjność na poziomie 0.985 natomiast polerowane aluminium tylko 0,05. A co z całą resztą istniejącą na świecie powierzchni? Istnieją tablice emisyjności z których można te wartości pobrać. Przykładową możesz pobrać stąd: Tablica emisyjności IR .

Komunikacja

Z MLX90614 dane na temat temperatury można wyciągnąć dwojako. Pierwszym interfejsem jest SMBus, czyli pochodna I²C. Drugim z kolei jest sygnał PWM, który szczerze mówiąc rzadko widziałem w użyciu dlatego nie implementowałem go tak jak miało to miejsce w przypadku SDS011. W dodatku po resesie domyślnym interfejsem jest SMBus, więc po co komplikować sobie życie.

Czym różni się ten SMBus od zwykłego I²C? Dla nas najważniejszą różnicą bedzie PEC czyli Packet Error Checking. Służy on do sprawdzania poprawności przepływających danych i w tym przypadku będzie wykorzystywany tylko przy zapisie do EEPROM czujnika. Jest to najzwyklejsza suma kontrolna CRC-8 liczona na podstawie adresu urządzenia, adresu rejestru do którego piszemy oraz wartości która jest wpisywana. Czy to problem? Nie. Można to rozwiązać w dwojaki sposób. Otóż STM32 mają wbudowaną obsługę SMBus i wybierając ją w CubeMX nie musisz się martwić żadnym PEC’em. Drugim sposobem jest policzenie i doklejenie CRC do przesyłanych danych.

Ja w implementacji użyłem zwykłego I²C. Dlaczego? Może się zdarzyć, że na jednym interfejsie będzie kila różnych urządzeń i nie każde będzie chciało PEC’a. Można byłoby machać bitem odpowiedzialnym za transfer PEC w rejestrach konfiguracyjnych I²C, ale nie gwarantuję, że każdy STM32 ma ten bit w tym samym miejscu. Zależało mi też na przenośności między rodzinami MCU. No dobra… ale to kosztuje i czas i flash i wszystko! Policzenie CRC może zajmuje chwilkę czasu, ale ile razy będziesz coś pisał do czujnika? Niewiele. Flash? Jest sporo w STMach.

Schemat i konfiguracja CubeMX

Dzisiaj użyłem Nucleo z mikrokontrolerem L053R8.

MLX90614 obsługuje maksymalnie 100 kHz na magistrali I²C, więc nie poszalejemy 🙁

Biblioteka

Czujnik nie jest mocno rozbudowany stąd nie wymaga przepastnej biblioteki. Tradycyjnie pierwszą funkcją jest inicjalizacja. W tym wypadku czujnik jest gotów do odczytu już po załączaniu mu zasilania, więc w funkcji tej przypisywany jest jedynie wskaźnik do interfejsu I²C.

MLX90614_STATUS MLX90614_Init(I2C_HandleTypeDef *hi2c);

Pirometr umożliwia odczyt dwóch temperatur – otoczenia oraz widzianego obiektu. Odczyt czujników przeprowadzisz za pomocą poniższych funkcji.

MLX90614_STATUS MLX90614_ReadObjectTemperature(float *Temperature);
MLX90614_STATUS MLX90614_ReadAmbientTemperature(float *Temperature);

Do obsługi emisyjności wystarczą Ci dwie funkcje.

MLX90614_STATUS MLX90614_GetEmissivity(float *Emissivity);
MLX90614_STATUS MLX90614_SetEmissivity(float Emissivity);

Wspomniałem wcześniej, że możesz zmienić adres SMBus czujnika. Pamiętaj, że biblioteka przewiduje tylko jeden czujnik podłączony do MCU i adres ustawiony jest na domyślny przez #define MLX90614_DEFAULT_ADDRESS ((0x5A)<<1). Jeśli chcesz zmienić adres, musisz przekompilować bibliotekę z nowym adresem. Chcąc podłączyć więcej czujników(max 127), trzeba będzie zmodyfikować bibliotekę.

Działanie MLX90614

Czujnik mierzy od razu po podłączeniu zasilania. Jeżeli nie chcesz zmieniać parametru emisyjności, wystarczy cyklicznie czytać temperaturę. W kodzie testowym czytam dwie temperatury oraz ustawioną emisyjność. Jak możesz zauważyć na screenie z terminala – emisyjność ustawiłem na odczyt ludzkiej skóry, a temperatura powierzchni mojego kciuka to lekko ponad 32ºC 🙂

Teraz to co tygryski(a przynajmniej jeden – ja) lubią najbardziej – czasówki. Najczęściej będziesz odczytywał temperaturę. Nie ma różnicy czy będzie ona dotyczyła otoczenia czy obiektu. Dla obydwu jest dokładnie taka sama procedura. Czas odczytu i przeliczenia temperatury to zaledwie 600 μs czyli bardzo mało.

Czy można użyć DMA? Oczywiście, że tak. Tylko zwróć uwagę, że należy dokonać małego przeliczenia, aby uzyskać temperaturę w Celsjuszach.

Podsumowanie

To by było na tyle jesli chodzi o ten ciekawy układ. Pirometr może być zastosowany wszędzie tam, gdzie nie ma możliwości ingerencji w mierzony obiekt. Sam w niedalekiej przyszłości będę chciał skonstruować sobie urządzenie na bazie tego czujnika. Co Wy na to, aby zrobić to live? Dajcie znac w komentarzach lub mailowo.

Jeżeli czujnik Ci się spodobał, możesz nabyć u mnie w sklepie.

Projekt z kodem znajduje się na moim GitHubie: link

Jeśli zauważyłeś jakiś błąd, nie zgadzasz się z czymś, chciałbyś coś dodać istotnego lub po prostu uważasz, że chciałbyś podystkutować w tym temacie, napisz komentarz. Pamiętaj, że dyskusja ma być kulturalna i zgodna z zasadami języka polskiego.

5/5 - (2 votes)

Podobne artykuły

.
Kategorie: STM32

14 komentarzy

Szymon · 29/09/2020 o 13:48

HAL_I2C_Master_Transmit, wypróbowałem tej funkcji wczesniej, ale niestety też program nie wchodził w tryb uśpienia. Szukam dalej 🙂

    Mateusz Salamon · 29/09/2020 o 13:50

    A na I2C leci dokładnie to, co trzeba? 🙂 Nie próbowałem nigdy Sleepa, ale próbuj z tym OPCODE tak jak w DS napisali. A może jest jakiś przykład na Arduino? Jak rozwiążesz to chętnie dorzucę Sleepa do mojej libki.

Szymon · 29/09/2020 o 13:34

Tylko tam zamiast HAL_I2C_Mem_Read jest HAL_I2C_Mem_Write

    Mateusz Salamon · 29/09/2020 o 13:35

    A no to daj tam 0xFF właśnie 🙂

    Szymon · 29/09/2020 o 13:36

    Okej, to co w takim razie w uint8_t *pData, które tutaj jest buforem tmp[2] ? 😛

      Mateusz Salamon · 29/09/2020 o 13:37

      A właśnie 🙂 Nic pod ten 0xFF nie piszesz więc użyj funkcji HAL_I2C_Write zamiast Mem_Write.

      Szymon · 29/09/2020 o 13:39

      No i własnie tu cały problem, bo nie mam dostępnej funkcji HAL_I2C_Write. Korzystam z Nucleo F411RE

      Mateusz Salamon · 29/09/2020 o 13:46

      To się zerka w dokumentacje lub szuka po HALowych funkcjach w IDE, a nie wierzy mi na słowo, bo pamięć jest zawodna 🙂 Sprawdziłem i to, co Cię interesuje nazywa się: HAL_I2C_Master_Transmit

Szymon · 29/09/2020 o 13:33

To w takim razie mam nadzieję, że ostatnie pytanie.
Mam taki zapis:
HAL_I2C_Mem_Read(hi2c1, MLX90614_DEFAULT_ADDRESS, Address, 1, tmp, 2, 10);

I zastanawiam się co podać tutaj w wartości “Address”

W moim przypadku hi2c1 to to samo co u Ciebie mlx90614_i2c 😉

    Mateusz Salamon · 29/09/2020 o 13:34

    Tutaj “Address” to wskaźnik do którego trafi wynik odcyztu z I2C.

Szymon · 29/09/2020 o 13:27

Mam wersję 3V, także Sleep mode jest. Czyli pod adres: MLX90614_DEFAULT_ADDRESS wysłać wartość 0xFF ?

    Mateusz Salamon · 29/09/2020 o 13:28

    Mam, spróbuj w ten sposób właśnie.

Szymon · 29/09/2020 o 13:14

Witam,
Mam pytanie co do sleep_mode.
Używając takiego zapisu:
MLX90614_Write16Eeprom(MLX90614_DEFAULT_ADDRESS, MLX90614_SLEEP_MODE);
czujnik nie wchodzi w tryb uśpienia. Z czego to wynika i jak powinien wyglądać poprawny kod ?

Pozdrawiam

    Mateusz Salamon · 29/09/2020 o 13:25

    Po pierwsze z dokumentacji wynika: Sleep mode is not available on the 5V version (MLX90614Axx).

    Nie wiem jaką masz dokładnie wersję 🙁

    Po drugie nie wchodzisz do Sleepa zapisem do EEPROM 😛 Tylko OPCODE 1111_1111, czyli musisz mu po prostu to wysłać pod jego adres 🙂

Dodaj komentarz

Avatar placeholder

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *