eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › Działająca biblioteka do BMP085
Ilość wypowiedzi w tym wątku: 28

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

strony : [ 1 ] . 2 . 3


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: