-
1. Data: 2014-04-23 19:10:08
Temat: Działająca biblioteka do BMP085
Od: Atlantis <m...@w...pl>
Próbuję właśnie uruchomić BMP085 w jednym ze swoich urządzeń i powoli
zaczynam z tego powodu siwieć. ;)
Na samym początku, bez większego problemu udało mi się znaleźć taką oto
bibliotekę w Sieci:
http://www.sicklinger.com/en/component/remository/Mi
crocontroller/ATMEL-AVR-ATMEGA-BMP085-library-in-C/?
Itemid=54
Skompilowała się uruchomiła bez problemu. Wystarczyło właściwie tylko
dodać pliki nagłówkowe do istniejącego projektu. Niestety moja radość
nie trwała długo - okazało się, że wartość ciśnienia jest nieprawidłowa
- wychodzi jakieś 300 HPa...
Pierwsze o czym pomyślałem to uszkodzony czujnik. Wyjąłem więc z
szuflady Arduino i wgrałem ten kod:
https://www.sparkfun.com/tutorials/253
Wszystko ruszyło bez najmniejszego problemu, wartości były prawidłowe (a
przynajmniej prawdopodobne).
Zabrałem się więc za porównywanie kodu zawartego w obydwu bibliotekach.
Odczytywanie danych kalibracyjnych wygląda praktycznie tak samo,
podobnie jak końcowa konwersja.
Jedyny fragment, w którym mógłbym się czegoś dopatrywać to odczyt
wartości ciśnienia ze scalaka. W bibliotece pod AVR wygląda to następująco:
pressure = bmp085ReadShort(0xF6,error_code);
pressure = pressure << 8;
pressure = pressure >> (8-OSS);
Funkcja bmp085ReadShort zwraca uint16_t, a więc czytane są tylko dwa bajty.
Natomiast w kodzie na Arduino znajduje się następujący fragment:
msb = Wire.read();
lsb = Wire.read();
xlsb = Wire.read();
up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) |
(unsigned long) xlsb) >> (8-OSS);
Jak widać odczytywane są tutaj trzy jednobajtowe (char) zmienne, które
potem są konwertowane do zwracanej wartości unsigned long.
Czy moja dedukcja jest prawidłowa? A może to nie ma nic do rzeczy i
źródła problemu powinienem szukać gdzie indziej?
-
2. Data: 2014-04-23 19:44:23
Temat: Re: Działająca biblioteka do BMP085
Od: "Pszemol" <P...@P...com>
"Atlantis" <m...@w...pl> wrote in message
news:lj8s5v$q9a$1@portraits.wsisiz.edu.pl...
> Jedyny fragment, w którym mógłbym się czegoś dopatrywać to odczyt
> wartości ciśnienia ze scalaka. W bibliotece pod AVR wygląda to
> następująco:
>
> pressure = bmp085ReadShort(0xF6,error_code);
> pressure = pressure << 8;
> pressure = pressure >> (8-OSS);
>
> Funkcja bmp085ReadShort zwraca uint16_t, a więc czytane są tylko dwa
> bajty.
>
> Natomiast w kodzie na Arduino znajduje się następujący fragment:
>
> msb = Wire.read();
> lsb = Wire.read();
> xlsb = Wire.read();
>
> up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) |
> (unsigned long) xlsb) >> (8-OSS);
>
> Jak widać odczytywane są tutaj trzy jednobajtowe (char) zmienne, które
> potem są konwertowane do zwracanej wartości unsigned long.
>
> Czy moja dedukcja jest prawidłowa? A może to nie ma nic do rzeczy
> i źródła problemu powinienem szukać gdzie indziej?
Co to jest za identyfikator OSS i jak jest ustawiony w obu porównywanych
kodach? Zauważ, że od wartości OSS zależy przesunięcie wyniku w prawo aż o 8
bitów! Zła wartość OSS będzie bardzo silnie wpływać na wynik.
-
3. Data: 2014-04-23 19:55:07
Temat: Re: Działająca biblioteka do BMP085
Od: "Pszemol" <P...@P...com>
"Pszemol" <P...@P...com> wrote in message
news:lj8u5o$e8k$1@dont-email.me...
> Co to jest za identyfikator OSS i jak jest ustawiony w obu porównywanych
> kodach? Zauważ, że od wartości OSS zależy przesunięcie wyniku w prawo aż o
> 8 bitów! Zła wartość OSS będzie bardzo silnie wpływać na wynik.
Z datasheeta:
https://www.sparkfun.com/datasheets/Components/Gener
al/BST-BMP085-DS000-05.pdf
wynika że cyfryzacja ciśnienia może działać na dokładności 16-19 bitów.
Na stronie 18 jest przykład 16 bitowy, dwa bajty danych, sprawdź czy tak
jest ustawiony.
p.s. latasz na lotni czy szybowcach? ;-)
-
4. Data: 2014-04-23 23:51:37
Temat: Re: Działająca biblioteka do BMP085
Od: Atlantis <m...@w...pl>
Hmm... Dziwna sprawa. Sądziłem, że winę za taki stan rzeczy ponosi błąd
w bibliotece. Jednak trafiłem na inną służącą do obsługi BMP085.
http://davidegironi.blogspot.com/2012/10/avr-atmega-
bmp085-pressure-sensor.html#.U1g0nFdpNIJ
Po podmienieniu plików, dostosowaniu źródeł i wgraniu hex-a okazało się,
że efekt nie zniknął. Ciągle otrzymuję dziwną wartość ciśnienia.
Prawdopodobieństwo wystąpienia tego samego błędu w dwóch różnych
bibliotekach jest niewielkie, więc należy założyć, że błąd tkwi w innym
miejscu.
W chwili obecnej procedura wysyłania wyniku wygląda w sposób następujący:
char result[10];
int32_t pressure = bmp085_getpressure();
itoa(pressure, result, 10);
strcpy_P(pAnswer, PSTR("+PRESS: "));
strcat(pAnswer, result);
strcat_P(pAnswer, PSTR("\r\n"));
Wskaźnik do bufora pAnswer jest następnie przekazywany do funkcji
zajmującej się wysyłaniem odpowiedzi na zapytania UDP.
Próbowałem także zastosować stdio:
printf_P(pAnswer, PSTR("+PRESS: %d\r\n"), bmp085_getpressure());
Efekt był dokładnie taki sam.
Ktoś ma jakiś pomysł gdzie mogę zacząć szukać przyczyny, co jeszcze
ewentualnie mogę sprawdzić?
-
5. Data: 2014-04-24 01:06:10
Temat: Re: Działająca biblioteka do BMP085
Od: "Grzegorz Niemirowski" <g...@p...onet.pl>
Atlantis <m...@w...pl> napisał(a):
> Hmm... Dziwna sprawa. Sądziłem, że winę za taki stan rzeczy ponosi błąd
> w bibliotece. Jednak trafiłem na inną służącą do obsługi BMP085.
> http://davidegironi.blogspot.com/2012/10/avr-atmega-
bmp085-pressure-sensor
> .html#.U1g0nFdpNIJ
> Po podmienieniu plików, dostosowaniu źródeł i wgraniu hex-a okazało się,
> że efekt nie zniknął. Ciągle otrzymuję dziwną wartość ciśnienia.
> Prawdopodobieństwo wystąpienia tego samego błędu w dwóch różnych
> bibliotekach jest niewielkie, więc należy założyć, że błąd tkwi w innym
> miejscu.
> W chwili obecnej procedura wysyłania wyniku wygląda w sposób następujący:
> char result[10];
> int32_t pressure = bmp085_getpressure();
> itoa(pressure, result, 10);
> strcpy_P(pAnswer, PSTR("+PRESS: "));
> strcat(pAnswer, result);
> strcat_P(pAnswer, PSTR("\r\n"));
> Wskaźnik do bufora pAnswer jest następnie przekazywany do funkcji
> zajmującej się wysyłaniem odpowiedzi na zapytania UDP.
> Próbowałem także zastosować stdio:
> printf_P(pAnswer, PSTR("+PRESS: %d\r\n"), bmp085_getpressure());
> Efekt był dokładnie taki sam.
> Ktoś ma jakiś pomysł gdzie mogę zacząć szukać przyczyny, co jeszcze
> ewentualnie mogę sprawdzić?
Zacząłbym od zignorowania bibliotek nietrzymających się dokumentacji BMP085.
A ta mówi, żeby odczytać trzy bajty: najstarszy MSB, młodszy LSB i
najmłodszy XLSB. Są to rejestry F6, F7 i F8. Te bajty są składane w inta, a
potem całość przesuwana jest w prawo o 8-oss, gdzie oss oznacza
over-sampling setting. W ten sposób otrzymujemy nieskompensowaną
temperaturę. Następnie wykonywane są obliczenia kompensacyjne.
A jaki mikrokontroler? Ma JTAG? Jak ma to użyj, bo kombinujesz strasznie
zamiast użyć debuggera. Jak nie ma JTAGa, to użyj czegoś innego, np. portu
szeregowego. Sprawdź jakie wartości masz odczytane w MSB, LSB i XLSB.
Następnie zobacz co robi z nimi kod kompensacyjny. Na oko wygląda dobrze,
ale może gdzieś jest pomieszane signed i unsigned. Prześledź działanie kodu
w trakcie działania. Wrzucając hexy i patrząc na końcowy wynik będzie Ci
bardzo trudno ustalić co się dzieje. Pomóc Ci też jest trudno, jeśli nie
podajesz odczytanych wartości MSB, LSB i XLSB. Ja niestety nie posiadam
BMP085 i nie porównam ze swoim, ale jakbyś podał wartości, to myślę, że
byłoby łatwiej. Mógłbym np. odpalić sobie biblioteki z danymi z Twojego
czujnika. Poza tym wkleiłeś bardzo krótkie fragmenty kodu, np. nie wiadomo
jak Arduino liczy kompensację. Czy też dzielenie robi przesunięciem bitowym?
A może robi normalne dzielenie? Bo to nie jest to samo: patrz przesuwanie
bitów w liczbach ujemnych. I jeszcze jedno: o ile dobrze rozumiem, to żeby
prawidłowo obliczyć ciśnienie, musisz mieć zmierzoną najpierw temperaturę.
Mierzysz ją?
--
Grzegorz Niemirowski
http://www.grzegorz.net/
OE PowerTool i Outlook Express: http://www.grzegorz.net/oe/
Uptime: 12 days, 22 hours, 55 minutes and 19 seconds
-
6. Data: 2014-04-24 01:31:48
Temat: Re: Działająca biblioteka do BMP085
Od: "Pszemol" <P...@P...com>
"Atlantis" <m...@w...pl> wrote in message
news:lj9clo$e2i$1@portraits.wsisiz.edu.pl...
> Ktoś ma jakiś pomysł gdzie mogę zacząć szukać przyczyny,
> co jeszcze ewentualnie mogę sprawdzić?
Wcześniej pisałeś że masz wynik około 300hPa...
Może zamiast 1000hPa czytasz coś jak 344hPa?
Jeśli tak, to stawiam hipotezę, że obcinasz górny bajt
z trzy-bajtowego wyniku...
1000hPa to 100000Pa, czyli w bajtach 0x01 0x86 0xA0.
Jeśli weźmiesz pod uwagę że Twój kod mógł skrócić
long'a do int'a i zamiast 0x186A0 dostaniesz 0x86A0
to uzyskasz wynik 34464, czyli 344,64hPa...
Poszukaj więc w swym kodzie miejsc, gdzie używasz
funkcji oczekującej argumentu typu int (2 bajty) i tam
posyłasz argument typu long (4 bajty) który zostaje przez
kompilator ucięty do oczekiwanych przez funkcję 2 bajtów.
Podejrzewałbym następujące linie Twojego kodu:
1) itoa(pressure, result, 10);
Prototyp funkcji:
char * itoa ( int value, char * str, int base );
Funkcja oczekuje int'a, posyłasz jej argument typu int32.
Bad boy! :-)
2) printf_P(pAnswer, PSTR("+PRESS: %d\r\n"), bmp085_getpressure());
Funkcja printf dekodując format %d szuka na stosie wartości
typu int, co ma dwa bajty a Ty podajesz wartość 4-bajtową.
Zamień ten format %d na %ld, czyli zapisz tą linię tak:
printf_P(pAnswer, PSTR("+PRESS: %ld\r\n"), bmp085_getpressure());
http://www.cplusplus.com/reference/cstdio/printf/
-
7. Data: 2014-04-24 01:34:07
Temat: Re: Działająca biblioteka do BMP085
Od: "Pszemol" <P...@P...com>
"Grzegorz Niemirowski" <g...@p...onet.pl> wrote in message
news:lj9h2d$sl2$1@node1.news.atman.pl...
> ale jakbyś podał wartości, to myślę, że byłoby łatwiej.
Podał przecież... Cytuję:
"że wartość ciśnienia jest nieprawidłowa - wychodzi jakieś 300 HPa..."
-
8. Data: 2014-04-24 10:32:56
Temat: Re: Działająca biblioteka do BMP085
Od: Elektrolot <e...@N...pl>
W dniu 2014-04-23 19:10, Atlantis pisze:
> Próbuję właśnie uruchomić BMP085 w jednym ze swoich urządzeń i powoli
> zaczynam z tego powodu siwieć. ;)
Na tej stronie też jest przykładowy soft do obsługi BMP085:
https://www.olimex.com/Products/Modules/Sensors/MOD-
BMP085/open-source-hardware
-
9. Data: 2014-04-24 16:26:45
Temat: Re: Działająca biblioteka do BMP085
Od: Atlantis <m...@w...pl>
W dniu 2014-04-24 01:31, Pszemol pisze:
> Podejrzewałbym następujące linie Twojego kodu:
>
> 1) itoa(pressure, result, 10);
Dokładnie, ta diagnoza okazała się być poprawną. Najpierw nie
zauważyłem, że itoa() przyjmuje short inta, a potem przeoczyłem literkę
"l" w tokenie obsługującym przesyłaną wartość w sprintf_P. Zaowocowało
to takim samym błędem.
Teraz wszystko działa, otrzymuję ciśnienie o prawdopodobnej wartości.
Jeśli chodzi o temperaturę, to zastosowana biblioteka zwraca ją jako
double. Myślę, że nie będę się już bawił w jej przerabianie, zresztą
miło byłoby, gdyby wynik był zwracany w normalnych jednostkach, a nie
0,1 stopnia C.
Włączanie operacji zmiennoprzecinkowych w stdio.h raczej nie chodzi w
grę. Nie dosyć, że kod od tego tyje, to jeszcze zużywane są cykle procesora.
Dobrze pamiętam tę sztuczkę?
double temperature = bmp085_gettemperature();
int16_t intpart = (int16_t)temperature;
int16_t decpart = ((int16_t)(temperature*2)%2);
sprintf_P(pAnswer, PSTR("+TEMP: %d.%d\r\n"), intpart, decpart);
-
10. Data: 2014-04-24 17:13:01
Temat: Re: Działająca biblioteka do BMP085
Od: Atlantis <m...@w...pl>
W dniu 2014-04-24 16:26, Atlantis pisze:
> int16_t decpart = ((int16_t)(temperature*2)%2);
Tfu! Tutaj oczywiście nie chodziło mi o liczbę miejsc po przecinku
wpisywaną w formie wartości bezwzględnej, ale jako mnożnik. Czyli 10,
100, 1000 itp.