Skocz do zawartości

Porównanie czujników ciśnienia, żyroskopów i akcelerometrów


Pitlab

Pomocna odpowiedź

W ramach prac rozwojowych nad swoim projektem komputera pokładowego modelu latającego, który ma sporo wspólnego z robotyką zrobiłem kilka testów porównawczych różnych czujników. Ze względu na uniwersalność i elastyczność, (prawie) wszystkie czujniki są umieszczone w odłączanych modułach. Obecny test miał wyłonić optymalną konfigurację jednego z tanich, cyfrowo odczytywanych (przez I2C/SPI) czujników dających funkcjonalność jednostki inercyjnej i wysokościomierza czyli modułu All-In-One.

Oto artykuły:

Porównanie czujników ciśnienia

Porównanie żyroskopów i akcelerometrów

Artykuły były już prezentowane w innych miejscach, ale mam nadzieję że przydadzą się również i tutaj.

Link do komentarza
Share on other sites

Pitlab, przeczytałem twój artykuł dotyczący żyroskopów i akcelerometrów ale szkoda, że robisz testy tylko w odniesieniu do temperatury. Mnie osobiście interesuje najbardziej dryft żyroskopów, plus metody kompensacji, a takiego porównania dostępnych żyroskopów nie ma nigdzie.

Link do komentarza
Share on other sites

szkoda, że robisz testy tylko w odniesieniu do temperatury. Mnie osobiście interesuje najbardziej dryft żyroskopów, plus metody kompensacji

To własnie temperatura jest największym źródłem dryftu w żyroskopach. W rozdziale "Próba kompensacji temperaturowej żyroskopów" zrobiłem testowo (w arkuszu kalkulacyjnym) dobór współczynnika temperaturowego pozwalającego zmniejszyć dryft ok. 10-krotnie dla lepszych czujników. W artykule jest jeszcze sporo niepewności wynikającej z użycia zewnętrznego termometru. Trzeba będzie to powtórzyć dla termometrów wbudowanych w każdy żyroskop. Oczekuję że pozwoli to na wyeliminowanie histerezy dla szybko zmieniającej się temperatury.

Jest z tym sporo roboty, bo jak pokazuje dotychczasowo praktyka, każdy termometr w żyroskopie pokazuje inną temperaturę i najpierw wypadało by je skalibrować a dopiero potem robić kompensację żyroskopu.

Jak rozumiem Ciebie nie interesuje zmniejszanie dryftu, tylko jego całkowita eliminacja. Do tego jeszcze nie dotarłem, ale wiem że robi się to filtrami komplementarnymi, gdzie z żyroskopu brana jest tylko zmienna składowa z pominięciem stałej (czyli dryftu) a z komplementarnego akcelerometru, dla którego została wykonana transformacja układu odniesienia z układu względem obiektu na układ względem Ziemi, brana tylko odpowiednio przefiltrowana i obłożona warunkami (brak przyspieszeń dynamicznych wynikających ze zmiany prędkości i kierunku ruchu) informacja o położeniu wektora przyspieszenia ziemskiego.

Te dwie informacje splata się w filtrze, np. Kalmana i tak otrzymuje się wektor określający 3 podstawowe kąty Eulera orientacji w przestrzeni (Theta, Phi i Psi).

Link do komentarza
Share on other sites

Mnie interesuje dryft ale dla mniej więcej stałej temperatury, nie będę używał żyroskopów w takich warunkach jak ty. Z tego co czytałem to dryftu nie da się całkowicie wyeliminować, ale mnie np. interesuje informacja porównawcza, np., który z dostępnych żyroskopów ma najmniejszy dryft w temperaturze pokojowej. Jaki ma wpływ szybkość zmian prędkości kątowej na ten dryft. Czyli innymi słowy mówiąc, który z żyroskopów da mi najwierniejsze dane bez zaprzątania skomplikowanych algorytmów i akcelerometrów w proces uzyskania interesujących mnie informacji o kącie obrotu.

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

mnie np. interesuje informacja porównawcza, np., który z dostępnych żyroskopów ma najmniejszy dryft w temperaturze pokojowej. Jaki ma wpływ szybkość zmian prędkości kątowej na ten dryft. Czyli innymi słowy mówiąc, który z żyroskopów da mi najwierniejsze dane bez zaprzątania skomplikowanych algorytmów i akcelerometrów w proces uzyskania interesujących mnie informacji o kącie obrotu.

To jest trudne pytanie. Jak widzisz w moim skromny porównaniu każda oś żyroskopu ma inny dryft w temperaturze pokojowej (za taką możemy przyjść początek i koniec charakterystyki temperaturowej). Nawet tak drogie czujniki jak ADXRS610 jeden miał dodatnią charakterystykę temperaturową dającą ok. 3,5°/s dryftu w minimalnej temperaturze, drugi miał charakterystykę ujemną dającą w tych samych warunkach dryft -0,3°/s. Dodatkowo każdy miał inną wartość dryftu w temperaturze pokojowej.

Należy oczekiwać jakiegoś rozrzutu parametrów pomiędzy poszczególnymi czujnikami. Nie badałem jeszcze tego, bo to wymaga przetrzepania sporej ilości sprzętu a jeszcze taką nie dysponuję. Na chwilę obecną mam ok. 20 żyroskopów ADXRS ale tylko 6 jest obsadzone w minimodułach, tylko 2 żyroskopy ITG-3200 i ok. 20 kompletów żyroskopów IDG-500 i ISZ-500 z czego tylko kilka jest obsadzonych w modułach. Zrobienie charakterystyk tego wszystkiego to 1-2 tygodnie pracy, stąd pewnie brak obfitości tego typu porównań.

Chcąc uprościć algorytmy do minimum musiałbyś używać wyselekcjonowanych żyroskopów a to jest wcale nie mniej skomplikowane niż oprogramowanie takiego filtra, które będzie mogło pracować z każdym egzemplarzem żyroskopu. Przede wszystkim takie rozwiązanie jest wielokrotnie droższe.

Jeżeli zakładasz że będziesz poruszał się w stałej temperaturze, to po po kilku minutach od włączenia (potrzebnej na ustabilizowanie się temperatury czujników podgrzewanych własnym prądem zasilania) możesz wykonać inicjalizację, która uśredni kilkaset pomiarów, wyliczy poziom dryftu i przyjmie tą wartość jako poziom zerowy. To chyba najbanalniejszy sposób rozwiązania problemu.

Zrobienie porządnego filtra nie jest takie bardzo skomplikowane, zakładając że piszesz w języku obsługującym funkcje trygonometryczne na jakiś współczesny mikrokontroler radzący sobie z takimi obliczeniami. Transformacja układów współrzędnych to trochę trygonometrii do ogarnięcia przez kogoś po kursie matematyki szkoły średniej. Obrót wokół jednej osi to szkolne zadanie z poczatków trygonometrii, tutaj trzeba zrobić 3 obroty w konkretnej kolejności. Z pewnością znajdziesz gotowe wzory choćby tutaj o kątach eulera

Filtr nie musi być od razu Kalmana. Wydaje mi się ze możesz zacząć od zwykłej średniej ważonej dwu sygnałów: odfiltrowanego, odpowiednio przetransformowanego akcelerometru i informacji przyrostowej kąta liczonej ze zmian sygnału żyroskpu. W filtrze Kalmana masz dwie fazy: predykcji i korekcji. W fazie predykcji powiększasz dotychczasowy kąt o wartość prędkości kątowej z żyroskopu razy czas między pomiarami a w fazie korekcji uśredniasz to ze wskazaniami akcelerometru. Na początku możesz przyjąć współczynnik uśredniania w stylu:

kąt = 0,05*(kąt z akcelerometru po transformacji) + (1-0,05)*(prędkość z żyroskopu * czas)

Filtr Kalmana ponad to daje Ci jeszcze informacje statystyczne która z wartości lepiej pasuje do liczonego modelu i dynamicznie ustala współczynnik wagowy (tutaj 0,05).

Link do komentarza
Share on other sites

a jak się sprawował czujnik ciśnienia bmp085? zastosowałem go do pomiaru ciśnienia w stacji pogodowej ale strasznie zawyża ciśnienie pokazuje nawet 1045hPa, jak tobie on działał?

Zerkam na upubliczniony log: http://www.pitlab.pl/autopitlot/log/W-Test_110721_79_BMP085.log (najlepiej obejrzeć go w specjalistycznym edytorze tekstu dla programistów np. UltraEdit, bo w przeglądarce zawija linie) i widzę dużą rozpiętość ciśnień mierzonych między czujnikiem MPX6115 a BMP085.

Ciśnienie z MPX6115 jest w kolumnie opisanej jako "Press" a ciśnienie z BMP085 w kolumnie opisanej "PresA". Jedne z pierwszych pomiarów dla MPX wskazuje 86.1427kPa a dla BMP jest 95.0272kPa. Nie wiem która wartość jest prawdziwa i nie mam pod ręką wiarygodnego punktu odniesienia.

Najbliższa stacja referencyjna jest na Ursusie: http://www.meteo.waw.pl/

W tej chwili według danych ze stacji jest ciśnienie rzeczywiste 1004,5hPa a u mnie kilka kilometrów dalej na 10-tym piętrze niekalibrowane czujniki pokazują odpowiednio: MPX=90,7067kPa i BMP=100,029kPa.

Ponieważ jestem na 10-tym piętrze, więc ok. 30m nad ziemią (nie wiem na jakiej wysokości jest stacja referencyjna, ale zakładam że standardowo, ok. 2m powyżej gruntu). Według moich danych na każde 100m ciśnienie spada o 1300Pa, więc na 28m będzie niższe o 364Pa, czyli bazując na ciśnieniu stacji u mnie powinno być 1000,86hPa.

Zdecydowanie bliżej tej wartości jest BMP085.

Podsumowując oba czujniki, to MPXH6115 ma dobrą odpowiedź dynamiczną. Nadaje się do takich rzeczy jak wariometr, czy krótkookresowy stabilizator wysokości lotu. Niestety mają duży rozrzut i mocno płyną z temperaturą.

BMP05 płynie jeszcze więcej (robiłem logowanie wartości przed obliczeniami ciśnienia), ale ma już w fabryce pomierzone wszystkie parametry i przynajmniej te 2 egzemplarze, które testowałem, po uwzględnieniu w obliczeniach wszystkich parametrów kalibracyjnych zachowują się bardzo stabilnie. Niestety trochę szumią i koledzy próbujący utrzymać wysokość lotu w quadrokopterach mocno na nie narzekają, bo kopter pływa im pół metra w tą, pół w tamtą.

Do taniej stacji pogodowej BMP085 jest wystarczająco dobrym rozwiązaniem. Jeżeli chcesz zrobić to profi, to wtedy MPXH6116 + dobry przetwornik i trochę posiedzieć nad jego kalibracją.

Link do komentarza
Share on other sites

do wyliczenia ciśnienia bmp używałeś standardowych równań z noty?

w moim przypadku wartość ciśnienia jest stabilna wahania rzędu +-1Pa. Tylko nie wiem czy wskazuje poprawną wartość. Sprawdzę z innym czujnikiem mpl115a2, ale sądzę że będzie jeszcze gorszy.

Link do komentarza
Share on other sites

do wyliczenia ciśnienia bmp używałeś standardowych równań z noty?

Tak, nie spotkałem innych obliczeń. Tam łatwo jest się pomylić, ale jest przykład, więc podstawiając przykładowe dane pod swoją wersję algorytmu łatwo jest go zweryfikować.

W ramach weryfikacji dobrze jest podgrzać czujnik np. suszarką do włosów aby sprawdzić czy nie ma błędu w kompensacji temperatury. Ewentualnie schłodzić - lodówka, albo na szybko i bardzo chłodno - butan do zapalniczek. Jest łatwopalny jak większość schładzaczy, ale przy odrobinie rozsądku da się go używać.

Jeżeli nie masz wzorca, to możesz wykorzystać ogólnopolskie wzorce, choćby podaną wcześniej stację http://www.meteo.waw.pl/. Znajdź spokojny dzień kiedy nie ma wiatru, na przykład dzisiaj. Brak wiatru oznacza brak różnicy ciśnień, więc 100km dalej ciśnienie nie powinno istotnie się różnić od tego u Ciebie. Wykres ciśnienia z dzisiejszego poranka oscyluje miedzy wartościami 1005,6 - 1006,5. Jeżeli znajdziesz jakąś bliższą stację to tym lepiej. Dokładność 0,5hPa dla domowej stacji meteo mnie by wystarczyła.

Link do komentarza
Share on other sites

popołudniu podam mój algorytm, może znajdziesz w nim błąd, wydaje mi się że jest taki sam jak w dokumentacji.

U mnie problem z kodem wyglądającym tak samo jak w dokumentacji polegał na kolejności wykonywania obliczeń. W końcu porozbijałem te dosyć długie wzory na prostsze operacje i sprawdzałem czy obliczenia na podanym przykładzie wychodzą tak jak w dokumentacji i z kalkulatora. Kilka operacji musiałem rozbić na mniejsze fragmenty, pomimo tego że wydawało się że kolejność operacji jest prawidłowa.

Już nie pamiętam czy to w tym czujniku, ale w którymś ze wzorów jest przesunięcie bitowe wewnątrz innych obliczeń. Przesunięcie ma najniższy priorytet i pomimo nawiasów nie chciało mi się poprawnie liczyć. Trzeba było obliczyć część wzoru do przesunięcia a w kolejnej linii dalsze operacje po przesunięciu, itp.

Link do komentarza
Share on other sites

long int X1,X2,B5,B6,X3,B3;
unsigned long int B4,p;
unsigned long int B7;
unsigned char MSB,LSB,XLSB;
unsigned int UT;
unsigned long int UP ;


TWI_zapis(0xEE,0xF4,0x2E); //
_delay_ms(4.5);
TWI_odczyt(0xEE,0xF6);     //
MSB=odczyt;
TWI_odczyt(0xEE,0xF7);
LSB=odczyt;

UT=((MSB<<8)+(LSB));



TWI_zapis(0xEE,0xF4,(0x34 + (OSS<<6)));
_delay_ms(2 + (3<<OSS));
TWI_odczyt(0xEE,0xF6);
MSB=odczyt;
TWI_odczyt(0xEE,0xF7);
LSB=odczyt;
TWI_odczyt(0xEE,0xF8);
XLSB=odczyt;

UP=(((unsigned long) MSB << 16) | ((unsigned long) LSB << 8) | (unsigned long) XLSB) >> (8-OSS);



X1=(((long)UT-(long)AC6)*(long)AC5)>>15;	
X2=(((long)MC<<11)/(X1+MD));
B5=X1+X2;
temperature=((B5+8)>>4);
temperature=temperature/10;


B6 = B5 - 4000;
// Calculate B3
X1 = (B2 * (B6 * B6)>>12)>>11;
X2 = (AC2 * B6)>>11;
X3 = X1 + X2;
B3 = (((((long)AC1)*4 + X3)<<OSS) + 2)>>2;


// Calculate B4
X1 = (AC3 * B6)>>13;
X2 = (B1 * ((B6 * B6)>>12))>>16;
X3 = ((X1 + X2) + 2)>>2;
B4 = (AC4 * (unsigned long)(X3 + 32768))>>15;

B7 = ((unsigned long)(UP - B3) * (50000>>OSS));
if (B7 < 0x80000000)
	p = (B7<<1)/B4;
else
	p = (B7/B4)<<1;

X1 = (p>>8) * (p>>8);
X1 = (X1 * 3038)>>16;
X2 = (-7357 * p)>>16;
p += (X1 + X2 + 3791)>>4;


pressure=(float)p/100;
Link do komentarza
Share on other sites

long int X1,X2,B5,B6,X3,B3;

unsigned long int B4,p;

unsigned long int B7;

unsigned char MSB,LSB,XLSB;

unsigned int UT;

unsigned long int UP ;

[...] transmisji nie jestem w stanie sprawdzić

UT=((MSB<<8)+(LSB)); sprawdź czy dobrze przesuwa się MSB. Przesunięcie o 8 bez rzutowania na co najmniej 16-bitową liczbę może dać 0.

[...]

UP=(((unsigned long) MSB << 16) | ((unsigned long) LSB << 8) | (unsigned long) XLSB) >> (8-OSS);

X1=(((long)UT-(long)AC6)*(long)AC5)>>15;

X2=(((long)MC<<11)/(X1+MD)); tutaj jest przesunięcie niby wewnątrz nawiasu ale po nim są operacje o wyższym priorytecie i mój kompilator źle to liczył. Zastąpiłem przesunięcie mnożeniem *2048 i jest OK

B5=X1+X2;

temperature=((B5+8)>>4);

temperature=temperature/10; te 2 linie można zapisać temperature=(B5+8)/160; tak jest jedna operacja mniej do liczenia. Ja rozpisuję sobie różne warianty obliczeń i wyświetlam zdeassemblowany kod i porównuję która wersja daje krótszy kod.

B6 = B5 - 4000;

// Calculate B3

X1 = (B2 * (B6 * B6)>>12)>>11;

X2 = (AC2 * B6)>>11;

X3 = X1 + X2;

B3 = (((((long)AC1)*4 + X3)<>2; tutaj są dwa zagnieżdżone przesunięcia rozdzielone dodawaniem mającym wyższy priorytet. Tak u mnie źle się liczyło. W pierwszej kolejności policz do przesunięcia przez wartość OSS a w drugiej linii dodaj 2 i przesuń o 2.

// Calculate B4

X1 = (AC3 * B6)>>13;

X2 = (B1 * ((B6 * B6)>>12))>>16;

X3 = ((X1 + X2) + 2)>>2;

B4 = (AC4 * (unsigned long)(X3 + 32768))>>15;

B7 = ((unsigned long)(UP - B3) * (50000>>OSS));

if (B7 < 0x80000000)

p = (B7<<1)/B4; tutaj też może być problem bo przesuniecie ma się wykonać pierwsze a raczej wykona się już po dzieleniu

else

p = (B7/B4)<<1;

X1 = ( 😋>>8) * ( 😋>>8); co znaczy ten dwukropek przed P?

X1 = (X1 * 3038)>>16;

X2 = (-7357 * p)>>16;

p += (X1 + X2 + 3791)>>4;

pressure=(float) :P/100;

Daj znać czy ruszyło po poprawkach.

Link do komentarza
Share on other sites

	long int X1,X2,B5,B6,X3,B3;
unsigned long int B4,p;
unsigned long int B7;
unsigned char MSB,LSB,XLSB;
unsigned int UT;
unsigned long int UP = 0;


TWI_zapis(0xEE,0xF4,0x2E); //
_delay_ms(4.5);
TWI_odczyt(0xEE,0xF6);     //
MSB=odczyt;
TWI_odczyt(0xEE,0xF7);
LSB=odczyt;

UT=((MSB<<8)+(LSB));



TWI_zapis(0xEE,0xF4,(0x34 + (OSS<<6)));
_delay_ms(2 + (3<<OSS));
TWI_odczyt(0xEE,0xF6);
MSB=odczyt;
TWI_odczyt(0xEE,0xF7);
LSB=odczyt;
TWI_odczyt(0xEE,0xF8);
XLSB=odczyt;
//szesna=MSB<<8;
UP=(((unsigned long) MSB << 16) | ((unsigned long) LSB << 8) | (unsigned long) XLSB) >> (8-OSS);



X1=(((long)UT-(long)AC6)*(long)AC5)>>15;	
X2=(((long)MC*2048)/(X1+MD));
B5=X1+X2;
temperature=((B5+8)>>4);
temperature=temperature/10;


B6 = B5 - 4000;
// Calculate B3
X1 = (B2 * (B6 * B6)>>12)>>11;
X2 = (AC2 * B6)>>11;
X3 = X1 + X2;
B3 = ((((long)AC1)*4 + X3)<<OSS);
B3 = (B3+2)>>2;   


// Calculate B4
X1 = (AC3 * B6)>>13;
X2 = (B1 * ((B6 * B6)>>12))>>16;
X3 = ((X1 + X2) + 2)>>2;
B4 = (AC4 * (unsigned long)(X3 + 32768))>>15;

B7 = ((unsigned long)(UP - B3) * (50000>>OSS));
if (B7 < 0x80000000)
	p = (B7*2)/B4;
else
	p = (B7/B4)<<1;

X1 = ( p>>8) * ( p>>8);
X1 = (X1 * 3038)>>16;
X2 = (-7357 * p)>>16;
p += (X1 + X2 + 3791)>>4;


pressure=(float) p/100;

poprawiłem ale nadal pokazuje taką samą wartość.

Aktualnie 1040,9 hPa

Link do komentarza
Share on other sites

UT=((MSB<<8)+(LSB));	

poprawiłem ale nadal pokazuje taką samą wartość.

Aktualnie 1040,9 hPa

Z poprawek została jeszcze ta linia. Ona liczy temperaturę. Jeżeli wartość temperatury jest skopana, to kompensacja bazująca na złych danych może dawać taką dużą wartość.

Zobacz jaką temperaturę odczytujesz z czujnika.

Przede wszystkim gdy zamiast odczytu danych z czujnika i EEPROMu podasz wartości ze strony 13 Data sheeta to czy wychodzi Ci taki sam wynik?

Czy czujnik ciśnienia pokazuje jakieś zmiany ciśnienia np na różnych wysokościach?

Ewentualnie weź jakiś grubościenny wężyk - najlepsze są silikonowe bo elastyczne i miękkie. Przyłóż do otworka w czole czujnika i podaj ustami jakieś pod/nad ciśnienie. Zobacz czy wynik się zmienia.

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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.