Wpis z mikrobloga

Mirko, mam problem z odczytami z akcelerometru, nie mam pojęcia dlaczego mi się wszystko rozjeżdża.

Otóż mam scalaka MPU-9150 z m.in 3-osiowym 16-bitowym akcelerometrem. Wynik pomiaru przyspieszenia zapisywany jest do dwóch rejestrów, w pierwszym są bity 15..8 a w drugim 7..0.

Odczyt za pomocą I2C i wysłanie na UART robię tak:

TWI_read_buf(MPU9150_ADDR, 0x3B, 2, read);
uart_putc(read[0]);
uart_putc(read[1]);

Następnie odbieram sobie dane w Javie i modyfikuję w taki sposób:

int byte1 = buffer[firstSampleIndex + 1];
int byte2 = buffer[firstSampleIndex + 2];


byte1 *= 256;
byte2 += 128;

Wartości byte1 i byte2 wyrzucam na wyjście, a po umieszczeniu w Excelu wygląda to tak:

http://i.imgur.com/UstOK2E.png

Niebieski wykres to najbardziej znaczące bity, zielony - mniej znaczące.

Jak mniej więcej widać, wartość najmniej znaczących bitów powinna się nałożyć w czasie tak, aby ich narastanie odbywało się w czasie pomiędzy skokami wynikającymi ze zmiany najbardziej znaczących bitów. A jest na wykresie - po złożeniu wygląda to bardzo dziwnie (poniższe zdjęcie jest dla innych danych, ale widać problem):

http://i.imgur.com/Rp1JCiZ.png

(ta czarna kreska przecinająca sygnał została dorysowana przeze mnie w Paincie)

Macie może pomysł, co z tym zrobić, jak to ugryźć? Z czego to może wynikać?

Zaczynam pewien projekt na koło naukowe i ugrzązłem na czymś takim.. :s

Link do arkuszu w Excelu jak by ktoś chciał:

https://www.dropbox.com/s/6haocp4if27wo26/Akcelerometr_1.xlsx?dl=0

Jak jest potrzeba, to mogę dostarczyć inne dane z akcelerometru. Proszę o pomoc :)

#elektronika #avr #mikrokontrolery #programowanie #sygnaly #teoriasygnalow #przetwarzaniesygnalow #czujniki
Visher - Mirko, mam problem z odczytami z akcelerometru, nie mam pojęcia dlaczego mi ...

źródło: comment_GGxNDS2xwN7OBrNOTEA6YX1nfnlNy3Lm.jpg

Pobierz
  • 31
@Visher: tradycyjna powinno być typu uint8t, po odebraniu jeszcze w procku składasz to przesuwając w lewo msb i zapisując do do int16t . Coś w ten deseń powinno zadziałać. Albo przesylasz oba bajty i na kompie to robisz.
@Tymian: ale ja wiem jak to się składa. Przesyłam osobno, bo i tak do przesłania po uarcie wygodnie mi osobno. Złożyć na kompie umiem i złożyłem, tylko że składanie takich danych nie daje nic sensownego.
@Tymian: to znaczy, że jak od razu przeliczyć na przyspieszenie? Funkcją TWIreadbuf odczytuję dwa bajty z dwóch kolejnych rejestrów, pierwszy bajt jest pod adresem 0x3B, drugi pod 0x3C
@Visher: pokaż jak to składasz bo nic nie rozumiem z tego co tu robisz. Tym bardziej po co analizujesz osobno składowe jednej liczby? Masz wynik z przedziału 0-65k i co właściwie Ci mówi dolny bajt? #!$%@?, nawet za 1% wyniku on nie odpowiada.
@andzej74: składanie tych dwóch bajtów wygląda tak:

int byte1 = buffer[firstSampleIndex + 1];
int byte2 = buffer[firstSampleIndex + 2];


byte1 *= 256;
byte2 += 128;
``````
int readValue = byte1 + byte2;

Najpierw rzutuję sobie na inta, bo byte jest od -128 do 127. byte1 mnożę przez 256, czyli odpowiada to przesunięciu o 8 bitów w lewo. A do byte2 dodaję 128 żeby mieć wynik od 0 do 255 a nie od -128 do 127.

I sumuję. I wychodzi taki ślaczek jak tutaj na wykresie (to takie góra dół):

http://i.imgur.com/Rp1JCiZ.png
@Visher: jeśli wyswietlasz osobno zawartość każdego rejestru a akcelerometr dupa cicho, nie rusza się to cały czas powinieneś mieć prawie to samo z ewentualnym szumem. Miarodajne będzie jak przeliczysz to na przyspieszenie (łatwo się interpretuje) albo wyswietlisz 16bitową zawartość rejestru - ilość zaliczeń akcelerometru
@Visher: pokazałeś jakiś dziki rysunek, który tylko Ty rozumiesz i analizujesz bajty jednej liczby. Tego się tak nie robi. Wynik pomiaru to dwa bajty i tak na niego patrz. Jak założę, że niebieski wykres to bardziej znaczący bajt to najpierw przyspieszyles a potem zwolniles. Tak było?
@Tymian:
i tak jest, jak leży w miejscu to widać szum.

@andzej74:
To co widać na wykresie pojawia się jak obracam akcelerometrem tak aby jedna z osi (ta wyświetlana) pokryła się z kierunkiem przyspieszenia ziemskiego a później wracam do początku.
Analizowałem całe złożenie, ale kiepsko to wyglądało, więc wróciłem do poziomu dwóch bajtów i widzę tu problem.
@Tymian: może w takim razie coś źle rozumiem jak działa akcelerometr - ja mam dane w rejestrach jeszcze przeliczać na przyspieszenie?

W nocie katalogowej mam:
rejestr 1: ACCELXOUT[15:8]
rejestr 2: ACCEL
XOUT[7:0]

i opis:
These registers store the most recent accelerometer measurements.
Accelerometer measurements are written to these registers at the Sample Rate as defined in
Register 25.

interpretuję to jako gotowe przyspieszenie.
@Visher: To jest kod dla 14bitowego akcelerometru z mojego starego programu:
volatile uint8t x[6];
error=I2C1
RecvBlock(&x, 6U, &snt); //do x zapisuje wsp. x y z po 2 bajty.
I2C1SendStop();

int16
t new1=((short)(x[0]<<8)|(x[1]))>>4;
int16t new2=((short)(x[2]<<8)|(x[3]))>>4;
int16
t new3=((short)(x[4]<<8)|(x[5]))>>4;

xyz[0]=new1;
xyz[1]=new2;
xyz[2]=new3;

////// potem gdzies w czelusciach programu przeliczenie na m/s^2

float Xg = ((float) xyz[0]) / SENSITIVITY2G;
float Yg = ((float) xyz[1]) / SENSITIVITY2G;
float
rejestr 1: ACCELXOUT[15:8]

rejestr 2: ACCELXOUT[7:0]


@Visher: I dokładnie tak to masz interpretować, rej2 jest młodszym bajtem wartości, a rej1 starszym. Cała wartość ma postać ((uint16)rej1)*256 + rej2.

A ty dodajesz jakieś dzikie 128 do młodszego bajtu, czyli przesuwasz go na dzień dobry o połowę w górę. I dokładnie to widać na wykresie (to, co ci nie pasuje - przesunięcie).
@Visher: Czytałeś Ty chłopie datasheet tego akcelerometru? Jeśli nie to (przepraszam za to) to walnij dyńką w ścianę aż zostanie dziura. Czytanie ze zrozumieniem to podstawa zabawy z elektroniką.
Siadasz, czytasz, robisz, jeszcze raz czytasz, robisz, , DZIAŁA
żeby mieć wynik od 0 do 255 a nie od -128 do 127


@Visher: To, że odczytujesz bajt i umieszczasz go w zmiennej o typie "int" nie oznacza, że będzie ona miała wartość od -128 do 127. Będzie ona miała wartość dokładnie taką, jaką ma odczytany bajt, czyli z zakresu 0 .. 255.
@pytonger: @Tymian: @andzej74:
fajnie że się wyżyliście.

Zapomniałem o jednej rzeczy, tu mój błąd. Zapomniałem dopisać, że przestawiłem akcelerometr na mniejszą czułość - większy zakres pomiarowy.

Bo problemu ze złożeniem przy podstawowym zakresie pomiarowym to nie miałem, może już nawet przez ten czas zapomniałem o tym. Dwa dni temu napisałem:
int readValue = (byte1<<8) + byte2;

i to działało, ale po przestawieniu na większy zakres pomiarowy pojawia się problem