Dzisiaj chciałbym zaprezentować bibliotekę do obsługi cyfrowego barometru – HP02S.
Układ ten jest produkcji Hope RF, który wyróżnia się następującymi cechami:
- zakres pomiarowy 300-1100hPa
- 16-bitowy przetwornik Σ-Δ – odczytywanych jest jedyni 14bitów
- możliwość zasilanie 2.0 – 5.0 VDC
- niski pobór mocy
- komunikacja z uC poprzez magistralę I2C
- układ posiada 1 linię resetu
- konwersja odbywa się poprzez dostarczenie do układu sygnału o częstotliwości 32768Hz
- czas konwersji wynosi 35ms
- auto uśpienie
- układ posiada 5 współczynników kompensujących – brak potrzeby kalibracji
Według noty katalogowej (nie jest to wprost opisane), układ dostarcza nam możliwość pomiaru ciśnienie bezwzględnego – czyli na danej wysokości na której znajduje się czujnik. W wielu sklepach oferujących ten czujnik w opisie można się doczytać, że jest to czujnik do pomiaru ciśnienia oraz temperatury. Ciśnienia nie można odczytać wprost z układu, lecz po obliczeniu wzoru na ciśnienie w którym oprócz stałych współczynników – dla danego układu – znajdują się jeszcze dwie zmienna, które zależą od ciśnienia i temperatury (zmienne D1 i T1). Producent czujnika nie dostarcza wzoru na obliczenie temperatury, więc dane odczytane niby jako temperatura, nie odnoszą się bezpośrednio do temperatury powietrza. Reasumując czujnik mierzy ciśnienie i temperaturę, lecz użytkownik w efekcie końcowym otrzymuje tylko ciśnienie bezwzględne – brak możliwości odczytu temperatury (na chwilę obecną, może w przyszłości producent umieści wzór umożliwiający obliczenie zmierzonej temperatury)
Podczas obsługi czujnika ciśnienia należy zwrócić szczególną uwagę na:
- pin XCLR ma byś ustawiony w stan wysoki (logiczna 1 – wysoki) tylko w tedy gdy odczytywane są wartości T1 i D1 (są to wartości mierzone – temperatury i ciśnienia) – stan niski (logiczne 0) ma występować podczas odczytu współczynników kalibrujących
- do pinu MCLK ma być dostarczony sygnał o częstotliwości 32768Hz (z kwarcu), bądź 32kHz (bezpośrednio z wyjścia mikrokontrolera) – czas konwersji wynosi minimum 35ms.
- linia SCL magistrali I2C może być taktowana z maksymalną częstotliwością wynoszącą 500kHz.
Poniżej przedstawiam sposób podłączenia układu do mikrokontrolera: ( a – według noty katalogowej, b – układ podłączony podczas testów)
Działanie:
Obsługa HP02S została podzielona na dwie części. W pierwszej części, program odczytuje 5 współczynników kalibrujących (kompensujących działanie czujnika) – jest on wykonywany tylko raz na samym początku programu docelowego (współczynniki są stałe dla danego czujnika i nie zmieniają się podczas użytkowania go). Następna część dotyczy już odczytu, oraz obliczeń ciśnienia. Przedstawiam tym razem dość krótkie algorytmy obrazujące działanie biblioteki:
Na samym początku, po odpowiednim ustawieniu bitu XCLR oraz sygnału MCLK zostało zastosowane dodatkowe opóźnienie wynoszące 5ms. Zastosowałem je w celu ustabilizowania wszystkich parametrów – na liniach sygnałowych, oraz w czujniku.
Podczas odczytywania współczynników D0, T0, P0, S, C z pamięci EEPROM układu, jedynym problemem jest odnalezienie w dokumentacji adresu dostępu do tej pamięci. Dokumentacja zwraca jednak uwagę, że dostęp do pamięci EEPROM jest taki sam jak w układzie AT24C02 (pamięci EEPROM firmy Atmel). Zajrzyjmy więc do kolejnej dokumentacji. Po kilku chwilach można odnaleźć zapis, że adres komórek pamięci to 0xA0 (podczas zapisu) – tak więc można przystąpić do odczytania wcześniej wspomnianych współczynników. Trzeba pamiętać o tym, że pin XCLR ma mieć stan logicznej 1. Odczytanie współczynników dokonuje się wywołując funkcję:
//********** odczyt współczynników potrzebnych do poprawnego pomiaru
ds_hp02s_coeff();
Odczytane dane zapisywane są w wewnętrznej strukturze, do której użytkownik nie ma dostępu z poziomu programu.
Pomiar ciśnienia dokonuje się przy udziale sygnału taktującego, pochodzącego z zewnętrznego kwarcu 32768Hz, bądź ze sygnału o częstotliwości 32kHz który może być dostarczony z mikrokontrolera. W moim przypadku zastosowałem opcję drugą, tzn. skonfigurowałem timer 1 tak aby przerwanie wykonywało się co 32kHz w trybie CTC, czego skutkiem ma być przełączanie stanu jednego z pinów dostępnych dla tego timer – wybrałem pin 5 portu D. Po wysłaniu komendy z żądaniem pomiaru czekam 40ms – wg noty ma być minimum 35ms, więc warunek jest spełniony. Algorytm dotyczący pomiaru, który został przedstawiony wcześniej, prezentuje sposób odbioru danych dla jednej z dwóch zmiennych (D1 lub T1) – podczas odczytu algorytm ten jest wykonywany dwa razy. Aby rozpocząć pomiar należy wywołać funkcję:
ds_hp02s_start();
a następnie w pętli głównej użyć funkcji:
ds_hp02s_measure();
Pomiar zostanie wykonany tylko raz (aż do ponownego użycia funkcji rozpoczynającej pomiar), a dane zostaną zapisane w strukturze do której użytkownik ma dostęp:
int16_t value_D1;
int16_t value_T1;
uint16_t value_pressure_abs_cel; //całosc
uint8_t value_pressure_abs_frac; //liczba po przecinku
uint8_t value_update; //czy wartosci zostały zaktualizowane - wartosc inkrementowana
W zmiennych D1 oraz T1 znajduje się ostatnie odczytane wartości z czujnika. Zmienna value_update zwiększa się za każdym razem gdy zostanie zakończony pomiar. W pozostałych dwóch zmiennych przechowywana jest wartość ciśnienia – liczba całkowita, oraz po przecinku.
Dostęp do tej struktury jest poprzez zmienną
ds_hp02s_value_pressure
Konfiguracja biblioteki.
Konfigurację biblioteki dokonuje się w pliku ds_hp02s_conf.h. Do ustawienia mamy jedynie:
//pin i port do którego podłączony jest XCLR
#define HP02S_XCLR_PIN 1
#define HP02S_XCLR_PORT B
//ile wyników ma byc usrednionych maksymalnie 40 !!im wększa ilosc wynikow do usredniania tym wieksza zajetosc pamieci!!
#define HP02S_AVG_VALUE 1
//jaki odstęp pomiedzy kolejnymi pomiarami w ms (maksymalnie 200ms)
#define HP02S_AVG_TIME 100
Warte wyjaśnienia jest jedynie uśrednianie wyników. Zastosowałem je aby możliwy był dokładniejszy pomiar ciśnienia. Wg noty powinno się uśrednić co najmniej 8 wyników pomiarowych, aby móc zwiększyć dokładność (wartość ta jest rekomendowana przez producenta). Podczas zwiększania ilości pomiarów do uśrednienia, należy pamiętać, że im większy zakres tym więcej pamięci jest pochłanianych przez tą bibliotekę. Użytkownika biblioteki ma również możliwość ustawienia czasu pomiędzy kolejnymi pomiarami podczas uśredniania – czas ten może wynosić od 1ms do 200ms.
Program został dopasowany do następujących mikrokontrolerów z rodziny AVR:
- Atmega8
- Atmega16
- Atmega32
- oraz układy z takimi samymi rejestrami.
Natomiast częstotliwości obsługiwane przez bibliotekę to: 4MHz, 6MHz, 8MHz, 10MHz, 11,0592MHz, 12MHz, 14MHz, 16MHz, 20MHz.
Magistrala I2C.
Biblioteka którą wykonałem, charakteryzuje się szczególnym aspektem – obsługa I2C nie jest na sztywno połączona z biblioteką. Oznacza to, że użytkownika może posiadać własny sposób obsługi magistrali I2C i podpiąć ją do tej biblioteki, poprzez rejestrację funkcji, która wygląda następująco:
//********** rejestracji funkcji i2c potrzebnych dla hp02s
register_twi_start_hp02s(I2C_start);
register_twi_stop_hp02s(I2C_stop);
register_twi_read_hp02s(I2C_read);
register_twi_write_hp02s(I2C_write);
Jedyne ograniczenie to jest takie, że funkcje strat i stop nie powinny przekazywać żadnych argumentów, oraz nie powinny nic zwracać (typ void). Funkcja dotycząca odczytu – read – również nie powinna nic zwracać, leż możliwe jest przesłanie adresu jako typ 8 bitowy bez znaku (uint8_t). Możliwość przekazania argumentów posiada funkcja odczytująca dane z urządzenia – przesyłane jest potwierdzenie (ACK = 1). Funkcja read powinna zwracać dane w postacie 8 bitowej bez znaku (uint8_t)
Po dokonaniu konfiguracji, oraz rejestracji potrzebnych funkcji należy dokonać inicjalizacji poprzez wywołanie funkcji:
//********** inicjalizacja hp02s
ds_hp02s_init();
Użytkownik korzystający z tej biblioteki powinien uruchomić przerwanie wykonywane co 1ms, a w procedurze tego przerwania umieścić warunek:
if(hp02s_time_1ms--);
Dzięki temu warunkowi, biblioteka nie powoduje blokowania działania całego programu – nie brana jest pod uwagę biblioteka obsługująca I2C.
Przykładowy program:
Przedstawiam również przykładowy program do obsługi czujnika ciśnienia HP02S.
ISR(TIMER0_COMP_vect){
if(++time_1ms>9){
time_1ms=0;
if(++time_10ms < 99){
time_10ms=0;
if(++time_1s < 59) time_1s=0;
}
}
if(hp02s_time_1ms--);
}// /isr
int main(void){
//inicjalizacja LCD
lcd_init();
//********** rejestracji funkcji i2c potrzebnych dla hp02s
register_twi_start_hp02s(TWI_start);
register_twi_stop_hp02s(TWI_stop);
register_twi_read_hp02s(TWI_read);
register_twi_write_hp02s(TWI_write);
//********** inicjalizacja hp02s
ds_hp02s_init();
//inicjalizacja przerwań
//timer0 w trybie ctc
TCCR0 |= (1<<WGM01); //tryb CTC
TCCR0 |= (1<<CS01) | (1<<CS00); //preskaler 64
OCR0 = 249; //co 1ms dla preskalera 64 bity i kwarcu 16MHz
TIMSK |= (1<<OCIE0); //aktywacja przerwania
//aktywacja przerwań
sei();
//program własciwy
lcd_cls();
lcd_str_P(PSTR("Cisnienie:"));
//********** odczyt współczynników potrzebnych do poprawnego pomiaru
ds_hp02s_coeff();
ds_hp02s_start();
uint8_t tmp=0;
while(1){
//pomiar co 5 sekund
if( (time_1s != time_ls) && !(time_1s % 5) ){
time_ls = time_1s;
ds_hp02s_start();
}
ds_hp02s_measure();
if(ds_hp02s_value_pressure.value_update != tmp){
tmp = ds_hp02s_value_pressure.value_update;
lcd_locate(1,0);
lcd_int(ds_hp02s_value_pressure.value_pressure_abs_cel);
lcd_char('.');
lcd_int(ds_hp02s_value_pressure.value_pressure_abs_frac);
lcd_str("hpa ");
}
}
}
Program jest przykładowy i nie zawiera informacji dotyczących potrzebnych bibliotek. Biblioteki które powinny być dołączone do programu dotyczą obsługi magistrali I2C, oraz wyświetlacza LCD.
Cechy biblioteki.
Przedstawiona biblioteka zajmuje około 5kB pamięci Flash, oraz 302Bajty pamięci RAM – dokładna ilość zajmowane pamięci zależy od ilości pomiarów uśrednianych. Dodatkowo wszystkie funkcje odczytujące pomiary z HP02S są nieblokujące – nie blokują na dłuższy okres działania całej pracy systemu. Nie brane jest pod uwagę działanie biblioteki obsługującej magistralę I2C, gdyż ona może powodować blokujące działanie reszty programu.
Użytkownik podczas odczytywania ciśnienia ma do dyspozycji strukturę w której odczytuje wartość całkowitą zmierzonego ciśnienia, oraz wartość po przecinku. Dostępne są również wartości D1 i T1 ostatnie zmierzonego ciśnienia. W dostępnej strukturze znajduje się również informacja o ilości wykonanych pomiarów – resetuje się ona po przekroczeniu wartości 255.
Podczas konfiguracji biblioteki użytkownik może zdecydować, czy odczytywane ciśnienie ma być ciśnienie uśrednionym z określonej ilości próbek, czy nie (parametr ustawiony na 1). Pomiędzy kolejnymi pomiarami występuje opóźnienie określone przez użytkownika (od 1ms do 200 ms).
W razie pytań proszę o kontakt poprzez formularz kontaktowy, lub poprzez komentarz poniżej artykułu.
Pliki biblioteki można pobrać tutaj:
Pobierz “DS_HP02S.zip”
DS_HP02S.zip – Pobrano 277 razy – 4,90 KBZachęcam do pobierania.