PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LSM303DLH 3D Compass and accelerometer Umrechnungsporblem



robonooby
27.12.2012, 16:49
Hallo
ich habe mich seit heute früh an den LSM303DLH Magnetfeld- und Beschleunigungssensor (http://www.pololu.com/file/0J433/LSM303DLH.pdf) rangesetzt.
Ich bin soweit gekommen, dass ich alle Werte für Beschleunigung und Magnetfeld via I2C Bus aus dem Sensor bekomme (diese verändern sich auch entsprechend der Bewegung).
Jetzt hab ich allerdings noch nen kleines Verständnisproblem bei der Umrechnung in brauchbare Werte (Grad und Beschleunigung).

In der Dokumentation (http://www.pololu.com/file/0J434/LSM303DLH-compass-app-note.pdf)steht:

MR_Data[0] = ReadCurrentAddress(); //read OUT_X_H_M (MSB)
MR_Data[1] = ReadCurrentAddress(); //read OUT_X_L_M (LSB)
MR_Data[2] = ReadCurrentAddress(); //read OUT_Y_H_M (MSB)
MR_Data[3] = ReadCurrentAddress(); //read OUT_Y_L_M (LSB)
MR_Data[4] = ReadCurrentAddress();//read OUT_Z_H_M (MSB)
MR_Data[5] = ReadCurrentAddress(); //read OUT_Z_L_M (LSB)
Mx = (int) (MR_Data[0] << 8) + MR_Data[1];
My = (int) (MR_Data[2] << 8) + MR_Data[3];
Mz = (int) (MR_Data[4] << 8) + MR_Data[5];

Aber wie übertrage ich dies auf Bascom befehle. Also die letzten 3 Zeilen. Was bedeutet dieses << und wieso wird da dann die andere MR_Data[] hinzuaddiert.

Ich hab jetzt hier noch nen anderes Beispiel zur Programmierung vom Beschleunigungssensor (https://www.roboternetz.de/community/threads/54445-3D-Beschleunigungssensor-LSM303DLH-auslesen?highlight=LSM303DLH) gefunden, aber ich kann hier keinen Zusammenhang zwischen dem im Datenblatt stehenden Beispiel und der Version von diesem Threat (https://www.roboternetz.de/community/threads/54445-3D-Beschleunigungssensor-LSM303DLH-auslesen?highlight=LSM303DLH)erkennen.
Auch wenn die Werte aus dem Threat sehr plausibel erscheinen.

Ich bekomm folgende Daten aus dem Sensor: (Beispiel Beschleunigung in x Richtung, Sensor liegt dabei irgendwie auf dem Tisch)


Messung
OUT_X_L_A
OUT_X_H_A
Umgerechnet in Beschleunigung aus anderem Threat


1
01100000
00011001
0.40 g


2
10000000
00011001
0.40 g


3
01100000
00011001
0.40 g



Ich versteh auch nicht wie sich das X_L_A und X_H_A zusammensetz. Beides ist ja wohl für den X Wert zuständig.

Ich hoff mir kann da jemand helfen.


Hier mal mein Code, falls ihr den benötigt:


'Microcontroller Einstellungen Definieren.
$lib "lcd_i2c.lib"
$regfile = "m32def.dat"
$framesize = 60 '32
$swstack = 60 ' 32
$hwstack = 60 '32
$crystal = 16000000
$baud = 9600

'Funktionen für Sensor:
Declare Sub Lsm303_init()
Declare Sub Acc_writereg(byval Breg As Byte , Byval Bval As Byte)
Declare Sub Acc_readsensordata() '-> iAx, iAy, iAz
Declare Sub Acc_calcgvalues() '-> sGx, sGy, sGz
Declare Sub Magnet_writerega(byval Dreg As Byte , Byval Dval As Byte)
Declare Sub Magnet_writeregb(byval Ereg As Byte , Byval Eval As Byte)
Declare Sub Magnet_writeregm(byval Mreg As Byte , Byval Mval As Byte)
Declare Sub Magnet_readsensordata()
Declare Sub Magnet_calcmvalues()

'Variablen für Beschleunigungs Sensor:
Const Acc_w_addr = &H30
Const Acc_r_addr = &H31

Const Ctrl_reg1_a = &H20
Const Ctrl_reg4_a = &H23

Const Out_x_l_a = &H28
Const Out_x_h_a = &H29
Const Out_y_l_a = &H2A
Const Out_y_h_a = &H2B
Const Out_z_l_a = &H2C
Const Out_z_h_a = &H2D

'Variablen für Magnetfeld Sensor :
Const Magnet_w_addr = &H3C
Const Magnet_r_addr = &H3D

Const Cra_reg_m = &H00
Const Crb_reg_m = &H01
Const Mr_reg_m = &H02

Const Out_x_h_m = &H03 ' Magnetfeld
Const Out_x_l_m = &H04
Const Out_y_h_m = &H05
Const Out_y_l_m = &H06
Const Out_z_h_m = &H07
Const Out_z_l_m = &H08

Const Res_2g = 0.0009765625 'Auflösung bei +- 2g

Dim Abaccdata(6) As Byte
Dim Abmagdata(6) As Byte

Dim Iax As Integer At Abaccdata(1) Overlay
Dim Iay As Integer At Abaccdata(3) Overlay
Dim Iaz As Integer At Abaccdata(5) Overlay

Dim Imx As Integer At Abmagdata(1) Overlay
Dim Imy As Integer At Abmagdata(3) Overlay
Dim Imz As Integer At Abmagdata(5) Overlay

Dim Sgx As Single 'Beschleunigungsvariablen
Dim Sgy As Single
Dim Sgz As Single

Dim Magnetx As Single 'Magnetfeldvariablen
Dim Magnety As Single
Dim Magnetz As Single

'****************************I2C##**************** **
Config Scl = Portc.0 'I2C SCL Pin
Config Sda = Portc.1 'I2C SDA Pin
Config I2cdelay = 20 '200 'I2C Bus Geschwindigkeit
I2cinit

Print "LSM303DLH Beschleunigungssensor und Magnometer"
Lsm303_init

Wait 2

Acc_readsensordata
Acc_calcgvalues

Magnet_readsensordata
Magnet_calcmvalues

Print "Beschleunigung: X: " ; Fusing(sgx , "#.##") ; " Y: " ; Fusing(sgy , "#.##") ; " Z: " ; Fusing(sgz , "#.##") 'Aus anderem Threat übernommen
Print "Magnetfeld: X: " ; Fusing(magnetx , "#.##") ; " Y: " ; Fusing(magnety , "#.##") ; " Z: " ; Fusing(magnetz , "#.##") 'Aus anderem Threat übernommen


Waitms 500
Loop
End

'LSM303DLH Sensor auslesen (Funktionen)
Sub Lsm303_init() 'Einstellungen definieren
Acc_writereg Ctrl_reg1_a , &H27 'normal power mode, 50 Hz data rate, all axes enabled
Magnet_writerega Cra_reg_m , &H14 'Output Rate 30Hz , Normal measurement configuration
Magnet_writeregb Crb_reg_m , &H20 'Gain setting 1,3 Gauss
Magnet_writeregm Mr_reg_m , &H00 ' magnetic sensor into continuous mode
End Sub

Sub Acc_writereg(byval Breg As Byte , Byval Bval As Byte) 'Einstellungen für Beschleunigung
I2cstart
I2cwbyte Acc_w_addr
I2cwbyte Breg
I2cwbyte Bval
I2cstop
End Sub

Sub Magnet_writerega(byval Dreg As Byte , Byval Dval As Byte) ' 1. Einstellungen für Magnet
I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Dreg
I2cwbyte Dval
End Sub

Sub Magnet_writeregb(byval Ereg As Byte , Byval Eval As Byte) ' 2. Einstellungen für Magnet
I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Ereg
I2cwbyte Eval
End Sub

Sub Magnet_writeregm(byval Mreg As Byte , Byval Mval As Byte) '3. Einstellung für Magnet
I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Mreg
I2cwbyte Mval
End Sub

Sub Acc_readsensordata()
I2cstart
I2cwbyte Acc_w_addr
I2cwbyte &HA8
I2cstart
I2cwbyte Acc_r_addr
I2crbyte Abaccdata(1) , Ack
I2crbyte Abaccdata(2) , Ack
I2crbyte Abaccdata(3) , Ack
I2crbyte Abaccdata(4) , Ack
I2crbyte Abaccdata(5) , Ack
I2crbyte Abaccdata(6) , Nack
I2cstop

Print "xxxx " ; Bin(abaccdata(1)) ; " xx " ; Bin(abaccdata(2))

Shift Iax , Right , 4 , Signed 'Aus anderem Threat übernommen
Shift Iay , Right , 4 , Signed 'Aus anderem Threat übernommen
Shift Iaz , Right , 4 , Signed 'Aus anderem Threat übernommen
End Sub

Sub Acc_calcgvalues()
Sgx = Iax * Res_2g 'Aus anderem Threat übernommen
Sgy = Iay * Res_2g 'Aus anderem Threat übernommen
Sgz = Iaz * Res_2g 'Aus anderem Threat übernommen
End Sub

Sub Magnet_readsensordata()
Dim Temp As Byte

I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Out_x_h_m
I2cstart
I2cwbyte Magnet_r_addr

I2crbyte Abmagdata(1) , Ack
I2crbyte Abmagdata(2) , Ack
I2crbyte Abmagdata(3) , Ack
I2crbyte Abmagdata(4) , Ack
I2crbyte Abmagdata(5) , Ack
I2crbyte Abmagdata(6) , Nack
I2cstop

End Sub

Sub Magnet_calcmvalues()
Magnetx = Imx
Magnety = Imy
Magnetz = Imz
End Sub

Dirk
29.12.2012, 18:47
Also, "<<8" kannst du in Bascom mit "* 256" umsetzen.
Grund: Der X-Wert ist z.B. der MSB-Wert * 256 plus LSB-Wert.

robonooby
30.12.2012, 12:33
ahh okey. danke dir.
dann kann hier dann weiter machen^^

robonooby
29.04.2013, 16:19
Hallo
ich will das Thema nochmal aufgreifen. hab jetzt nach langer Zeit wieder zeit für mein Projekt gefunden.
Leider komm ich nicht so richtig vorran. Hab schon das Handbuch gewälzt aber komm einfach net weiter, daher hoffe ich, dass ihr mir helfen könnt.

Und zwar bekomm ich keine sinnvollen Werte aus dem Sensor raus. Beschleunigung geht, aber nur wenn ich das nicht direkt nach Handbuch mache.
Magnetkompass bekomm ich gar nicht hin....

hier erstmal mein Code (direkt nach Handbuch):

'LSM303DLH Sensor auslesen (Funktionen)
'Einstellungen:
Sub Lsm303_init() 'Einstellungen definieren
Acc_writereg Ctrl_reg1_a , &H27 'normal power mode, 50 Hz data rate, all axes enabled
Magnet_writerega Cra_reg_m , &H14 'Output Rate 30Hz , Normal measurement configuration
Magnet_writeregb Crb_reg_m , &H20 'Gain setting 1,3 Gauss
Magnet_writeregm Mr_reg_m , &H00 ' magnetic sensor into continuous mode
End Sub

Sub Acc_writereg(byval Breg As Byte , Byval Bval As Byte) 'Einstellungen für Beschleunigung
I2cstart
I2cwbyte Acc_w_addr
I2cwbyte Breg
I2cwbyte Bval
I2cstop
End Sub

Sub Magnet_writerega(byval Dreg As Byte , Byval Dval As Byte) ' 1. Einstellungen für Magnet
I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Dreg
I2cwbyte Dval
End Sub

Sub Magnet_writeregb(byval Ereg As Byte , Byval Eval As Byte) ' 2. Einstellungen für Magnet
I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Ereg
I2cwbyte Eval
End Sub

Sub Magnet_writeregm(byval Mreg As Byte , Byval Mval As Byte) '3. Einstellung für Magnet
I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Mreg
I2cwbyte Mval
End Sub



'Auslesen der Daten und Auswertung:
Sub Acc_readsensordata() 'Beschleunigungssensor auslesen
I2cstart 'ST
I2cwbyte Acc_w_addr 'SAD + W
I2cwbyte &HA8 'SUB = OUT_X_L_A, SUB(7) = 1
I2cstart 'SR
I2cwbyte Acc_r_addr 'SAD + R
I2crbyte Abaccdata(1) , Ack
I2crbyte Abaccdata(2) , Ack
I2crbyte Abaccdata(3) , Ack
I2crbyte Abaccdata(4) , Ack
I2crbyte Abaccdata(5) , Ack
I2crbyte Abaccdata(6) , Nack
I2cstop

Shift Iax , Right , 4 , Signed
Shift Iay , Right , 4 , Signed
Shift Iaz , Right , 4 , Signed

Sgx = Iax
Sgy = Iay
Sgz = Iaz

Iax = Abaccdata(1)
Shift Iax , Left , 8 , Signed
Iax = Iax + Abaccdata(2)

Iay = Abaccdata(3)
Shift Iay , Left , 8 , Signed
Iay = Iay + Abaccdata(4)

Iaz = Abaccdata(5)
Shift Iaz , Left , 8 , Signed
Imz = Iaz + Abaccdata(6)
End Sub

Sub Acc_calcgvalues() 'ausgelesene Beschleunigungswerte Auswerten
'Sgx = Sgx * Res_2g
'Sgy = Sgy * Res_2g
'Sgz = Sgz * Res_2g

Hilfsvariable1 = Acckorrektur(1) * Iax 'Norminalisierung mit Korrekturwerten X Richtung (Formel 3 Siehe Bild)
Hilfsvariable2 = Acckorrektur(2) * Iay
Hilfsvariable3 = Acckorrektur(3) * Iaz
Hilfsvariable = Hilfsvariable1 + Hilfsvariable2
Hilfsvariable = Hilfsvariable + Hilfsvariable3
Sgx = Hilfsvariable + Acckorrektur(4)

Hilfsvariable1 = Acckorrektur(5) * Iax 'Norminalisierung mit Korrekturwerten Y Richtung
Hilfsvariable2 = Acckorrektur(6) * Iay
Hilfsvariable3 = Acckorrektur(7) * Iaz
Hilfsvariable = Hilfsvariable1 + Hilfsvariable2
Hilfsvariable = Hilfsvariable + Hilfsvariable3
Sgy = Hilfsvariable + Acckorrektur(8)

Hilfsvariable1 = Acckorrektur(9) * Iax 'Norminalisierung mit Korrekturwerten Z Richtung
Hilfsvariable2 = Acckorrektur(10) * Iay
Hilfsvariable3 = Acckorrektur(11) * Iaz
Hilfsvariable = Hilfsvariable1 + Hilfsvariable2
Hilfsvariable = Hilfsvariable + Hilfsvariable3
Sgz = Hilfsvariable + Acckorrektur(12)

Pitch = -asin(sgx) '(Formel 10 Siehe Bild)
Hilfsvariable = Cos(pitch)
Hilfsvariable = Sgy / Hilfsvariable
Roll = Asin(hilfsvariable)
End Sub

Sub Magnet_readsensordata() 'Magnetsensordaten auslesen
Dim Temp As Byte

I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Out_x_h_m
I2cstart
I2cwbyte Magnet_r_addr

'I2cwbyte Magnet_w_addr
'I2cwbyte Mr_reg_m

I2crbyte Abmagdata(1) , Ack
I2crbyte Abmagdata(2) , Ack
I2crbyte Abmagdata(3) , Ack
I2crbyte Abmagdata(4) , Ack
I2crbyte Abmagdata(5) , Ack
I2crbyte Abmagdata(6) , Nack
I2cstop


Imx = Abaccdata(1)
Shift Imx , Left , 8 , Signed
Imx = Imx + Abaccdata(2)

Imy = Abaccdata(3)
Shift Imy , Left , 8 , Signed
Imy = Imy + Abaccdata(4)

Imz = Abaccdata(5)
Shift Imz , Left , 8 , Signed
Imz = Imz + Abaccdata(6)

End Sub

Sub Magnet_calcmvalues() 'ausgelesene Magnetsensorwerte Auswerten
Dim Xh As Single
Dim Yh As Single
Dim Zh As Single

Imx = Imx - Magkorrektur(4)
Imy = Imy - Magkorrektur(8)
Imz = Imz - Magkorrektur(12)

Hilfsvariable1 = Magkorrektur(1) * Imx 'Norminalisierung mit Korrekturwerten X Richtung (Formel 4 Siehe Bild)
Hilfsvariable2 = Magkorrektur(2) * Imy
Hilfsvariable3 = Magkorrektur(3) * Imz
Hilfsvariable = Hilfsvariable1 + Hilfsvariable2
Magnetx = Hilfsvariable + Hilfsvariable3

Hilfsvariable1 = Magkorrektur(5) * Imx 'Norminalisierung mit Korrekturwerten Y Richtung
Hilfsvariable2 = Magkorrektur(6) * Imy
Hilfsvariable3 = Magkorrektur(7) * Imz
Hilfsvariable = Hilfsvariable1 + Hilfsvariable2
Magnety = Hilfsvariable + Hilfsvariable3

Hilfsvariable1 = Magkorrektur(8) * Imx 'Norminalisierung mit Korrekturwerten Z Richtung
Hilfsvariable2 = Magkorrektur(10) * Imy
Hilfsvariable3 = Magkorrektur(11) * Imz
Hilfsvariable = Hilfsvariable1 + Hilfsvariable2
Magnetz = Hilfsvariable + Hilfsvariable3


Hilfsvariable1 = Magnetx * Cos(pitch) 'X-Wert ausrechnen (Formel 12 Siehe Bild)
Hilfsvariable2 = Magnetz * Sin(pitch)
Xh = Hilfsvariable1 + Hilfsvariable2

Hilfsvariable1 = Magnetx * Sin(pitch) 'Y-Wert ausrechnen
Hilfsvariable1 = Hilfsvariable1 * Sin(roll)
Hilfsvariable2 = Magnety * Cos(roll)
Hilfsvariable3 = Magnetz * Sin(roll)
Hilfsvariable3 = Hilfsvariable3 * Cos(pitch)
Yh = Hilfsvariable1 + Hilfsvariable2
Yh = Yh - Hilfsvariable3

Hilfsvariable1 = Magnetx * Cos(roll) 'Z-Wert ausrechnen
Hilfsvariable1 = Hilfsvariable1 * Sin(pitch)
Hilfsvariable2 = Magnety * Sin(roll)
Hilfsvariable3 = Magnetz * Cos(roll)
Hilfsvariable3 = Hilfsvariable3 * Cos(pitch)
Zh = Hilfsvariable2 - Hilfsvariable1
Zh = Zh + Hilfsvariable3

Richtung = Yh / Xh 'Richtung in Grad bestimmen (Formel 13 Siehe Bild)
Richtung = Atn(richtung)
Richtung = Rad2deg(richtung)

If Xh > 0 And Yh >= 0 Then 'schauen in welchem Quadranten der Wert liegt (wegen Tangens) (Formel 13 Siehe Bild)
Richtung = Richtung
End If

If Xh < 0 Then
Richtung = 180 + Richtung
End If
If Xh > 0 And Yh <= 0 Then
Richtung = 360 + Richtung
End If
If Xh = 0 And Yh < 0 Then
Richtung = 90 + Richtung
End If
If Xh = 0 And Yh > 0 Then
Richtung = 270 + Richtung
End If

End Sub



Mein Problem:
Es ändern sich die Werte ständig obwohl der Sensor einfach nur fest montiert ist und sich nicht bewegt. Und ich weis nicht warum.
Wenn ich den Sensor um z.B. 90 Grad drehe dann bleiben die Werte immer noch so in dem Bereich. Am Winkel und Pitch ändert sich auch so gut wie nichts...
Hoffe da kann mir jemand weiterhelfen. Wenn das läuft würd ich dann auch mal nen Tutorial hierzu ins Wiki stellen wollen.

Anbei ein paar Messdaten. (erste zwei Messungen stehender Sensor, andere Messungen Sensor in Bewegung)
Messung 1:

Beschleunigung: X: -4626.00 Y: -4626.00 Z: -4626.00
Magnetfeld: X: -4119.00 Y: -4119.00 Z: -4119.00
Pitch: 1.570796366 Roll: 1.570796366
Richtung: 224.999618528

Messung 2:

Beschleunigung: X: -5654.00 Y: -5654.00 Z: -5654.00
Magnetfeld: X: -5147.00 Y: -5147.00 Z: -5147.00
Pitch: 1.570796366 Roll: 1.570796366
Richtung: 224.999618528

Messung 3:

Beschleunigung: X: -5654.00 Y: -5654.00 Z: -5654.00
Magnetfeld: X: -5147.00 Y: -5147.00 Z: -5147.00
Pitch: 1.570796366 Roll: 1.570796366
Richtung: 224.999618528

Messung 4:

Beschleunigung: X: -5397.00 Y: -5397.00 Z: -5397.00
Magnetfeld: X: -4890.00 Y: -4890.00 Z: -4890.00
Pitch: 1.570796366 Roll: 1.570796366
Richtung: 225.00036621

Messung 5:

Beschleunigung: X: -6424.00 Y: -6424.00 Z: -6424.00
Magnetfeld: X: -5662.00 Y: -5662.00 Z: -5662.00
Pitch: 1.570796366 Roll: 1.570796366
Richtung: 224.999618528

Messung 6:

Beschleunigung: X: -5145.00 Y: -5145.00 Z: -5145.00
Magnetfeld: X: -6169.00 Y: -6169.00 Z: -6169.00
Pitch: 1.570796366 Roll: 1.570796366
Richtung: 224.999618528

Messung 7:

Beschleunigung: X: -5145.00 Y: -5145.00 Z: -5145.00
Magnetfeld: X: -6169.00 Y: -6169.00 Z: -6169.00
Pitch: 1.570796366 Roll: 1.570796366
Richtung: 224.999618528 Grad




Das Steht in der Bedienungsanleitung: (Siehe Bild) (https://www.sparkfun.com/datasheets/Sensors/Magneto/Tilt%20Compensated%20Compass.pdf)

Thomas$
29.04.2013, 16:37
habe grad nicht den nerv mir den code genauer anzusehen
aber die messwerte geben wirklich zu denken
x y und z wert sind immer gleich

Dirk
29.04.2013, 21:35
@robonooby:
Ich kann deinen Code auch nicht komplett ansehen.

Aber:
Du solltest erst mal ganz einfach nur die Rohwerte auslesen (ohne weitere Berechnungen, Kalibrierung o.ä.) und hier posten.


Zum Auslesen der Rohwerte:
1. Beschleunigungssensor:
Nach dem Einlesen der 6 Bytes und Berechnung jeder Achse als (H_Byte * 256 + L_Byte)
... gib hier mal die Min/Max-Werte an.
Dabei sollte beim Beschleunigungssensor der jeweilige Maximal-/Minimalwert erreicht werden, wenn die jeweilige Achse (X/Y/Z) nach unten/oben gehalten wird.

2. Magnetfeldsensor:
Nach dem Einlesen der 6 Bytes und Berechnung jeder Achse als (H_Byte * 256 + L_Byte)
... gib hier mal die Min/Max-Werte an.
Dabei kann man die Min/Max-Werte durch Drehen/Neigen/Kippen des Sensors erreichen.

robonooby
01.05.2013, 12:06
Also hab das mal gemacht.
dabei ist mir aufgefallen dass die Magnetwerte sich immer nur um den Faktor 256 ändern .
25383
Also um die Multiplikation des H_Bytes.
das bedeutet demnach, dass entweder der Magnetsensor defekt ist, was ich nicht hoffe. Oder dass hier beim auslesen ich irgendwas falsch mache.
hier nochmal der Code vom auslesen des Magnetsensor:



'Variablen für Magnetfeld Sensor :
Const Magnet_w_addr = &H3C '3C 1E
Const Magnet_r_addr = &H3D

Const Cra_reg_m = &H00
Const Crb_reg_m = &H01
Const Mr_reg_m = &H02

Const Out_x_h_m = &H03 ' Magnetfeld
Const Out_x_l_m = &H04
Const Out_y_h_m = &H05
Const Out_y_l_m = &H06
Const Out_z_h_m = &H07
Const Out_z_l_m = &H08

Dim Abmagdata(6) As Byte

Dim Imx As Integer At Abmagdata(1) Overlay
Dim Imy As Integer At Abmagdata(3) Overlay
Dim Imz As Integer At Abmagdata(5) Overlay


.......


Sub Magnet_readsensordata()
Dim Temp As Byte

I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Out_x_h_m
I2cstart
I2cwbyte Magnet_r_addr

'I2cwbyte Magnet_w_addr
'I2cwbyte Mr_reg_m

I2crbyte Abmagdata(1) , Ack
I2crbyte Abmagdata(2) , Ack
I2crbyte Abmagdata(3) , Ack
I2crbyte Abmagdata(4) , Ack
I2crbyte Abmagdata(5) , Ack
I2crbyte Abmagdata(6) , Nack
I2cstop


Imx = Abmagdata(1)
Shift Imx , Left , 8 , Signed
Imx = Imx + Abmagdata(2)

Imy = Abmagdata(3)
Shift Imy , Left , 8 , Signed
Imy = Imy + Abmagdata(4)

Imz = Abmagdata(5)
Shift Imz , Left , 8 , Signed
Imz = Imz + Abmagdata(6)

End Sub

Che Guevara
01.05.2013, 12:40
Hi,

du hast glaube ich einen Fehler beim einlesen! Durch das Overlay ersparst du dir das shiften, deswegen springen deine Werte (wegen dem Shiften) um den Wert 256 ;)
Probier mal so:



Dim Imx As Integer
Dim Imy As Integer
Dim Imz As Integer

Dim Imx_tmp(2) As Byte At Imx Overlay
Dim Imy_tmp(2) As Byte At Imy Overlay
Dim Imz_tmp(2) As Byte At Imz Overlay

Sub Magnet_readsensordata()

I2cstart
I2cwbyte Magnet_w_addr
I2cwbyte Out_x_h_m
I2cstart
I2cwbyte Magnet_r_addr
I2crbyte Imx_tmp(1) , Ack
I2crbyte Imx_tmp(2) , Ack
I2crbyte Imy_tmp(1) , Ack
I2crbyte Imy_tmp(2) , Ack
I2crbyte Imz_tmp(1) , Ack
I2crbyte Imz_tmp(2) , Nack
I2cstop

End Sub


Kann sein, dass du zuerst das zweite Byte auslesen musst, das kommt drauf an, ob dein Sensor MSB oder LSB zuerst ausgibt.

Gruß
Chris

robonooby
01.05.2013, 13:11
Also Chris hab gerade mal deinen Code ausprobiert.
wenn ich das mache bekomm ich ebenfalls immer wieder die selben Werte für Imx_tmp, Imy_tmp und Imz_tmp egal wie ich das Modul drehe und wende.

Imx_tmp(1) = 255 und Imx_tmp(2) = 255
Imy_tmp(1) = 1 und Imy_tmp(2) = 1
Imz_tmp(1) = 0 und Imz_tmp(2) = 0

Find das schon sehr merkwürdig...

Che Guevara
01.05.2013, 13:37
Hi,

also erstmal sind für dich die Variablen Imx, Imy und Imz relevant, die anderen solltest du nicht verändern oder irgendwo verwenden.
Hast du den mal probiert, zuerst die zweite Variable der Arrays einzulesen?

Gruß
Chris

robonooby
01.05.2013, 14:29
also wenn du mit zweite variable der arrays meinst, dass ich I2cwbyte Out_x_l_m oder I2cwbyte Out_y_h_m als erstes auslese, das hab ich eben mal gemacht. aber keine veränderung. immer die gleichn werte.

aber was meinst du mit die anderen nicht verändern oder verwenden?

Che Guevara
01.05.2013, 14:35
Naja, die Variablen Imx_tmp(1) usw.. solltest du nicht verändern. Das sind nur Dummy-variablen, die eigentlich garnicht existieren. Es sind Zeiger, die auf die beiden Bytes der Variable Imx zeigen. Sie dienen hauptsächlich dazu, das einlesen der Sensorwerte zu verschnellern und machen das Shiften und addieren überflüßig.

Gruß
Chris

robonooby
01.05.2013, 14:41
ahh jetzt kapier ich auch den sinn des overlays
okay. aber finds komisch dass es trotz des shiftens bei den Beschleunigungswerten funktioniert aber bei den Magnet werten nicht

- - - Aktualisiert - - -

jetzt bekomm ich auf ejdenfall andere werte raus :-)
Imx: -2817 Imy: 32257 Imz: 0
allerdings bleiben die ebenfalls Konstant egal wie ich das Modul drehe :confused:

Che Guevara
01.05.2013, 15:21
Warum bekommst du jetzt andere Werte? Was hast du den geändert? Wie oft liest du denn den Sensor aus?
Hast du mal versucht, die Error-Variable nach der I2C-Kommunikation auszugeben? Vielleicht läuft da was schief?

Gruß
Chris

robonooby
01.05.2013, 17:02
Warum bekommst du jetzt andere Werte? Was hast du den geändert? Wie oft liest du denn den Sensor aus?
Hast du mal versucht, die Error-Variable nach der I2C-Kommunikation auszugeben? Vielleicht läuft da was schief?

Gruß
Chris
ich hab das shiften weggelassen und somit komm ich jetzt auf andere werte ^^
braucht man ja bei deiner methode nicht mehr, wenn ichs richtig verstanden habe.
aber mir ist noch nen Fehler aufgefallen. Hatte die falsche Hex Adresse zum auslesen angegeben:Haue. jetzt kommen Werte an.

Jetzt wäre nur die Frage soll ich das nach deiner Methode ohne Shiften, mit den Hilfsvariablen Imx_tmp(1) usw. machen, oder mit meiner shift methode wie unten zu sehen.
Meine Shift Methode hab ich hier irgendwo im Forum gefunden, da hatte jemand nur den Beschleunigungssensor ausgelesen und das dann so gelöst. weis aber jetzt nicht was besser bzw. richtig ist...


Dim Abmagdata(6) As Byte
Dim Imx As Integer At Abmagdata(1) Overlay
Dim Imy As Integer At Abmagdata(3) Overlay
Dim Imz As Integer At Abmagdata(5) Overlay

...

I2crbyte Abmagdata(1) , Ack
I2crbyte Abmagdata(2) , Ack
I2crbyte Abmagdata(3) , Ack
I2crbyte Abmagdata(4) , Ack
I2crbyte Abmagdata(5) , Ack
I2crbyte Abmagdata(6) , Nack
I2cstop


Imx = Abmagdata(1)
Shift Imx , Left , 8 , Signed
Imx = Imx + Abmagdata(2)

Imy = Abmagdata(3)
Shift Imy , Left , 8 , Signed
Imy = Imy + Abmagdata(4)

Imz = Abmagdata(5)
Shift Imz , Left , 8 , Signed
Imz = Imz + Abmagdata(6)


- - - Aktualisiert - - -

Was mir auch noch aufgefallen ist, ist dass die Werte weit außerhalb der maximal Ausgabewerte des Sensors liegen (Laut Datenblatt: -2048 bis 2047)

Messdaten ohne Bewegung des Sensors:

Iax: 0 Iay: -12033 Iaz: 24769
Imx: 25088 Imy: -1793 Imz: 31745

Iax: 4096 Iay: 0 Iaz: 28865
Imx: 25600 Imy: -1793 Imz: 32513

Iax: 0 Iay: -20225 Iaz: -16191
Imx: 23552 Imy: -3073 Imz: -32511

Iax: 0 Iay: 0 Iaz: -28479
Imx: 23552 Imy: -2305 Imz: 32001

Iax: 0 Iay: 0 Iaz: -28479
Imx: 22272 Imy: -1537 Imz: -32511

Che Guevara
01.05.2013, 17:46
Hi,

du kannst sowohl mit Shift als auch mit Overlay arbeiten, Overlay hat aber eben den Vorteil, dass es wesentlich schneller von statten geht ;)
Dann tausch doch mal die beiden Bytes, also erst Imx_tmp(2) und dann Imx_tmp(1) einlesen bzw. andersrum wenn dus schon so hast.

Gruß
Chris

robonooby
01.05.2013, 17:59
Hi,

du kannst sowohl mit Shift als auch mit Overlay arbeiten, Overlay hat aber eben den Vorteil, dass es wesentlich schneller von statten geht ;)
Dann tausch doch mal die beiden Bytes, also erst Imx_tmp(2) und dann Imx_tmp(1) einlesen bzw. andersrum wenn dus schon so hast.

Gruß
Chris
ja das hab ich probiert. Da kommen natürlich auch andere werte raus, aber immer noch sehr hoch. wobei sich diese noch innerhalb des 16Bit Fensters Bewegen...
Ist das den Normal, dass so nen Sensor so arg streut. Wenn man oben die Werte sich anguckt. Da springt er ja immer hin und her obwohl er einfach nur aufm Tisch liegt....

Che Guevara
01.05.2013, 18:43
Hi,

also innerhalb des 16Bit - Fensters werden sich wohl alle Werte bewegen, da deine Variable als 16Bit deklariert sind ;)
Irgendwas wird da wohl noch faul sein, wenn im DB von 12Bit Werten gesprochen wird. Das würde ich als erstes mal rausfinden, dann kannst du ja schauen, ob die Werte noch immer so stark springen.

Gruß
Chris

Dirk
01.05.2013, 19:12
Hi robonooby,

da ich aktuell eher in GCC unterwegs bin, habe ich Bascom nicht mehr so auf dem Schirm.

Was ich aber noch weiß:
1. Wenn du Imx, Imy und Imz mit Overlays auf die Abmagdata()-Variablen legst, dann entsteht nach Einlesen der Abmagdata()-Variablen schon in Imx, Imy und Imz der gewünschte 16-Bit-Wert. Damit sind die Zeilen:
Imx = Abmagdata(1)
Shift Imx , Left , 8 , Signed
Imx = Imx + Abmagdata(2)
... ganz überflüssig und müssen auch für Imy und Imz weg!
2. Dasselbe gilt auch für den Acc-Sensor.

Poste mal die Ausgabewerte nach dieser Änderung!

robonooby
02.05.2013, 16:21
Also hier mal die Messdaten ohne Shift.
Hatte das aber oben schonmal gemacht. (letzte 3 Messungen waren bei Stillstand des Sensors)


Iax: 0 Iay: 8192 Iaz: -12095
Imx: 23296 Imy: 1280 Imz: 27649

Iax: 4096 Iay: 0 Iaz: -16191
Imx: -31489 Imy: 17407 Imz: 26113

Iax: 8192 Iay: 28672 Iaz: -28479
Imx: -15618 Imy: 4352 Imz: 25857

Iax: -24383 Iay: -16384 Iaz: 20484
Imx: 7169 Imy: 1024 Imz: 17151

Iax: 0 Iay: 8192 Iaz: 24769
Imx: 25344 Imy: -3073 Imz: 26369

Iax: 4096 Iay: 0 Iaz: -28479
Imx: 26112 Imy: -769 Imz: 26881

Iax: 16384 Iay: 8192 Iaz: 28865
Imx: 25088 Imy: 256 Imz: 26881



EDIT:
Hab das ganze nochmal ganz abgeändert. Auch wie im anderen Beispiel von Mikrocontroller.net (http://www.mikrocontroller.net/topic/240946) die Einstellwerte geändert, sodass er ne höhere aber ungenauere Updaterate hat.
Hier nun die aktuellen Werte.
Diese sind mit Shift Befehl aber ohne Overlay generiert worden. Die ACC Werte sehen schonmal viel besser aus. Die Magnetwerte erscheinen mir jedoch etwas klein. Oder könnte das hin kommen?


Iax: -48 Iay: 48 Iaz: -15872
Imx: 78 Imy: 4 Imz: 266

Iax: 32 Iay: 64 Iaz: -15872
Imx: 79 Imy: 9 Imz: 260

Iax: -16 Iay: 32 Iaz: -15872
Imx: 80 Imy: 12 Imz: 267

Iax: -80 Iay: 64 Iaz: -15872
Imx: -86 Imy: -152 Imz: 265


- - - Aktualisiert - - -

so nochmal das ganze Ohne Shift sondern mit Overlay: (erste drei Messungen im Stillstand, vierte Messung um Y gedreht, 5 Messung um Z Achse gedreht)


Iax: 4096 Iay: 4096 Iaz: 28866
Imx: 19968 Imy: 3584 Imz: 4353

Iax: 0 Iay: 4096 Iaz: 12482
Imx: 20736 Imy: 5120 Imz: 3329

Iax: 0 Iay: 0 Iaz: 16578
Imx: 19456 Imy: 3072 Imz: 3585

Iax: -28479 Iay: -12287 Iaz: -28668
Imx: -11008 Imy: 1280 Imz: 28927

Iax: 4096 Iay: 8192 Iaz: 24770
Imx: -23041 Imy: 27647 Imz: 3073

Dirk
02.05.2013, 17:15
Beide Lösungen ("Shift") und mit Overlay sollten dieselben Ergebnisse/Werte bringen.

Was mir noch auffällt:
Beim "Shift" verwendest du die "Signed"-Variante. Das sollte aber nicht richtig sein: Nimm das Shiften ohne Vorzeichen oder rechne einfach (Highbyte * 256 + Lowbyte),- das passt immer.

robonooby
03.05.2013, 07:41
So hab jetzt nochmal das abgeändert und ausprobiert.
Find alles sehr merkwürdig^^

Alle Ergebnisse wurden praktisch Zeitgleich erstellt und der Sensor wurde dabei nicht bewegt.

Hier mal der aktuelle Code zum Auslesen des ACC Wertes:

Sub Acc_readsensordata()
Slaveadress = Acc_w_addr '= &H30
Subadress = Out_x_l_a '= &H28

Subadress.7 = 1 'Variablen sind so deklariert: Dim Slaveadress As Byte Dim Subadress As Byte
I2cstart
I2cwbyte Slaveadress 'SAD+W
I2cwbyte Subadress
Incr Slaveadress 'for reading LSB=1
I2crepstart
I2cwbyte Slaveadress 'SAD+R

I2crbyte Iax_tmp(2) , Ack 'Variablen sind so deklariert: Dim Iax_tmp(2) As Byte At Iax Overlay Dim Iax As Integer
I2crbyte Iax_tmp(1) , Ack
I2crbyte Iay_tmp(2) , Ack
I2crbyte Iay_tmp(1) , Ack
I2crbyte Iaz_tmp(2) , Ack
I2crbyte Iaz_tmp(1) , Nack
I2cstop

Print "Iax: " ; Iax ; " " ; "Iay: " ; Iay ; " " ; "Iaz: " ; Iaz
End Sub
Die Ergebnisse hierzu:

Iax: 4096 Iay: 0 Iaz: -7999
Iax: 4096 Iay: 4096 Iaz: -24383
Iax: 8192 Iay: 16384 Iaz: -12095

Code zum Auslesen des Magnetsensors ohne Shift:

Sub Magnet_readsensordata()
Slaveadress = Magnet_w_addr '&H3C
Subadress = Out_x_h_m '&H03

Subadress.7 = 1 'Variablen sind so deklariert: Dim Slaveadress As Byte Dim Subadress As Byte

I2cstart
I2cwbyte Slaveadress 'SAD+W
I2cwbyte Subadress
Incr Slaveadress 'for reading LSB=1
I2crepstart
I2cwbyte Slaveadress 'SAD+R

I2crbyte Imx_tmp(1) , Ack 'Variablen sind so deklariert: Dim Imx_tmp(2) As Byte At Imx Overlay Dim Imx As Integer
I2crbyte Imx_tmp(2) , Ack
I2crbyte Imy_tmp(1) , Ack
I2crbyte Imy_tmp(2) , Ack
I2crbyte Imz_tmp(1) , Ack
I2crbyte Imz_tmp(2) , Nack
I2cstop

Print "Imx: " ; Imx ; " " ; "Imy: " ; Imy ; " " ; "Imz: " ; Imz
End Sub
Die Ergebnisse hierzu:

Imx: 21504 Imy: 1280 Imz: 1537
Imx: 18432 Imy: 1536 Imz: 2049
Imx: 17920 Imy: 0 Imz: 4097


Und nochmal Magnetsensor mit Shift

Sub Magnet_calcmvalues()
Wait 1
Slaveadress = Magnet_w_addr '&H3C
Subadress = Out_x_h_m '&H03

Subadress.7 = 1 'Variablen sind so deklariert: Dim Slaveadress As Byte Dim Subadress As Byte

I2cstart
I2cwbyte Slaveadress 'SAD+W
I2cwbyte Subadress
Incr Slaveadress 'for reading LSB=1
I2crepstart
I2cwbyte Slaveadress 'SAD+R

I2crbyte Abmagdata(1) , Ack 'Variablen sind so deklariert: Dim Abmagdata(6) As Byte
I2crbyte Abmagdata(2) , Ack
I2crbyte Abmagdata(3) , Ack
I2crbyte Abmagdata(4) , Ack
I2crbyte Abmagdata(5) , Ack
I2crbyte Abmagdata(6) , Nack
I2cstop


'Iaxx = Abmagdata(1) 'Variablen sind so deklariert: Dim Iaxx As Integer
'Shift Iaxx , Left , 8
'Iaxx = Iaxx + Abmagdata(2)

Iayy = Abmagdata(3)
Shift Iayy , Left , 8
Iayy = Iayy + Abmagdata(4)

Iazz = Abmagdata(5)
Shift Iazz , Left , 8
Iazz = Iazz + Abmagdata(6)

Print "Shift: Imx: " ; Iaxx ; " " ; "Imy: " ; Iayy ; " " ; "Imz: " ; Iazz
Print ""
End Sub
und deren Ergebnisse: (Ich habe auch deine Variante mit (Highbyte * 256 + Lowbyte) ausprobiert. kommt das selbe raus wie bei shift)

Shift: Imx: 75 Imy: 11 Imz: 266
Shift: Imx: 83 Imy: 14 Imz: 264
Shift: Imx: 74 Imy: -6 Imz: 277

Dirk
03.05.2013, 08:48
1. Zum "Auslesen des ACC-Wertes":
Wie ist Iax_tmp(1) definiert? Nimm lieber einzelne Byte-Variablen und nicht Arrays. High- und Low-Byte richtig angeordnet?

2. Zum "Magnetsensor ohne Shift":
Wie ist Imx_tmp(1) definiert? Nimm lieber einzelne Byte-Variablen und nicht Arrays.

3. Zum "Magnetsensor mit Shift":
Sieht noch am besten aus. Die Werte sind aber etwas niedrig...?

robonooby
03.05.2013, 10:15
1. Zum "Auslesen des ACC-Wertes":
Wie ist Iax_tmp(1) definiert? Nimm lieber einzelne Byte-Variablen und nicht Arrays. High- und Low-Byte richtig angeordnet?

2. Zum "Magnetsensor ohne Shift":
Wie ist Imx_tmp(1) definiert? Nimm lieber einzelne Byte-Variablen und nicht Arrays.

3. Zum "Magnetsensor mit Shift":
Sieht noch am besten aus. Die Werte sind aber etwas niedrig...?
Habs extra hinten dran geschrieben aber gerne nochmal^^

Zu 1:
Dim Iax As Integer
Dim Iax_tmp(2) As Byte At Iax Overlay
High und Low Byte müsste richtig angeordnet sein. Laut Datenblatt kommt erst das Low Byte und dann das High Byte. Beim Magnetsensor genau umgedreht.

Zu 2:
Dim Imx As Integer
Dim Imx_tmp(2) As Byte At Imx Overlay

zu 3:
jop ich denk auch dass die Werte zu niedrig sind. aber ich weis nicht warum. normal müsste doch die selben Werte raus kommen??
Find das alles sehr merkwürdig...

Dirk
03.05.2013, 10:44
@robonooby:
Zu 1 und 2: Ich hatte aber nach Iax_tmp(1) bzw. Imx_tmp(1) gefragt!
Der Grund meiner Frage:
Wenn du als _tmp-Variablen ein Array nimmst, hat das wieder eine eigene Struktur im Speicher. Wenn du also das _tmp-Array mit Index (2) als Overlay-Adresse benutzt, liegt das _tmp-Array mit Index (1) unterhalb von Index (2) im Speicher, also auch unterhalb der Iax bzw. Imx Variable.

Zu 3: Du könntest mit den Werten (ohne weitere Kalibrierung/Normalisierung) einmal die Richtung errechnen. Kommt da was Sinnvolles raus?

robonooby
03.05.2013, 16:24
Mühsam ernährt sich das Eichhörnchen :D
bin jetzt weiter gekommen, und die Werte scheinen ganz Brauchbar zu sein. Auch wenn ichs nicht ganz verstehe^^

hier erstmal der aktuelle Code:

Deklarationen:

'Variablen für Beschleunigungs Sensor:
Const Acc_w_addr = &H30
Const Acc_r_addr = &H31

Const Ctrl_reg1_a = &H20
Const Ctrl_reg4_a = &H23

Const Out_x_l_a = &H28
Const Out_x_h_a = &H29
Const Out_y_l_a = &H2A
Const Out_y_h_a = &H2B
Const Out_z_l_a = &H2C
Const Out_z_h_a = &H2D

'Variablen für Magnetfeld Sensor :
Const Magnet_w_addr = &H3C '3C
Const Magnet_r_addr = &H3D

Const Cra_reg_m = &H00
Const Crb_reg_m = &H01
Const Mr_reg_m = &H02

Const Out_x_h_m = &H03 ' Magnetfeld
Const Out_x_l_m = &H04
Const Out_y_h_m = &H05
Const Out_y_l_m = &H06
Const Out_z_h_m = &H07
Const Out_z_l_m = &H08

Dim Slaveadress As Byte 'Adress of the slave to read or write
Dim Subadress As Byte 'the register to read or write

Dim Iax As Integer
Dim Iay As Integer
Dim Iaz As Integer

Dim Xha As Byte
Dim Xla As Byte
Dim Yha As Byte
Dim Yla As Byte
Dim Zha As Byte
Dim Zla As Byte

Dim Imx As Integer
Dim Imy As Integer
Dim Imz As Integer

Dim Xhm As Byte
Dim Xlm As Byte
Dim Yhm As Byte
Dim Ylm As Byte
Dim Zhm As Byte
Dim Zlm As Byte


Dim Sgx As Single 'Beschleunigungsvariablen
Dim Sgy As Single
Dim Sgz As Single

Dim Pitch As Single
Dim Roll As Single

Dim Magnetx As Single 'Magnetfeldvariablen
Dim Magnety As Single
Dim Magnetz As Single
Dim Richtung As Single

ACC Sensor:

Sub Acc_readsensordata()
Subadress = Out_x_l_a '&H28

Subadress.7 = 1
I2cstart
I2cwbyte Acc_w_addr '&H30 'SAD+W
I2cwbyte Subadress
I2crepstart
I2cwbyte Acc_r_addr 'SAD+R Acc_r_addr = &H31


I2crbyte Xla , Ack
I2crbyte Xha , Ack
I2crbyte Yla , Ack
I2crbyte Yha , Ack
I2crbyte Zla , Ack
I2crbyte Zha , Nack
I2cstop

Iax = Xha
Shift Iax , Left , 8
Iax = Iax + Xla

Iay = Yha
Shift Iay , Left , 8
Iay = Iay + Yla

Iaz = Zha
Shift Iaz , Left , 8
Iaz = Iaz + Zla

Sgx = Iax
Sgy = Iay
Sgz = Iaz

Print "Iax: " ; Iax ; " " ; "Iay: " ; Iay ; " " ; "Iaz: " ; Iaz
End Sub

Magnet Sensor:

Sub Magnet_readsensordata()
Subadress = Out_x_h_m '&H03

I2cstart
I2cwbyte Magnet_w_addr 'SAD+W '&H3C
I2cwbyte Subadress
I2crepstart
I2cwbyte Magnet_r_addr 'SAD+R Magnet_r_addr = &H3D

I2crbyte Xlm , Ack
I2crbyte Xhm , Ack
I2crbyte Ylm , Ack
I2crbyte Yhm , Ack
I2crbyte Zlm , Ack
I2crbyte Zhm , Nack
I2cstop

Print "XHM: " ; Xhm ; " XLM: " ; Xlm ; " YHM: " ; Yhm ; " YLM: " ; Ylm ; " ZHM: " ; Zhm ; " ZLM: " ; Zlm

Imx = Xhm
Shift Imx , Left , 8
Imx = Imx + Xlm

Imy = Yhm
Shift Imy , Left , 8
Imy = Imy + Ylm

Imz = Zhm
Shift Imz , Left , 8
Imz = Imz + Zlm

Print "Imx: " ; Imx ; " " ; "Imy: " ; Imy ; " " ; "Imz: " ; Imz

End Sub

Ergebnisse:
hierbei wurde der Sensor im Uhrzeigersinn immer um 90 Grad gedreht. Bei der letzten Messung von der Ausgangsposition um 90° um die y-Achse gedreht.

Ausgangsposition:
Iax: 0 Iay: 32 Iaz: -15824
Pitch: 1.570796366 Roll 1.570796366
XHM: 79 XLM: 0 YHM: 249 YLM: 255 ZHM: 15 ZLM: 1
Imx: 20224 Imy: -1537 Imz: 3841
Richtung: 79.248695372

Iax: -16 Iay: 0 Iaz: -15904
Pitch: 1.570796366 Roll 1.570796366
XHM: 166 XLM: 255 YHM: 111 YLM: 255 ZHM: 18 ZLM: 1
Imx: -22785 Imy: 28671 Imz: 4609
Richtung: 281.433227538

Iax: 64 Iay: 128 Iaz: -15824
Pitch: 1.570796366 Roll 1.570796366
XHM: 15 XLM: 255 YHM: 20 YLM: 0 ZHM: 13 ZLM: 1
Imx: 4095 Imy: 5120 Imz: 3329
Richtung: 50.892387387

Iax: 0 Iay: 16 Iaz: -15936
Pitch: 1.570796366 Roll 1.570796366
XHM: 189 XLM: 255 YHM: 174 YLM: 0 ZHM: 253 ZLM: 0
Imx: -16897 Imy: -20992 Imz: -768
Richtung: 267.394683837

Iax: -15872 Iay: 272 Iaz: 1280
Pitch: 1.570796366 Roll 1.570796366
XHM: 220 XLM: 0 YHM: 254 YLM: 255 ZHM: 115 ZLM: 255
Imx: -9216 Imy: -257 Imz: 29695
Richtung: 342.755859375

Was mich verwundert ist, dass der Magnetsensor zuerst Low Byte und dann High Byte raushaut. Im Datenblatt steht das ganz anderst drin. Wenn ichs laut Datenblatt mache dann kommen sehr niedrige Werte wie dieser folgender raus:

Ebenfalls ca in Ausgangsposition von obiger Messung
Iax: 32 Iay: 0 Iaz: -15904
Pitch: 1.570796366 Roll 1.570796366
XHM: 0 XLM: 81 YHM: 255 YLM: 250 ZHM: 1 ZLM: 9
Imx: 81 Imy: -6 Imz: 265
Richtung: 16.859010695

Weis jetzt nicht was eher stimmen könnte:confused:
Und warum das ganze mit Arrays nicht richtig funktioniert ist mir auch schleierhaft...

Dirk
03.05.2013, 18:05
@robonooby:
Die Richtungsausgabe sieht doch schon mal ganz gut aus. Pitch/Roll zeigen nur konstante Werte, stimmt da was nicht!?

Was mich verwundert ist, dass der Magnetsensor zuerst Low Byte und dann High Byte raushaut. Im Datenblatt steht das ganz anderst drin.
Ne, für den LSM303DLH steht das genau so auch im Datenblatt.
Anders ist das beim Magnetsensor vom LSM303DLHC,- der hat die High-Low Reihenfolge der Output-Register.

Und warum das ganze mit Arrays nicht richtig funktioniert ist mir auch schleierhaft...
Den Grund hatte ich dir geschrieben.

robonooby
03.05.2013, 18:14
@robonooby:
Die Richtungsausgabe sieht doch schon mal ganz gut aus. Pitch/Roll zeigen nur konstante Werte, stimmt da was nicht!?

Ne, für den LSM303DLH steht das genau so auch im Datenblatt.
Anders ist das beim Magnetsensor vom LSM303DLHC,- der hat die High-Low Reihenfolge der Output-Register.

Den Grund hatte ich dir geschrieben.
Oh da hab ich dann wohl das falsche Datenblatt runter geladen^^
Ja aber normal müsste das doch das gleiche sein? Also kenn das nur vom PC Programmieren, dass er immer genau so viel Speicher reserviert wie er braucht...

Pitch/Roll ist so nicht korrekt das stimmt. das liegt aber an der Berechnung. Da bin ich gerade dran. aber immerhin ändern sich die Ausgangswerte.

Also dann erstmal vielen Dank für eure Gedult und Hilfe

robonooby
04.05.2013, 14:33
So nachdem ich soweit brauchbare Ergebnisse rausbekommen hab, bin ich dabei das ganze zu Kalibrieren. Hierzu brauch ich Kalibrierungsfaktoren. Beim ACC hab ichs soweit geschaft.
Beim Magnetsensor komm ich gerade nicht weiter.
Hab mir erstmal die Werte vom Magnetsensor (Imx, Imy, Imz) ausgeben lassen und dann in Excel geplottet. Laut compass-app-note Dokument und dieser Seite (http://www.sensorsmag.com/sensors/motion-velocity-displacement/compensating-tilt-hard-iron-and-soft-iron-effects-6475)soll das ganze dann nen Kreis oder zumindestens ne Elypse werden.
bei mir ist es allerdings alles andere geworden^^

hier mal das Bild:
25413
Kann es sein, dass der Sensor da so streut oder können das Stöhrquellen sein, die das Gesammtbild so sehr beeinflussen?
Hat jemand schonmal sowas gemacht und kann mir hier ggf. Tipps geben...

Wenn ich den Winkel ausrechne kommt bei einer Drehung nichts Sinnvolles raus. Ist einfach nicht Gleichmäßig. zwischen 0 und 90 Grad zeigt er zum Beispiel -90 und 180 Grad an und sowas. Ist also nicht linear.

Dirk
04.05.2013, 20:25
Hi robonooby:
Das Kalibrieren und Beseitigen von allen Einflußfaktoren beim Magnetometer ist schon eine Herausforderung.
Wenn du da ganz genau sein willst und z.B. Hard- und Soft-Iron Effekte (das ist die elliptische Messwert-Wolke) kompensieren willst, must du schon Aufwand betreiben.
Das Ganze lohnt auch nur, wenn dein Sensor schon dauerhaft auf/in DER Hardware montiert ist, wo er definitiv seinen Dienst tun soll.
D.h. wenn er noch auf einem Experimentierbrett "herumfliegt", braucht und kann man kaum etwas kompensieren und sollte nur kalibrieren.

Gute Lektüre:
- AN996 (Microchip)
- "Applications of Magnetoresistive Sensors in Navigation Systems" (Honeywell Inc.)
- AN00022 (PHILIPS)
- AN4248 (Freescale Semiconductor)

robonooby
05.05.2013, 07:28
okay. ja dann werd ich das bisl nach hinten verschieben bis er dann endgültig eingebaut ist.
Guck mir dann aber schonmal die Lektüre an. So beim Überfliegen sind die Dokumente echt nicht schlecht. Auf jedenfall besser als das vom LSM303DLH

hier mal noch die dazu gehörenden Links, falls das noch jemand anderes Interessiert:
- AN996 (Microchip) (http://ww1.microchip.com/downloads/en/appnotes/00996a.pdf)
- "Applications of Magnetoresistive Sensors in Navigation Systems" (Honeywell Inc.) (http://inertial-solutions.us/pdf_files/sae.pdf)
- Applications of Magnetic Sensors for Low Cost Compass Systems (Honeywell Inc.) (http://hnc.ru/lib/a&c%20%28automatic%20&%20controls%29/sensors/DataSheet/Magnit/Honeywell/lowcost.pdf)
- AN00022 (PHILIPS) (http://www.sbszoo.com/ve6sbs/projects/compass/kmz52an00022.pdf)
- AN4248 (Freescale Semiconductor) (http://www.freescale.com/files/sensors/doc/app_note/AN4248.pdf)

Danke dafür.

Ritchie
05.05.2013, 19:27
Hallo robonooby,

ich habe das gleiche Problem und werde mich bald mit diesem Thema auch beschäftigen.

Habe hier auch einen Interessanten Link, vielleicht hilft er Dir ja.
http://www.starlino.com/imu_guide.html

Gruss R.
P.S.: Das Thema ist auch neu für mich.

robonooby
10.05.2013, 10:09
ja ich hab jetzt auch mal ein kurzes Tutorial im Wiki verfasst, ist allerdings noch nicht ganz fertig.
http://www.rn-wissen.de/index.php/Bascom_und_Kompass_LSM303DLH

Ich hab immer noch Probleme mit der Kalibrierung des Kompasswertes. Der schwankt mir einfach zu sehr (+-130°)
Bekomm das auch durchs kalibrieren nicht weg. Hab das nach der oben stehenden Literatur probiert. Hab auch mal versucht nen Mittelwert zu bilden (100 durchläufe pro Mittelwert) aber keine Besserung.
Mein Normaler Pfadfinderkompass bleibt stabil^^

Der ACC Wert ist sehr stabil. schwankt im bereich von 0,02° für Pitch und Roll, was für mich völlig ausreichend ist.

Dirk
10.05.2013, 17:53
Das Kalibrieren hilft ja nicht gegen Meßwertschwankungen. +-130° ist nicht nur zu viel, sondern so nicht auswertbar.
Da muss noch ein Wurm (Hardware, Software) drin sein.

robonooby
11.05.2013, 12:49
Das Kalibrieren hilft ja nicht gegen Meßwertschwankungen. +-130° ist nicht nur zu viel, sondern so nicht auswertbar.
Da muss noch ein Wurm (Hardware, Software) drin sein.
Also ich habs endlich geschafft :)
hab nen Beispielcode für Audrio gefunden und den auf Bascom übersetzt. Und jetzt funktioniert es soweit. Werte bleiben stabil und alles funktioniert. Muss ich dann gleich in meinem Wikibeitrag noch ändern.

EDIT: Wiki Beitrag Korrigiert (http://www.rn-wissen.de/index.php/Bascom_und_Kompass_LSM303DLH)