PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 3D-Beschleunigungssensor LSM303DLH auslesen



dariegel
15.08.2011, 11:11
Morgen Roboternetz,

habe hier den 3D-Beschleunigungssensor/-Kompass LSM303DLH (http://www.pololu.com/catalog/product/1250) per I2C an ein RN-Control 1.4 angeschlossen (Aufbau siehe Anhang). Nach zwei Tagen Kopfrauchen kann ich auch die Beschleunigungswerte auslesen. \\:D/

Allerdings verhalten sich zwei der drei Achsen etwas merkwürdig. Wie im Ausgabe-Beispiel (Anordnung X Y Z, eine Zeile = ein Datensatz) zu sehen ist, springt die X-/Z-Achse augenscheinlich willkürlich innerhalb des eingestellten +-2g-Bereiches hin und her. Seltsamerweise tun sie dies nur in Schritten eines Vielfachen von 0,25 g.

Nur die mittlere Wertspalte (Y-Achse) liefert die im horizontalen, unbewegten Zustand erwarteten konstanten Werte. Kippt man die Platine, verändert sich die Y-Spalte sehr feinfühlig und spiegelt als einzige den zunehmenden/abnehmenden Anteil der Erdbeschleunigung wider (bis max. 1 g).

Zudem sind die Achsen vertauscht, die im Datenblatt beschriebenen Register entsprechen nicht dem auf der Platine angegebenen Koordinatensystem.

Könnt Ihr mir einen Hinweis geben, warum die X-/Z-Achse so springt? Mir erscheint das unerklärlich, denn alle drei Achsen werden auf die gleiche Art ausgelesen, verarbeitet und in einen g-Wert umgerechnet (siehe Code).

Danke Euch.



1.50 0.00 1.25
1.50 0.00 0.50
1.25 0.00 0.00
1.00 0.00 0.75
1.25 0.00 0.50
-2.00 0.00 1.00
1.25 0.00 0.50
1.00 0.00 0.00
0.75 0.00 0.75
1.25 0.00 0.00
1.25 0.00 0.50
0.75 0.00 0.25
-2.00 0.00 1.00
1.75 0.00 1.00
-2.00 0.00 0.75
1.25 0.00 0.50
1.50 0.00 0.50
1.50 0.00 1.25
-2.00 0.00 0.75
1.00 0.00 -0.25
1.00 0.00 0.50
-1.75 0.00 0.25
-2.00 0.00 0.00



$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000
$baud = 9600

Config Scl = PortC.0
Config Sda = PortC.1

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

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

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

Dim abAccData(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 sGx As Single
Dim sGy As Single
Dim sGz As Single


LSM303_Init

Do
ACC_ReadSensorData
ACC_CalcGValues

PRINT FUSING(sGx , "#.##") ; " " ; FUSING(sGy , "#.##") ; " " ; FUSING(sGz , "#.##")

WAITMS 100
Loop

End


Sub LSM303_Init()
ACC_WriteReg CTRL_REG1_A , &H27 'normal power mode, 50 Hz data rate, all axes enabled
End Sub

Sub ACC_WriteReg(ByVal bReg As Byte , ByVal bVal As Byte)
I2CSTART
I2CWBYTE ACC_W_ADDR
I2CWBYTE bReg
I2CWBYTE bVal
I2CSTOP
End Sub

Sub ACC_ReadSensorData()
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)
I2CRBYTE abAccData(2) , ACK
I2CRBYTE abAccData(3)
I2CRBYTE abAccData(4) , ACK
I2CRBYTE abAccData(5)
I2CRBYTE abAccData(6) , NACK
I2CSTOP

SHIFT iAx , RIGHT , 4 , SIGNED
SHIFT iAy , RIGHT , 4 , SIGNED
SHIFT iAz , RIGHT , 4 , SIGNED
End Sub

Sub ACC_CalcGValues()
sGx = iAx * RES_2G
sGy = iAy * RES_2G
sGz = iAz * RES_2G
End Sub

MagicWSmoke
17.08.2011, 09:19
Was veranlasst Dich zu der Annahme, daß nur jedes 2te Byte zu ACK-en ist ?
Durch diesen Fehler wird I2CRBYTE für Data 1, 3, 5 nicht einkompiliert, mit entsprechendem Ergebnis. Bascom sollte sich da eigentlich beschweren, passiert nur nicht.

dariegel
17.08.2011, 09:25
Danke, werde das ausprobieren und berichten.

dariegel
18.08.2011, 20:33
Was veranlasst Dich zu der Annahme, daß nur jedes 2te Byte zu ACK-en ist ?
Durch diesen Fehler wird I2CRBYTE für Data 1, 3, 5 nicht einkompiliert, mit entsprechendem Ergebnis. Bascom sollte sich da eigentlich beschweren, passiert nur nicht.

Wahnsinn, das war's! Vielen Dank! :p

Gibt es eigentlich eine Möglichkeit, die Ausgabe des PRINT-Befehls in Spalten mit fester Breite zu formatieren?

MagicWSmoke
19.08.2011, 15:26
Gibt es eigentlich eine Möglichkeit, die Ausgabe des PRINT-Befehls in Spalten mit fester Breite zu formatieren?
Nein, ist aber mit Len() und Space() schnell gebastelt.

dariegel
19.08.2011, 17:11
Nein, ist aber mit Len() und Space() schnell gebastelt.

Da hast Du wohl recht, dachte aber, dass es eine einfachere Möglichkeit gäbe. Danke für Deine Hilfe.

MagicWSmoke
19.08.2011, 17:55
Bitte, gern geschehen ;-)