PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 3-Achs Beschleunigungssensor - sensationell günstig !



Andree-HB
15.04.2010, 11:24
Eben bei ELV entdeckt :

"3-Achsen-Beschleunigungssensor, Komplettbausatz
Artikel-Nr.: 68-915-21, EUR 5,95
Das sehr kompakte Sensor-Modul ist mit einem digitalen 3-Achsen-MEMS-Beschleunigungssensor BMA020 von Bosch Sensortec bestückt und stellt für die einfache Einbindung in eigene Applikationen einen 2,5-V-Spannungswandler sowie fünf Pegelwandler bereit."


http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=28515

TobiKa
25.04.2010, 21:31
Hi

Hast du dir das Ding gekauft? Hab ja großes Interesse dran, aber wenn das wirklich ein Bausatz ist, dann wird echt schwer das zu löten, besonders der Sensor selbst...

Besserwessi
25.04.2010, 22:55
Ich würde mal Tippen dass die SMD Teile schon drauf sind. Man muß eventuell noch die Stiftleisten einlöten.

Andree-HB
26.04.2010, 05:25
...auch ich tippe drauf, dass es grösstenteils fertig ist. Leider verzögert sich die Verfügbarkeit, aber ich wollte mir schon bei Gelegenheit einen Sensor bestellen.

asurofreak.
26.04.2010, 15:32
scheint wirklich ein guts angebot zu sein...

schätze auch das die smd´s bereits eingelötet sind, will damit nämlich nichts zutuhen haben :D

MfG

Besserwessi
26.04.2010, 17:18
Auf dem Bild sehen die SMDs sehr Professionell gelötet aus, z.B. per Reflow. Die Stiftleisten sehen dagegen mehr wie gut von Hand gelötet aus.

Selber hab ich den Sensor nicht, also nur eine Vermutung.

Thomas$
26.04.2010, 17:44
freu mich schon auf ein testbericht BEI DEM PREIS
wenn das teil wirklich was taugt wäre das echt super

wuseltum
27.04.2010, 17:46
Konntet Ihr denn überhaupt welche bestellen? Bei mir steht: Lieferung in 21 Wochen - auf Anfrage wurde mir das gerade als korrektes Datum bestätigt. So lange möchte ich eigentlich nicht warten :(

Thomas$
27.04.2010, 17:54
bei dem preis kein wunder

BastelWastel
27.04.2010, 19:25
Hab mir heut früh um 1 noch zwei Stück bestellt..da stand noch 1 Woche, hast es wohl knap verpaßt :-#

wuseltum
27.04.2010, 22:01
Also wenn jemand bereit wäre, mir eins oder zwei weiterzuverkaufen, wär ich sehr dankbar um ne PN...

wuseltum
28.04.2010, 10:03
EDIT: Hat sich scheinbar erledigt. Die Module sind wieder lieferbar!
(schon komisch, dass mir gestern auf Anfrage die Lieferung in der KW39 bestätigt wurde)

Sternthaler
29.04.2010, 23:38
Hallo zusammen.

Guter Tipp!
Ich habe mir trotz der 21 Wochen Lieferzeit (wurde heute bestätigt) gleich 4 Stück bestellt.

Und hier finden man, dass tatsächlich alles bis auf die Stiftleisten eingelötet ist: (letzte Seite; rechts unten)
http://www.elv-downloads.de/downloads/Leseproben/Journal/02-2010/91521_3d_bs.pdf

Und für die 'Selbermacher' unter uns gibt es von ELV auch noch das Platinenlayout gratis:
http://www.elv-downloads.de/downloads/platinenfolien/2010-2/1023472A1.pdf

Aber komisch ist, dass es diesen BMA020-Sensor scheinbar bei Bosch gar nicht/oder nicht mehr gibt. (Stört uns das? Oder kommt hier die Lieferzeit her?) Im oben angegebenen ELV-PDF steht jedenfalls ein Erstelldatum vom 04.03.2010.
http://www.bosch-sensortec.com/content/language1/html/4377.htm
Allerdings ist die Pressemitteilung von Bosch zum Sensor schon vom März 2008.
http://www.bosch-presse.de/TBWebDB/bosch-ptj/modules/oragetblob.dll/PI6206.pdf?db=TBWebDB&item=TBWebDB_texpdf&id=3581,1&dispo=a


Drei (demnächst ;-)) messbare Beschleunigungen wünscht
Sternthaler

P.S.: Was macht man mit den Messdaten? Kennt einer die mathematischen Notwendigkeiten? (:oops: Ich habe zum selbersuchen ja nun 21 Wochen Zeit.)

Zachso
30.04.2010, 00:41
sehe ich das richtig dass man, um alle 3 achsen zu messen, tatsaechlich 3 von den dingern braucht die man dann auch noch absolut exakt im 90grad winkel anordnen muss?

Thoralf
30.04.2010, 07:23
sehe ich das richtig dass man, um alle 3 achsen zu messen, tatsaechlich 3 von den dingern braucht die man dann auch noch absolut exakt im 90grad winkel anordnen muss?

da es ein 3-Achs-Sensor ist, braucht man nur einen (zumindest der Beschreibung nach)

wuseltum
03.05.2010, 20:43
so, meiner ist heute schon angekommen. funktioniert auf anhieb, dummerweise scheint das ding falsch kalibriert zu sein oder ich hab's irgendwie kaputt gemacht.
jedenfalls liegt die z-beschleunigung bei mir zwischen -0.7 und 1.2g, wenn ich den sensor rumdreh. x und y stimmen auch nicht genau. hat sonst schon jemand erfahrungen gesammelt?

malthy
05.05.2010, 14:37
Hallo,

also nur zur Information für all jene, die sich einen solchen Sensor bestellen wollen: ich habe am 29.04. einen Sensor bestellt, der wurde am 30.04. versandt und ist am 03.04. bei mir angekommen. Und auf der ELV-Seite steht er auch als "sofort lieferbar". Ist mir also nicht klar, warum er bei manchem Leuten angeblich erst so spät lieferbar ist...

Gruß
Malte

wtp
12.05.2010, 21:21
hallo an alle!
ich bin neu hier und hab gleich mal ein paar fragen!

hab mir vor einigen tagen besagten beschleunigungssensor besorgt und bekomm einfach keine daten aus ihm herausgekitzelt!

ich hab mal versucht das byte welches ich reinschreibe wieder auszulesen, jedoch passiert im terminal gar nichts! (ausser ständiger ausgabe von 0...)

Ps.: Habe gerade mit bascom begonnen und verwende einen atm88 auf einem experimentierboard (franzis)


hier mein testprogramm:


$regfile = "m88def.dat"
$crystal = 8000000
$baud = 19200
$lib "i2c_twi.lbx"


Config Scl = Portc.5
Config Sda = Portc.4

Dim Wert As Byte

I2cinit
Config Twi = 100000

Do

I2cstart

I2cwbyte &H70
I2cwbyte &H15
I2cwbyte &B10001000

I2cstop

Waitms 25

I2cstart

I2cwbyte &H70
I2cwbyte &H02

I2cstart

I2cwbyte &H71
I2crbyte Wert
I2cstop

Waitms 25

Print Wert

Loop
End

kann mir jemand einen tipp geben wo mein fehler liegt?
danke im voraus!!!
Robert

Andree-HB
31.05.2010, 09:47
...würde mich ja nun auch mal interessieren, ob/wie das Teil gut funktioniert....

_|Alex|_
31.05.2010, 10:49
werd mir nachher mal einen Bestellen Lieferzeit 16 Wochen :S

RobbyFan
13.06.2010, 12:51
hallo,
in die wo wird der wert des sensors in var "wert "gespeichert" ?

Sternthaler
21.06.2010, 00:56
Hallo an alle,

hier mal ein Programmschnippsel für die Neugierigen, die wissen wollen wie es geht: (Und es geht gut!)


/*----------------------------------------------------------------------------
Defines: Adresse vom BMA020-3D-Beschleunigungssensor
*/
#define I2C_BMA_W 0x70
#define I2C_BMA_R 0x71

int16_t x, y, z;
uint8_t ret;

/*
Lesen von 6 Registern ab Register 0x02. X, Y, Z-Koordinate
*/
ret = StartI2C (I2C_BMA_W);
ret = WriteI2C (0x02);
StopI2C ();

ret = StartI2C (I2C_BMA_R);
ret = ReadI2C (ACK); x = (int16_t)ret;
ret = ReadI2C (ACK); x = x | ((int16_t)ret << 8); x /= 64;
ret = ReadI2C (ACK); y = (int16_t)ret;
ret = ReadI2C (ACK); y = y | ((int16_t)ret << 8); y /= 64;
ret = ReadI2C (ACK); z = (int16_t)ret;
ret = ReadI2C (NAK); z = z | ((int16_t)ret << 8); z /= 64;
StopI2C ();


Um z.B. das Status-Register 14 (Hex) auszulesen macht man folgendes:

/*----------------------------------------------------------------------------
Defines: Adresse vom BMA020-3D-Beschleunigungssensor
*/
#define I2C_BMA_W 0x70
#define I2C_BMA_R 0x71

/*
Lesen des Status-Registers 0x14 : reserviert:7:5 range:4:3 bandwidth:2:0
*/
uint8_t ret, r14;
uint8_t range;

ret = StartI2C (I2C_BMA_W);
ret = WriteI2C (0x14);
StopI2C ();

ret = StartI2C (I2C_BMA_R);
r14 = ReadI2C (NAK);
StopI2C ();
range = (r14 & 0b00011000) >> 3;



Und bei mir betrug die Lieferzeit nur ca. 10 Tage. Jippie ;-)

Gruß
Sternthaler

[edit 11.10.2010]
Auf Wunsch eine kleine Erklärung für die Berechnung der x-, y-, z-Werte.

Für X steht im oberen Code-Block folgendes:
Zeile 1) ret = ReadI2C (ACK); x = (int16_t)ret;
Zeile 2) ret = ReadI2C (ACK); x = x | ((int16_t)ret << 8 ); x /= 64;

In Zeile 1) wird beim ersten ReadI2C der Wert vom Register 0x02 aus dem Chip gelesen. Darin sind nur die beiden obersten Bit relevant für das X-Ergebnis. Es sind die beiden untersten Bits vom gesamten 10-Bit-Messwert.
Trotzdem wird diese Byte nun als 16-Bitwert in der Variablen x gespeichert.
In Zeile 2) wird mit dem nächsten ReadI2C das Register 0x03 aus dem Chip gelesen. (Die Adresse wird automatisch vom Chip hochgezählt.)
Dahinter wird nun das in Zeile 1) gelesene BIT-Muster mit |-Zeichen und dem in Zeile 2) gelesenen und mit dem <<8 um 8 BIT nach links geschobenem Registerwert aus 0x03 'verbunden'.
=> 0000 0000 ??-- ----: Die 2 Bits aus Zeile 1) in der 16-Bit-Variablen x
Bit-ODER-Verknüpft (|-Zeichen) mit dem um 8 Bit nach links geschobenem Wert aus Zeile 2)
=> ???? ???? 0000 0000: Die oberen 8 Bit vom Messwert. Ergibt:
----------------------------
=> ???? ???? ??-- ----

Die ? sind also nun die 10 Bit Messergebnis
Die - sind Bits, die auch gelesen wurden, aber hier nicht interessieren.
Die 0 sind Bits, die wir bewusst gesetzt hatten.

Jetzt noch in Zeile 2) mit dem x /= 64 diese Ergebnis einfach um 6 Bit nach rechts schieben. (Man kann auch schreiben x = x / 64;)
Man hätte auch x = ( x | ((int16_t)ret << 8 ) ) >> 6; schreiben können. Das macht der Compiler sowiso daraus.

Also ist das Ergebnis nun:
=> 0000 00?? ???? ????

Und damit haben wir die 10 Bit X-Messwert 'greifbar'.
ACHTUNG: Das höchste ?-Bit ist ein Vorzeichen.
Die Zählweise für den Betrag des Wertes kann man am besten in der Doku nachlesen.

Datenblatt: BMA020 (http://www.asuro-sternthaler.de/bauteile/I2C/BMA020_DataSheet_1_1_080114.pdf)
Die Register sind auf Seite 9 beschreiben.
Die Zählweise vom Ergebnis ist auf Seite 21.

Viel Spaß beim Lesen wünscht
Sternthaler

Sternthaler
26.06.2010, 13:01
@wtp
Hallo, 3 Dinge sind mir aufgefallen in deinem Programm.
Aber erst mal muss ich gleich sagen, dass ich noch nie mit diesem Basic was gemacht habe und, dass ich die I2C-Schnittstelle hier zum ersten mal benutze. Allerdings in C und es funktioniert bei mir.
Nun zu deinem Programm.
1) Nach dem I2C-Init setzt du noch einen Parameter mit config. Das würde ich tauschen.
2) Vor dem schreiben der Adresse 71 (Leseaufforderung) hast du ein I2C-Start. Ich habe vor dem Start noch einen Stop-Befehl. Eventuell hilft das schon.
3) Du liest Register 02 aus. Das sind nur die beiden untersten Bits von X-Beschleunigungswert. Versuche mal Register 03 zu lesen. Oder las das setzen vom Shadow_dis-Bit und lese dann Register 02 und sofort auch Register 03 und nutze nur 03.

Viel Erfolg
Gruß Sternthaler

Razzorhead
05.07.2010, 22:25
Was kann man denn mit so ein teil tolles machen? ^^
Geschwindigkeit? Zurückgelegte strecke?

LG Raz

Basteltisch
06.07.2010, 19:40
Hallo,
hat jemand schon Erfahrungen mit diesem Gyro gemacht?
Mich Interessiert vorallem die Bascom kompabilität, die tauglichkeit für ausbalancierte Fluggeräte (Tri-Quadrocoper), und die zuverlässigkeit.

Kann jemand zu einem der Punkte schon etwas sagen?

Es grüßt,
Basteltisch

Andree-HB
06.07.2010, 21:42
- Lesen - ;-)

...hat nix mit Gyro zu tun !

Crazy Harry
07.07.2010, 12:11
Falls es am Datenblatt mangelt - das hab ich noch ;)
Ich hab vor ca. einem Jahr bei Bosch Sensortec angerufen und da wurde mir gesagt, daß der BMA020 nicht mehr hergestellt wird.

Frühstücker
15.07.2010, 18:06
Moin Leute,

ich versuche auch Daten aus dem Sensor mit einem ATMega644 zu lesen (via SPI). Leider gibt mein Display für die 8 höchsten Bits der z-Beschleunigung eine 0 aus.


Ich hab das Programm gut kommentiert, sollte leicht verständlich sein.
Sieht jemand von Euch einen Fehler darin? Meines Erachtens habe ich alles beachtet.


#include <avr/io.h>
#include <util/delay.h>
#include "m50530.h"
#include <stdlib.h>


#define DDR_SPI DDRB
#define PORT_SPI PORTB
#define PIN_SPI PINB

#define DD_BMA020_CS PB4
#define DD_MOSI PB5
#define DD_MISO PB6
#define DD_SCK PB7

#define P_BMA020_CS PB4
#define P_MOSI PB5
#define P_MISO PB6
#define P_SCK PB7

#define acc_z 7

#define read 7


void SPI_MasterInit(void)
{
// Set MOSI and SCK output, all others input
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);

// BMA020 ChipSelect is output (low active)
DDR_SPI |= (1<<DD_BMA020_CS);

// Deselect BMA020
PORT_SPI |= (1<<P_BMA020_CS);

// Enable SPI, Master, set clock rate fck/16, SPI Mode 3
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPOL)|(1<<CPHA);
}

void SPI_MasterTransmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
;
}

char getZ(void)
{
// Select BMA020
PORT_SPI &=~ (1<<P_BMA020_CS);

// Send command: Read z_acceleration
SPI_MasterTransmit((1<<read)|(acc_z));

// Send dummy byte
SPI_MasterTransmit(0);

// Deselect BMA020
PORT_SPI |= (1<<P_BMA020_CS);

// Return z acceleration
return SPDR;
}


int main(void)
{
uint16_t z=0;
char string[20];


// Wait 2 ms for the BMA020
_delay_ms(2);

// Initialize LCD and SPI
LCDInit();
SPI_MasterInit();


while(1)
{
// Read z-axis via SPI
z=getZ();

// Convert z To String
itoa(z, string, 10);

// Print z on LCD
LCDWrite(string);

// Set CoursorPosition to [0,0]
LCDSetCursorPos(0,0);
}
return 0;
}


Vielen Dank schonmal und Grüße aus Hamburch

malthy
19.07.2010, 13:23
Hallo,

falls es noch für jemanden von Interesse ist: ich habe die I2C-Kommunikation mit dem Sensormodul mal in BASCOM implementiert. Hier ist ein Beispielcode:


' kleines beispielprogramm zum auslesen des bma020
' malte ahlers 2010
' weitere infos auf malteahlers.de
'
'
' compiler steuerung
$regfile = "m8def.dat"
$crystal = 1000000
$framesize = 64
$swstack = 64
$hwstack = 64
$baud = 9600
$lib "i2c_twi.lbx"
'
' hardware konfigurieren
' - taster
Config Pinb.6 = Input
Portb.6 = 1
Config Pinb.7 = Input
Portb.7 = 1
Config Pind.5 = Input
Portd.5 = 1
Taster1 Alias Pinb.6
Taster2 Alias Pinb.7
Taster3 Alias Pind.5
' - leds
Config Portd.7 = Output
Config Portd.6 = Output
Config Portb.0 = Output
Led_gl Alias Portd.7
Led_rt Alias Portd.6
Led_gr Alias Portb.0
' - i2c
Config Scl = Portc.5
Config Sda = Portc.4
'
' variablen dimensionieren
Dim V(6) As Byte
Dim Ax As Integer At V(1) Overlay
Dim Ay As Integer At V(3) Overlay
Dim Az As Integer At V(5) Overlay
Dim Acc_cntr As Byte
Dim I As Byte
Dim Acc_range As Byte
Dim D2g As Single
Dim S As Single
'
' konstanten
Const Acc_w = &H70
Const Acc_r = &H71
'
' subs
Declare Sub Set_acc_range(byval Range As Byte)
'
' hauptprogramm
Print "acc test!"
Wait 1
'
I2cinit
'
Call Set_acc_range(0)
' messbereich:
' Set_acc_range(0) -> +/- 2g (default)
' Set_acc_range(1) -> +/- 4g
' Set_acc_range(2) -> +/- 8g
'
Do
I2cstart
'
' sensor adressieren
I2cwbyte Acc_w
'
' acc datenregister adressieren
I2cwbyte &H02
'
I2cstop
'
I2cstart
'
' daten lesen
I2cwbyte Acc_r
'
For I = 1 To 5
I2crbyte V(i) , Ack
Next I
I2crbyte V(6) , Nack
'
I2cstop
'
' format konvertieren
Ax = Ax / 64
Ay = Ay / 64
Az = Az / 64
'
' in beschleunigungen umrechnen & ausgeben
S = Ax * D2g
Print "a(x)= " ; S ;
S = Ay * D2g
Print " a(y)= " ; S ;
S = Az * D2g
Print " a(z)= " ; S
'
Toggle Led_rt
Waitms 10
'
Loop
'
End
'
Sub Set_acc_range(byval Range As Byte)
I2cstart
'
' sensor adressieren
I2cwbyte Acc_w
'
' kontrollregister adressieren
I2cwbyte &H14
'
I2cstop
'
I2cstart
' kontrollregister lesen
I2cwbyte Acc_r
I2crbyte Acc_cntr , Nack
'
I2cstop
'
' kontrollregister manipulieren
Acc_cntr.3 = Range.0
Acc_cntr.4 = Range.1
'
I2cstart
'
' kontrollregister zurückschreiben
I2cwbyte Acc_w
I2cwbyte &H14
I2cwbyte Acc_cntr
'
I2cstop
'
' umrechnungsfaktor neu berechnen
D2g = 2 ^ Range
D2g = D2g * 2
D2g = D2g / 512
'
End Sub

Ich habe auf meiner Homepage noch ein paar zusätzliche Informationen zu dem Programm hinterlegt. Hier kann man nachlesen, wenn man mag: http://www.mtahlers.de/index.php?option=com_content&view=article&id=32&Itemid=69

Gruß
Malte

mausi_mick
11.10.2010, 05:40
hallo malthy,
hallo Sternthaler,

Danke für die Code-Beispiele.

Der Basic-Code sieht aus meiner Sicht sehr gut aus und ist gut dokumentiert. Einzig in der Leseschleife wird bei V() ein kleines i verwandt, aber da ist Basic vielleicht gnädig ?

Beim C-Code wäre mir ein wenig Doku hilfreich.

Auch wäre in der ASURO-Umgebung interessant, wie man die Sensordaten
auf dem LCD-Display, das ja auch an I2C hängt, ausgeben kann.

SCL könnte bleiben (MY_I2C_SCL --> PC3/Pin26) aber SDA müsste man wohl umswitchen von PC2/PIN25 für LCD auf z.B. PC4/Pin27 für BMA020.

Werd aber wohl mit dem C-Code testen, da ich von BASIC wenig Ahnung habe.

Gruss mausi_mick

Sternthaler
11.10.2010, 21:21
Hallo mausi_mick,

lange nichts mehr voneinander gehört.

Ich habe mal für dich, natürlich nicht nur ;-), in meinem oberen Post eine Erklärung abgegeben. Ja, ich bin Schuld. Äh, ..., was passiert da eigentlich.
Auch das Datenblatt zum BMA020 kann man da runterladen.
Ohne das Papier kann diese wilde Bitschieberei natürlich nicht interpretiert werden.
Viel Erfolg beim Einbinden in deine Kontroller.

Warum aber willst du SDA auf einen anderen Port hängen?
Wenn du das Display schon über I2C am Asuro angeschlossen hast, kannst du an genau diese beiden benutzten Pins einfach weitere I2C-Bausteine dazu 'hängen'. Also einfach parallel schalten die beiden SDA- und SCL-Leitungen.
Oder habe ich da irgend etwas falsch verstanden in deinem Text?

Gruß
Sternthaler

mausi_mick
12.10.2010, 06:07
Hallo Sternthaler,

Dank für Deine schnelle Antwort.
Mit den Leitungen, das ist bereits geklärt, ich hatte im ASURO-Thread auch nachgefragt und hab mich dann auch nochmal über I2C genauer informiert.
Hab mir gestern nochmal das Basic Programm und die Doku von malthy/mtahlers angesehen, ist recht gut dokumentiert mit den 2 (LSB)-Bits auf den Adressen 02,04,06 und den 8 (MSB-)Bits auf 03,05,07.

Hatte gestern mit Deinen Code-Schnipseln mal geübt, bekam aber nur für x,y,z 0 heraus.
Werd mir Deine Beschreibung oben mal ansehen und versuchen, das irgendwie zum Laufen zu kriegen.

Gruss mausi_mick

Sternthaler
12.10.2010, 08:10
Hallo Mausi_mick,

ja, die Beschreibung von malthy ist echt gut. Vor allem seine Ausführung zur Berücksichtigung vom Vorzeichen ist sehr schön.

Ich kann da leider mit meinem Code bzw. mit der Beschreibung nicht mithalten, da ich zwar auch mit integer-Variablen für x, y und z arbeite und eben nicht um 6 Bit nach rechts schiebe, sondern auch durch 64 dividiere, aber ob dann das korrekte Ergebnis raus kommt kann ich im Moment nicht sagen.
Mein Rechner kann im Moment nämlich noch keinen AVR-Code übersetzten da ich erst seit kurzer Zeit wieder ein lauffähiges System habe und der Asuro noch warten muss.

Ich kann die dir Doku zum BMA020 nur wärmstens empfehlen. Es stehen echt spannende Dinge darin.
Das Teil kann unter anderem zu verschiedenen Situationen Interrupts erzeugen. Freier Fall ist da zum Beispiel so eine Möglichkeit.

Gruß
Sternthaler

mausi_mick
12.10.2010, 09:34
Hallo Sternthaler,

hab mir Deine Beschreibung angesehen, ist eigentlich verständlich.
Dachte zuerst, man müsste auch die LSB um 6 Bit verschieben, da ja aber ein komplettes Byte gesandt wird, ist das wohl nicht nötig ( die entspr. Bits stehen ja bereits links).

Scheint bei mir ein HW-Problem gewewesen zu sein, mit einem
anderen Exemplar hab ich's jetzt zum Laufen gebracht. Zuerst nur die einzelnen Bytes als Integer8 (ret) am Display angezeigt und dann Deine
Umsetzung genommen.
Scheint zu klappen. Werd das aber nochmal besser aufbauen, das Hauptprogramm ändern (Ausgabe der Beschleunigungswerte in einer Schleife , bisher nur eine Messung) und ein paar Fotos (Video?) machen.

mausi_mick
12.10.2010, 12:39
hallo,

hab mal ein paar Fotos gemacht, Video klappt leider nicht, da Werte auf Display bei der Videoauflösung nicht erkennbar. Beschleunigungswerte liegen wohl zwischen ca +-255, in der ersten Displayzeile werden sie in Reihenfolge x,y,z ausgegeben.
Die 2.Zeile ist für Winkel vorgesehen, ist aber noch nicht realisiert.

Gruss mausi_mick

PS: das Display ist ein Minaturdisplay von Pollin, ca 5,2 cm x 2 cm,
Displayfläche ca 3,6 cm x 1 cm, kostete glaube ich um die 2 €

Sternthaler
12.10.2010, 21:03
Hey, super.

Na, da haben wir ja noch einen im Beschleunigungsrausch.
Bei mir habe ich neben der Anzeige auch noch 2 Servos angeschlossen die ich mit den X- und Y-Achsen steuern kann.
Mal sehen was als nächstes auf dem Programm steht.
Als Idee steht auf dem Wunschzettel, dass ich die Schlaglöcher auf meinem Weg zur Arbeit messe. Mit dem Rad natürlich.

Allerdings geht es bei mir im Moment nur schleppend voran da mein PC nach einem totalen Plattenausfall noch nicht wieder komplett bereit ist. Und außerdem nervt die Arbeit aktuell heftigst.

Gut hinbekommen mausi_mick. Im übrigen bist du nicht der erste der hier erst mit dem 2.ten Sensor zum Erfolg kommt.

Gruß Sternthaler

P.S.: Auf deinen Bildern kann man gut sehen, dass du den Messbereich bei +/-2g eingestellt haben müsstest.
Messwert 0-1023 für die 4g => 512 für 2g => 256 für das eine 'normale' g auf der Erde. Du bist kein Alien ;-)

mausi_mick
13.10.2010, 06:30
ja,

+/-2g ist wohl der voreingestellte Wert, hab mich nur gewundert, dass
ich manchmal leicht über die 255 hinauskomme (bis ca 265 glaube ich). Auch müssten bei total ebener Lage x und y auf 0 sein und z auf -255. Der z - Wert liegt bei mir aber max unter 240. Vielleicht gibt's hier doch ein negatives schwarzes Loch in der Nähe oder man ist vom Normort zu weit entfernt .

Gruss mausi_mick

Sternthaler
13.10.2010, 08:27
Normort?
Wo ist denn der.? Doch nicht etwa im Louvre beim Urmeter?

Bei mir sind die Achsen auch nicht nicht symetrisch. Z geht von +240 bis -256.


Gruß Sternthaler

mausi_mick
13.10.2010, 09:02
hallo,

am 45 Breitengrad beträgt g ca 9,8062 m/sxs (in Meereshöhe), hier auf ca 500 m muss ich wohl nochmal ca 1,5 mm/sxs hinzuschlagen, da wär ich dann
bei 9,8077 m/sxs, aber vermutlich liegt hier noch 'ne Goldader drunter, daher werde ich bei den z.Zt. hohen Preisen für das Material meinen Wohnort nicht genauer spezifizieren...

oberallgeier
13.10.2010, 11:14
... hier auf ca 500 m muss ich wohl nochmal ca 1,5 mm/sxs hinzuschlagen ...Leider muss ich Dir - sogar ohne genauere Kenntnis Deiner Bodenschätze - widersprechen. Die Erdbeschleunigung (besser die gegenseitige Anziehungskraft) sinkt mit steigender Höhe (bzw. Abstand der Körper voneinander). Allerdings kann die Beschaffenheit des Untergrundes Höhenunterschiede in der genannten Größenordnung durchaus übertönen. Dagegen sind bekanntlich Hohlköpfe weniger betroffen - wobei nicht abgesichert ist, warum die sich entgegen theoretisch basierter Ergebnisse eher stärker anziehen.

Deiner Rechnung kann ich - bei Vorzeichenwechsel - ansonsten schon zustimmen. Hatte vor vielen Jahren verschiedene Messungen "in der Höhe" gemacht, und das ähnlich eingerechnet. Bei 1180 m MSL bekam ich eine Abminderung um 0,003 m/s² (F. Dubs, Aerodynamik der reinen Unterschallströmung, 1979, Verlag Birkhäuser Basel, Boston, Stuttgart). Das ist auch der Grund, warum ich mich hier auf 812 m (OK Schreibtisch) sooo leicht fühle . . . .

mausi_mick
13.10.2010, 14:01
hallo oberallgeier,

hast recht, wenn man sich schon bei Wikipedia erkundigt, sollte man
es schon genau durchlesen oder sich die Grafik ansehen. Rein gefühlsmässig hätte ich auch eher eine Zunahme (Richtung Erdmittelpunkt) erwartet, sonst wäre wohl auch an Gold leichter ranzukommen.
Da gab's doch mal sowas wie "Reise zum Mittelpunkt der Erde", weiss aber nicht , was darin zu dem Thema stand.

oberallgeier
13.10.2010, 22:07
Hallo Leute,

nicht ganz on topic - aber es betrifft diesen ELV-3-Achs-G-Meter. Vor mir liegt so ein hübsches Teil und ich will das natürlich in Betrieb nehmen. Bisher habe ich null Erfahrung mit I²C. Im Moment bekomme ich dummerweise mein US B-Lab nicht I²C-Logger ingang (das PC-Tool zum lesen, schreiben und senden der Daten läuft nicht - keine Ahnung wieso). Dieser Logger könnte nämlich nach Spezifikation angeblich I2C-Signale bis 200 kHz mitschneiden und I2C-Daten mit 100 kHz senden. Also muss ich selbst etwas basteln um mit dem ELV-Platinchen ingang zu kommen.

Dazu habe ich eine Platine mit mega168, ohne Quarz, derzeit mit 1MHz und angeschlossenem LCD 2x16.

Fragen :
Baue ich die Software mit der Fleury-Lib?
Wird / kann das mit dem 1MHz-quarzlosen Controller laufen - oder mit 8MHz? Oder ist ein Quarz zwingend erforderlich?
Oder gibt es eine sinnvolle Alterntive zum Selbstbau?

Danke für die Antworten - und sorry für das Beinahe-OT.

mausi_mick
14.10.2010, 06:51
hallo oberallgeier,

ich hab das ELV-Platinchen am Atmega8 (Quarz 8MHz), die ASURO-Bib
(hat wohl auch die Fleury-Dateien) mit I2C.c und I2C.h und das Beispiel von Sternthaler aus diesem Thread. Das LCD (2x16 von Pollin) hab ich an einem PCF5... (Porterweiterung) auf Adresse
x40 und den Sensor auf Adresse x70 bzw. x71.
Gib z.Zt. ca alle halbe s die x,y,z - Werte auf dem Display aus.

Hab nur den Eindruck, dass zwar die Auflösung des Sensors mit 10 Bit sehr gut ist, die Genauigkeit ( Übersprechen) aber relativ schlecht.
Auch erreich ich nicht den Maximal-Wert in z-Richtung (+-255) , sondern liege wohl knapp über 230.
Werde aber mal versuchen, über arcsin/cos aus math.h die Winkel zu berechnen, bevor ich da genaueres sagen kann.

Gruss mausi_mick

mausi_mick
14.10.2010, 15:47
hallo,

hab mal ein wenig experimentiert und festgestellt, dass die Werte für+- 1 g für die x,y,z Achse sehr unterschiedlich sind (ist aber auch im Datenblatt angegeben) und der Wert für +-1g von +-256 stark abweicht . Bei meinem Exemplar liegen die Kennlinien in diesem Bereich:
-90° +90°
x: -198 +264
y: -258 +220
z: -232 +228


Ich hab das dann auf 255 normiert und den Nullpunkt entsprechend verschoben.
Damit komm ich dann auf Werte von > 88 ° für die Maximalpositionen,
die auch mit der wirklichen lage des Sensors gut korrespondieren.

Sternthaler
17.10.2010, 01:58
Ach, da beschleunigt der oberallgeier nun auch? ;-)

Bei mir hängt das Ding an einem ATmega644 ohne Quarz. Es läuft somit standardmäßig auch bei einem winzigen MHerzchen. Das Hochtakten im 644 auf 8 MHz geht auch ohne Quarz um noch Daten vom beschleunigten Leben zu lesen.
Und wie mausi_mick schon schrieb, ist die LIB vom Asuro mit dem Fleury-Code funktionsfähig.

@mausi_mick
Wie hast du die Winkel ausgerechnet?
Ich vermute, dass du 'Seiteneffekte' weg läßt und nur den Winkel über die Z-Achse gegen X- bzw. Y-Achse rechnest.
Oder betrachtest du auch eine waagerechte Lage mit einer echten seitlichen Beschleunigung?
Wie ist/sind da die Messwerte zu sehen? Ist Z dann immer noch bei 1g und nur X oder Y 'beschleunigen'? Wie kann man dann ausrechnen, wenn das Teil auch noch schief im Raum liegt, in welchem Winkel ich durch die Gegend sause/beschleunige?
Ach du meine Güte! Ich hoffe, dass du verstehst was ich da eigentlich frage ;)

Frohes Beschleunigen wünscht
Sternthaler

mausi_mick
17.10.2010, 05:23
Hallo Sternthaler,

Ich hatte bei meinem grossen Monowheel (Big-MW) , bei dem ich den MMA7260Q verwende, auch das Problem, dass die Beschleunigungswerte, wenn ich nur z.B. die x-Richtung quer zur Fahrtrichtung betrachtete, von dem im Ruhezustand abwichen, auch wenn das Fahzeug garnicht in x-Richtung geneigt war.
Das lag wohl nicht nur an den "dynamischen" Beschleunigungen z.B. durch den Antrieb, sondern im Wesentlichen daran, dass das Innenfahrzeug nach dem Anfahren eine Schräglage einnimmt ( Es fährt anfangs vorne im Rad hoch, um den Ausennreifen in Drehung zu bringen, nach dem Anfahren (und Erreichen der rel. konstanten Fahrgeschwindigkeit) lag das Innenfahrzeug etwas (ca 20°) nach vorne geneigt im Rad . Dadurch bekam dann die Beschleunigung quer zur Fahrtrichtung nicht mehr den vollen g-Vektor mit.
Ich hab das dann anfangs korrigiert, indem ich die Nullage des Sensors etwas manipuliert habe, werd das jetzt aber wohl mit den unten angegebenen Formeln bzw. der Tabelle machen.


Zu Deiner Frage:


ich hab da vom MMA7260Q/Freescale eine Doku (AN3461), wo ein wenig Geometrie gemacht wird. Da gibt's dann die Winkel

rho = arctan(Ax/sqrt(Ay*Ay + Az*Az))

phi = arctan(Ay/sqrt(Ax*Ax + Az*Az))

und theta = arctan(sqrt(Ax*Ax + Ay*Ay)/Az)

und sqrt (Ax*Ax + Ay*Ay + Az*Az) = 1 g (falls nur Gravitation)

wobei bei theta - nehme ich an - ein Schreibfehler vorliegt

ich rechne mit

theta = arctan(Az/sqrt(Ax*Ax + Ay*Ay))


zusätzlich ist dort auch noch eine Umsetztabelle

von AD-Werten zu Winkeln ( der MMA7260 ist ja ein analoger Sensor).

Ich versuche mal, meinen (wohl nicht sehr schönen und vermutlich auch nicht ganz fehlerfreien) Code zu posten. Kansst Du Dir ja mal ansehen und verbessern.

Gruss mausi_mick


PS: Ich hab mit ELV telefoniert und ihnen mitgeteilt, dass mein
2. Sensor defekt ist. Ich hab dann geäussert, dass es mir lieber wäre , anstelle das defekte hin-und-her zu senden , noch zusätzlich zwei Sensoern portofrei zu erwerben.
Sie waren dann sehr kulant und haben mir ausserdem noch ein Exemplar kostenlos beigelegt.
Die Lieferung erfolgte dann auch innerhalb von 2 Tagen, nachdem ich bei den ersten Exemplaren mehr als 3 Monate gewartet hatte

oberallgeier
17.10.2010, 17:24
Hallo alle,

puhhhh. Na ja, ich bekomme wenigstens Daten heraus.

Chip verdrahtet nach Bau- und Bedienungsanleitung 91521 von ELV, Bild 7. I2 C-Bibliothek von PFleury und das "Programmschnippsel für die Neugierigen" von Sternthaler. Sternthalers Programmschnippsel an die Wortwahl (Befehle) von PF anpassen. Irgendwann wirds dann fehlerfrei compiliert. Flashen. Einschalten.

// ================================================== ===============================
void DAA_lcd(void) // Daten lesen und Ausgabe aufs LCD-Modul
{ //
char zahlwort[5];

lcd_init(LCD_DISP_ON); // Initialisiere Display, Cursor aus
lcd_clrscr(); // loesche LCDisplay, Cursor 1 Zeile, 1 Spalte
lcd_puts ("L168-10x31, 17Okt10 1730");
waitms ( 10); //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - Es folgt die Datenerfassung, vergleiche dazu Sternthaler in
// https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=507498#507498
//
// ----------------------------------------------------------------------------
// Defines: Adresse vom BMA020-3D-Beschleunigungssensor
//
#define I2C_BMA_W 0x70
#define I2C_BMA_R 0x71
//
unsigned char ACK, NAK;
int16_t x, y, z;
uint8_t ret;
uint16_t wloop;
wloop = 0;
//
// ----------------------------------------------------------------------------
// Die Werte aufs LCD schreiben
lcd_clrscr(); // loesche LCDisplay, Cursor 1 Zeile, 1 Spalte
// 012345678901234567890123
lcd_puts ("Wertx Werty Wertz ");
// ----------------------------------------------------------------------------
// Lesen von 6 Registern ab Register 0x02. X, Y, Z-Koordinate
// Ab hier Befehle ähnlich Sternthaler, aber aus der Fleury-Lib
//
while (1) //
{ //
wloop++; // Loop hochzählen
//
i2c_init(); //
//
ret = i2c_start (I2C_BMA_W);
ret = i2c_write (0x02);
i2c_stop ();
//
ret = i2c_start (I2C_BMA_R);
ret = i2c_read (ACK); x = (int16_t)ret;
ret = i2c_read (ACK); x = x | ((int16_t)ret << 8); x /= 64;
ret = i2c_read (ACK); y = (int16_t)ret;
ret = i2c_read (ACK); y = y | ((int16_t)ret << 8); y /= 64;
ret = i2c_read (ACK); z = (int16_t)ret;
ret = i2c_read (NAK); z = z | ((int16_t)ret << 8); z /= 64;
i2c_stop ();
//
// Die Werte für X, Y, Z-Koordinate sind gelesen
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Die Werte aufs LCD schreiben
//
utoa(x, zahlwort, 10); //
lcd_gotoxy( 1, 1); // Spalte 2 {0, 23} in Zeile 2 {0, 1}
lcd_puts(zahlwort); //
waitms( 1); //
//
utoa(y, zahlwort, 10); //
lcd_gotoxy( 9, 1); // Spalte 19 in Zeile 1
lcd_puts(zahlwort); //
waitms( 1); //
//
utoa(z, zahlwort, 10); //
lcd_gotoxy(18, 1); // Spalte 19 in Zeile 1
lcd_puts(zahlwort); //
waitms( 10); //
if (wloop == 1000) //
break; //
} // Ende von while (1)
//
waitms( 5000); //
lcd_gotoxy(0, 1); // Cursor auf Anfang untere Zeile
// 012345678901234567890123
lcd_puts (" Datenausgabe Ende "); // Text ausgeben

return;
}
Schön, es gibt sogar eine Ausgabe am LCD - nachdem ich den UPULLUP (auch) auf +5V gelegt hatte. Aber die Ausgabe war nicht so richtig akzeptabel: die x-Werte schwanken um drei Digits, der Rest ist stabil. Wenn ich die Versorgung - Vcc und GND - von der Sensorplatine abklemme, dann wird nur der Text, nicht aber die Zahlenwerte angezeigt (Controller bleibt hängen), auch die "Ende Messung"-Meldung bleibt aus.

//012345678901234567890123 - - Die folgenden 2 Zeilen symbolisieren das LCD 2x24
| Wertx Werty Wertz |
| 65533 0 65532 |
4
5
Ahhhh - da war doch diese Geschichte mit den 10k von SCL und SDA nach Vcc. Ok, das ist schnell gemacht. Aber es ändert sich nix. Da die Gravitation nach Lage des Sensors gerade in Z-Richtung groß ist (ich habs ja nicht am Kniebrett und teste es in Formel1-Kurvenfahrt) - habe ich offenbar etwas falsch gemacht. Weiß jemand was? Danke im Voraus.

Sternthaler
17.10.2010, 18:13
Hallo oberallgeier,

du nutzt nach dem Lesen von x, y und z die Funktion utoa(). Mir scheint es angebracht zu sein, dass du itoa() benutzen solltest. u sollte für UNsigned stehen. i steht für Integer und damit signed.
Auch die Variable zahlwort[5] solltest du länger machen. Im String ist IMMER das letzte Zeichen das Byte 0 als Abschlußzeichen. Netto also 4 Byte für Text. Ein Vorzeichen, Und schon wird es knapp.


Hallo mausi_mick,

oh, ich glaube, dass mir das von dir angegebene "sqrt (Ax*Ax + Ay*Ay + Az*Az) = 1 g (falls nur Gravitation)" schon echt auf die Sprünge hilft um geistig weiter zu kommen.
Nun fehlt mir zwar noch jede Menge weitere Mathe um irgendwann auch mal nur ansatzweise sagen zu können was das Teil im Raum macht, aber da verlasse ich mich lieber auf euch/dich.

Dein Code sieht gut aus.
An einer Stelle hätte ich noch einen Satz Klammern spendiert beim casten:
DU: xn = (int16_t)(double) xn * x_norm;
ICH: xn = (int16_t) ( (double) xn * x_norm);

Essen ist fertig.
Und tschüß
Sternthaler

oberallgeier
17.10.2010, 18:44
Hi Sternthaler,

danke, das "utoa"-Problem war mir beim Abendessen aufgefallen. Hatte ich vorhin repariert - und schon gehts ohne diese großen Werte. X (das ist Richtung meines Rückens) ist jetzt negativ - also beschleunigt mein Schreibtisch leicht mit Werten -1 bis -3, die anderen Werte sind stabil auf Null.

Deine Anpassung an die char-länge - danke - hat an den vermurksten Werten nix geändert.

Nachtrag: 17. 10. 2010, 23:24 (Nachtschwärmer haben tagsüber Nachteile oder: eigen Fehler währen am längsten)
Irgendwie ging beim Code-Aufräumen etwas verloren: ACK und NAK schwebten irgendwo im begrenzten Werteraum des unsigned char. Kaum hatten die beiden den Wert 1 und Null (wieder) bekommen - dann liefs auch. (Wers nicht glaubt, darf auf das Bildchen klicken).

............http://oberallgeier.ob.funpic.de/3xG-meter_1869_kl.jpg (http://oberallgeier.ob.funpic.de/3xG-meter_1869.jpg)
............Ein Probelauf mit dem Testaufbau

mausi_mick
18.10.2010, 06:18
hallo oberallgeier,

Gratulation !

Das Ergebnis sieht zwar noch etwas furchtbar aus (für die recht gute Linearität von 0,5% FS), aber da sind ja noch die Faktoren Sensivity (für 1g):

yx: 205 ... 256 ... 307
z : 166 ... 256 ... 346

zero offset g : +/- 220mg

und die Crossoversensivity von < 2%

(neben den temperatur - und alterungsbedingten Abweichungen).

Es gibt also noch viel zu manipulieren .

Viel Erfolg

mausi_mick

Sternthaler:

Werd das mal mit dem Casting ausprobieren.
Winkelberechung:
In der AN von Freescale ist auch noch eine Skizze, die das etwas veranschaulicht.

Oder dieser Link: http://books.google.de/books?id=cUY-3H3bERgC&pg=PA60&lpg=PA60&dq=3d+winkel+wurzel&source=bl&ots=DUeM2ARblN&sig=XG0EwTN-wtrfAmvDZG9BVdUhgtY&hl=de&ei=Lti7TNaSHsKOswaY77ipDQ&sa=X&oi=book_result&ct=result&resnum=1&ved=0CBYQ6AEwAA#v=onepage&q&f=false

(

mausi_mick
18.10.2010, 15:16
hallo Sternthaler,

hab da nochmal etwas experimentiert und die Umrechung der Beschleunigungswerte mit dem arcsin gemacht. Das scheint besser zu klappen. Nur ist die Funktion bei Messwerten nahe 256(entspricht 90°) nicht grad sehr sensitiv.

Gruss mausi_mick

ElchiMtr
18.10.2010, 19:59
Hey,

Hat jemand schon mit dem Gedanken gespielt durch 2xIntegieren eine Positionsänderung zu messen ?
Wie seht ihr da die Chancen auf Erfolg ?

Martin.
18.10.2010, 21:16
Wenn mich mein Mathematischer Sinn nicht trügt, müsstest du dafür trotzdem noch die Anfangsgeschwindigkeit wissen, die du allein aus der Beschleunigung nicht erhälst. Dadurch kommt dann ein linearer Fehler rein, den du nicht so leicht rausbekommst.

ElchiMtr
18.10.2010, 21:24
Das stimmt man müsste auch noch die Anfangsposition kennen, aber du kannst auch mit messen anfangen, wenn der Bot steht. Dann nimmst du v0 als Null und s0 auch als Null. und Problem gelöst mit der Methode bist du dann nicht schlechter als nen Radencoder. Die Frage ist eigentlich nur ob des ni der Umsetzung auch so toll ist, wie das klingt und wie gut die Ergebnisse sind. Kann sich wer vorstellen das des klappt.

oberallgeier
18.10.2010, 21:38
Hat jemand eine Erklärung dafür, dass der Sensor von Bosch ein linksweisendes Koordinatensystem verwendet? Das scheint mir etwas unüberlegt, da die Mathematik ihrem Koordinatenformalismus bei orthogonalen, kartesischen Koordinaten standardmässig ein rechtsweisendes System zugrundegelegt hat. Bei etlichen Umrechnungen muss man jetzt aufpassen, um nicht Vorzeichenfehler einzubauen. Anm.: ich rechne noch nix um, ich wühle mich erst durch das data sheet - die unübliche Koordinatenkonvention war mir schon auf der Platine aufgefallen.

Zur Integrationsfrage (Integration ist ja gerade zum Modewort geworden) : Die Auflösung ist 10 bit, da hat man schon mal mindestens 0,1% Fehler alleine bei der Messung. Wie die Reproduzierbarkeit ist, kann ich nicht mal abschätzen. Aber eine Wegmessung nach zweimaliger Integration der Beschleunigung kommt mir nicht nur mit diesem Bauteil nicht vielversprechend vor.

ElchiMtr
18.10.2010, 22:09
wenn ich ehrlich bin glaub ich auch nicht das es funktionieren würde. Ich wollte es nur mal zur Sprache bringen. Ich gebs zu als Student bin ich etwas realitätsfremd und theoretisch ausgebildet. Es ist schade, dass ich man nicht lernt ob solche methoden funktionieren können.

Allerdings muss ich dir zustimmen was das Koordinatensystem betrifft Rechtssysteme sind zum rechnen, besser geeignet wenn mans so kennt. Ohne dich angrifen zu wollen vlt hast du den Sensor nur falschrum eingebaut und das was dein Oben ist sollte Unten sein.

oberallgeier
18.10.2010, 22:14
... vlt hast du den Sensor nur falschrum eingebaut und das was dein Oben ist sollte Unten sein ...Hääää? Was hat die Einbaurichtung mit dem internen Sensoraufbau zu tun? Hast Du diese Platine? Kennst Du das Datenblatt - S. 37, Fig. 18 ?

ElchiMtr
18.10.2010, 22:21
nein. ich hätte mich vielleicht besser belesen bevor ich etwas schreibe. Ich hatte das nur für möglich gehalten, da mir auf einem anderen Gebiet genau so schon selbst fabriziert habe. Das solte kein Vorwurf sein. lassen wir das einfach und ich gebe zu das ich keine Ahnung habe warum des so ist.

mausi_mick
19.10.2010, 04:20
Hallo oberallgeier,


ich hab mir das nochmals angesehen (auch Page 37, Figure 18 ),
ich vermute, die meisten ( alle ?) 3-Achsen Beschleunigungssensoren
haben ein rechtshändiges System ( z.B. SCA3000, BMA020, BMA145,SMB380,SMB830, ADXL330, ADXL335), nur ist auf dem Platinchen
von ELV das nicht richtig eingetragen: Die Pfeilspitze der z-Achse müsste zur Platinenoberseite(hier (bei SMD) richtiger: Bestückungsseite der SMD-Bauteile) zeigen .

Den Vorschlag durch Integrieren Geschwindigkeit und /oder Weg zu ermitteln,
finde ich nicht schlecht, obwohl man - wie oberallgeier beschrieben - da nicht ein genaues Egebnis erwarten darf. Auch hängt das wohl sehr von der Anwendung ab: Auf glattem Fahrweg geht das vielleicht, in unruhigem Gelände integriert man wohl nur irgendwelche Erschütterungen/Kollisionen.





Gruss mausi_mick

oberallgeier
19.10.2010, 07:23
... ich hab mir das nochmals angesehen ... auf dem Platinchen ... nicht richtig ...Danke, mausi_mick. Genauso sehe ich es auch, die Darstellung im doc, S 37, Fig 18 ist ja wirklich eindeutig. Wobei ich den Aufdruck auf der Sensorplatine nicht als falsch ansehe, nur als missverständlich - zumindest für mich :- ( .

Anderes Thema: es ist ja meine erste I²C-Erfahrung. Ich bin von der Schnelligkeit überrascht. Einschließlich Ansteuerung des LCD brauche ich für eine Ausgabe der 3 Werte 11,6 ms. Dies allerdings noch ohne Prüfung im Sensor, ob neue Werte vorliegen.

oberallgeier
23.10.2010, 10:40
Bits 5, 6 and 7 of register addresses 14h do contain critical sensor individual calibration data wich must not be changend or deleted by any means.

In order to proberly modify addresses 14h for range and/or bandwidth selection using bits 0, 1, 2, 3 and 4, it is highly recommended to read-out the complete byte, perform bit-slicing and write back the complete byte with unchanged bits 5, 6 and 7.

Otherwise the reported acceleration data may show incorrect results.Also: Byte auslesen und dezimal und binär anzeigen. Danach neue Werte setzen und Byte zurückschreiben. Zur Kontrolle eine kleine Routine, zwei Tasten aufs Steckbrett als Wahlhelfer (Auswahl der Messwerte, Routinen, Bitposition und -änderung).

Getestet musste die richtige Funktion werden, bevor der erste Schreibvorgang gemacht wird. Dazu ist das Byte 14h im Auslieferungszustand nicht nützlich: -128/0b10000000, da musste zum Test der Ausgabe ein anderer Wert her. Jetzt läuft die Darstellung glaubhaft und prima.

............http://oberallgeier.ob.funpic.de/rng+bnd_1872_kl.jpg (http://oberallgeier.ob.funpic.de/rng+bnd_1872.jpg)

Auf den kurzen Code zur int-nach-bin-Wandlung bin ich fast stolz. Siehe z.B. Zeile 45 - 48.


// ------------------------------------------------------------------------------ -
// Lesen des Register 0x14, Range und Bandwidth
//
i2c_init(); //
ret = i2c_start (I2C_BMA_W); // Schreibbefehl auf Device-Adresse 0x70
ret = i2c_write (0x14); // Zu lesende Adresse für Range+Bandwidth
i2c_stop (); // Stop
//
ret = i2c_start (I2C_BMA_R); // Lesen bis zum Stop auf Device-Adresse 0x71
brb = i2c_read (NAK); // brb = Byte mit Range + Bandwidth
i2c_stop (); // Steuerwert Range+Bandwidth wurde gelesen

brb = 86; // <<<<<##### Diese Zuweisung NUR testweise <<<<<#####

//
// ------------------------------------------------------------------------------ -
// ------------------------------------------------------------------------------ -
// Wert von Range und Bandwidth dezimal und binär aufs LCD schreiben
//
lcd_clrscr(); // loesche LCDisplay; Cursor Zeile 0 Spalte 0
// 012345678901234567890123
lcd_puts ("Rng+Bndwth : dez"); //
//
itoa(brb, zahlwort, 10); //
lcd_gotoxy(14, 0); // Spalte 11 {0 bis 23} in Zeile 0 {0 bis 1}
lcd_puts(zahlwort); // = neunte Spalte in erster Zeile
lcd_gotoxy( 0, 1); // Spalte 0 in Zeile 1
// 012345678901234567890123
lcd_puts ("Biner = - - - - - - bin"); // = nullte Spalte in zweiter Zeile
ae[0] = 225; // Umlaut a
ae[1] = 0; // Stringende
lcd_gotoxy(3, 1); // Spalte 3 {0 bis 23} in Zeile 1 {0 bis 1}
lcd_puts(ae); // = schreibe "ä" von Binär
//lcd_puts ("Binär = 0b bbbb bbbb bin "); // Binär = korrekt geschrieben
//
// ------------------------------------------------------------------------------ -
// bsg[15] für Konvertierung nach binär und Darstellung: "0b bbbb bbbb"
//
bsg[0] = 48; // dez48 = ASCII 0
bsg[1] = 98; // dez98 = ASCII b
bsg[2] = 30; // dez30 = ASCII Space
//
bsg[7] = 30; // dez30 = ASCII Space
// Bis hierher ist es nur "Vorspann"
for (ia = 1; ia <= 4; ia++) // Erstes Nibble übersetzen nach Binär
{ //
bsg [ia+2] = ((IsBitSet (brb, (8-ia))) + 48);
} // Ende for (ia = 1; ia <= 4; ia++)
// Die ersten vier Bits sind abgearbeitet
for (ia = 5; ia <= 8; ia++) // Übersetzen des zweiten Nibbels nach Binär
{ //
bsg [ia+3] = ((IsBitSet (brb, 8-ia)) + 48);
} // Ende for (ia = 7; ia == 4; ia--)
// Die vier Bits des zweiten Nibbels sind abgearbeitet
// ------------------------------------------------------------------------------ -
// ------------------------------------------------------------------------------ -
// Null in das Feld des Ausgabestrings als Abschlusskennung
bsg[12] = 0; //
// Dekodieren ist abgeschlossen
// ------------------------------------------------------------------------------ -
// ------------------------------------------------------------------------------ -
// Binären Wert aufs LCD schreiben

Sternthaler
05.11.2010, 00:25
Hallo mausi_mick,

nun finde ich auch deinen Link zu dem 3D-Spiele-Buch. Ich glaube, ich muss da mal kaufen gehen. Die Leseprobe sagt mir schon, dass ich den Matheteil abschreiben kann und der restliche Text reicht mir aus. Guter Tipp.


Hey oberallgeier, nicht schlecht dein Binärwandler.

Zum Bit-Anzeigen hätte ich folgendes geschrieben:
unit8_t offset, wanderbit;

offset = 3;
wanderbit = 0b10000000;
for (i = 0; i < 8; i++)
{
bsg [offset] = ( brb & wanderbit >> i) ) ? '1' : '0';
if i = 4 offset++;
}
Kannst du mir mal den Gefallen tun und das Zeug von mir mal kompilieren und die benötigten Bytes posten? (Mein PC ist leider immer noch AVR-frei. Sch... Firma)
Ich tippe fast, dass deine Variante sparsamer ist.

Gruß Sternthaler

P.S.: Das mit der Geschwindigkeits- / Positionsmessung kommt mir noch schlimmer als oben angegeben vor.
Klar hat der Wandler 10 Bit Auflösung. Aber kann man die tatsächlich nutzen wenn ich in einer (Fahrt-/Beschleunigungs)-Richtung messe? Bleiben da nicht nur 9 Bits als relevanter Messwert? Und somit nur 0.2% Genauigkeit?

oberallgeier
05.11.2010, 16:44
... Das mit der Geschwindigkeits- / Positionsmessung kommt mir noch schlimmer als oben angegeben vor ... 9 Bits als relevanter Messwert? ...Da stelln ma uns mal jaaanz domm.

Wat is denn integrierbar? Doch nur eine Funktion. Was ist eine Funktion? Das ist, kurz gefasst, doch die Zuordnung von Elementen der Definitonsmenge an eine Zielmenge mit all den bekannten Dingen: Stetigkeit, Eindeutigkeit etc. Als Definitionsmenge für den Weg, entlang dem die Beschleunigung existiert, ebenso für die Zeit, während der die Beschleunigung dauert, gelten alle Elemente des (reellen Zahlenraumes) http://oberallgeier.ob.funpic.de/reell.gif. Wir haben aber nur einige wenige diskrete Zahlenwerte. Grund ist die endliche, nicht eindeutig fassbare Wandelzeit und die wählbare Auflösung mit max. 1024 Werten. Daher ist - streng genommen - die Funktion garnicht stetig integrierbar. Es liegen ja keine Werte d2x/dt² vor, sondern nur Δ2x/Δt². Genaugenommen ist die "Funktion" eben nur durch diejenigen Näherungsrechtecke "integrierbar", die durch die existierenden Punktpaare definiert sind (Herr Riemann freut sich gerade). Lauter Fallstricke, die die numerische Mathematik der Analytik in den Weg legt. Und damit kommen Sternthalers Fehler hinein.

Zweimal aufintegriert mit solchen Fehlern gilt dann eher als Schätzung.

Da ein Bild mehr als tausend (holprige Theorie-) Worte sagen kann, hier mal zwei Beispiele für identische Messwerte für zwei unterschiedliche Beschleunigungsverläufe . . . . . der Rest ist offensichtlich. Dabei wäre der Glitch im ersten Abschnitt sogar noch gesondert zu diskutieren. Die Rasterpunkte stellen die ausschließlich möglichen Zeit- und Beschleunigungswerte dar *ggg*.

............http://oberallgeier.ob.funpic.de/beschleunigg.jpg

Verbessert mich, wenn ich daneben liege (bin von der heutigen Bergtour noch ziemlich ko).

Sternthaler
06.11.2010, 17:34
Oh, ja!
Domm kann ich ganz viel. (Und wenn dann noch etwas Brennendes im Töpfchen dabei ist, ist der Abend gerettet.)
Ausserdem sollte ich mal so langsam lernen mich nicht in mathematische Angelegenheiten einzumischen.

Nee, den Riemann meinte ich aber auch nicht. Ist mir schon klar, dass ein System mit Messzyklen 'dazwischen' keine Realität hat.
Was ich P.S.'en wollte ist meine Befürchtung, dass ich für eine positive Beschleunigung nur die 9 Bits habe und da vermute ich, dass dies die Begrenzung darstellt.

Meine Bauch-Begründung:
[Sternthaler-Theorem]
- Fahrzeug steht: Nix zum Integrieren vorhanden -> Ergebnis: 0 m/s
- Fahrzeug beschleunigt auf Maximum: Nur 9 Bits, die mir beim Rechnen zur Verfügung stehen.
- Fahrzeug hält die Geschwindigkeit: Nun ja; Riemann und Co. berechnen weiterhin die Maximalgeschwindigkeit.

Ich nutze also bei der Beschleunigung überhaupt nicht das 10-te Vorzeichenbit. Somit habe ich, um deine Rasterpünktchen zu erwähnen, ja auch nur die Hälfte auf der Y-Achse und somit geht wieder ein Teil der Realität 'dazwischen' verloren.
[/Sternthaler-Theorem]

Ansonsten kann ich jetzt nur sagen, dass du dir viel Mühe gemacht hast um bei mir ein Lichtlein anzuzünden.
Vor allem dein "http://oberallgeier.ob.funpic.de/reell.gif" gefällt mir sehr gut ;-).

Ach und natürlich noch etwas:
Meine Code zum Binärrechen ziehe ich erst mal zurück.
Dank oberallgeier sind da viele Tippfehler entdeckt worden, die das Zeug nicht wirklich nutzbringend erscheinen lassen. (Vor allem das Zählen von Klammern muss ich noch üben.)

Gruß Sternthaler

oberallgeier
06.11.2010, 18:33
... Sternthaler ... Beiträge: 999 (Stand 06. Nov. 2010, 19:12) ...Huiiii - da muss ich jetzt aufpassen, damit ich Dir zu Deinem Tausender gratulieren kann.


... Meine Code zum Binärrechen ziehe ich erst mal zurück ...Ähhhh - und die Verschworenen dürfen den auch nicht mehr zur Kenntnis nehmen? Was solls denn mit ein paar Klammern mehr oder weniger - wos grad einen witzigen Thread gibt, (https://www.roboternetz.de/phpBB2/viewtopic.php?t=56684) über so viele Jammern in C - ich meine ein jammerThread über die Klamme.. . . . mist, jetzt hab ich den Faden verloren. Schade - Dein Code hätte mich interessiert. Weil Du ja ziemlich vorbildliches C schreibst. Aber um das Maß für verwuchselte Bechstaben zu füllen: ich hab mit meinem Code die Binärdarstellung aus der Dezimalzahl gerechnet - da ich leider keinen Binärrechen habe. Übrigens war ich über das Gelingen meines ersten I 2C-Projektchens so happy, dass ich die Konsequenz aus dem Vorzeichenbit übersehen habe. Immerhin wäre dann die feinste Auflösung (Range 2g) schon 40 mm/s² - (ich muss mal sehen, ob der asuro so viel - oder mehr - schafft). Also - Sternthaler macht klug.

@Sternthaler: Machs wie alle - nimm mich einfach nicht ernst.

TJ_99
07.11.2010, 18:54
Hallo zusammen,

ich arbeite mit dem BMA150, der ähnlich ist zum BMA020. Den Sensor habe ich mit einem Robi von Conrad(PRO BOT 128) verbunden. Die Kommunikation zwischen den beiden Komponenten habe ich über die I2C Schnittstelle realisiert und ich programmiere auf der Plattform von Conrad mit Hilfe von C-Conrol (Programmiersprache ist Compact C, ähnlich zu C).

Eure Beiträge bzgl. dem Auslesen der Register hat mit gut geholfen. Es sollen die Beschleunigungen ausgelesen werden während mein Robi fährt.

Über Multithreads habe ich die beiden Programme verbunden, damit die zwei Programme nahe zu parallel ablaufen.

Der Robi fährt und ich bekomme auch Werte ausgelesen, nur ändern diese sich nur im Werteberecih von +/- 1g.
Wie kann ich festlegen, ob ich mit 2g, 4g oder 8g arbeiten möchte? Laut BOSCH Datenblatt steht dazu das Register 14 (Bit 3 und 4) zur Verfügung.
Aber muss ich jetzt in das Register reinschreiben?

Hab euch mal mein Programm angefügt.


Grüße TJ



//Die Beschleunigungen in x,y und z Richtung sollen mithilfe des BMA150 und dem PRO BOT128 ausgelesen werden


void main(void)
{


word adresse;
adresse=0x02;

int x_long,y_long,z_long;
unsigned int x_short,y_short,z_short;
float x,y,z;
byte bma_r,bma_w;
bma_r=0x71;
bma_w=0x70;

PRO_BOT128_INIT();
I2C_Init(I2C_100kHz);
DRIVE_INIT();

Thread_Start(1,thread1);
Thread_Delay(10);

/* Thread_Start(2,thread2);
Thread_Delay(10);*/

do
{
I2C_Start();
I2C_Write(0x70);
I2C_Write(adresse);
I2C_Stop();

I2C_Start();
I2C_Write(0x71);

x_short=I2C_Read_ACK();
x_long=I2C_Read_ACK();

x_long=(((x_long)*4)*+(x_short/64));

if (x_long > 511)
{
x_long= (x_long - 511);
x_long= (511 - x_long);
x_long= (x_long*(-1));

x= (x_long * 0.00390625);
}
else
{
x= (x_long * 0.00390625);
}

y_short=I2C_Read_ACK();
y_long=I2C_Read_ACK();

y_long=(((y_long)*4)+(y_short/64));

if (y_long > 511)
{
y_long= (y_long - 511);
y_long= (511 - y_long);
y_long= (y_long*(-1));

y= (y_long * 0.00390625);
}
else
{
y= (y_long * 0.00390625);
}


z_short=I2C_Read_ACK();
z_long=I2C_Read_NACK();

z_long=(((z_long)*4)+(z_short/64));

if (z_long > 511)
{
z_long= (z_long - 511);
z_long= (511 - z_long);
z_long= (z_long*(-1));

z= (z_long *0.00390625);
}
else
{
z= (z_long *0.00390625);
}

I2C_Stop();

float str[4];
str[1]=x;
str[2]=y;
str[3]=z;

Str_Printf(str,"%1.2f",x);
Msg_WriteChar(97);
Msg_WriteChar(120);
Msg_WriteChar(61);
Msg_WriteText(str);
Msg_WriteChar(13);

Str_Printf(str,"%1.2f",y);
Msg_WriteChar(97);
Msg_WriteChar(121);
Msg_WriteChar(61);
Msg_WriteText(str);
Msg_WriteChar(13);

Str_Printf(str,"%1.2f",z);
Msg_WriteChar(97);
Msg_WriteChar(122);
Msg_WriteChar(61);
Msg_WriteText(str);
Msg_WriteChar(13);
Msg_WriteChar(13);

}while(1);

}

oberallgeier
07.11.2010, 19:10
... Register 14 (Bit 3 und 4) ... Aber muss ich jetzt in das Register reinschreiben ...Genau das musst Du tun. Dazu steht im Datenblatt des BMA020 etwas mit "Important notes . . ." - und deswegen lese ich erst das Statusbyte in Register 14h aus, bevor ich ein Bit setze und das geänderte Byte zurückschreibe.

TJ_99
07.11.2010, 20:47
Hallo Oberallgeier,

danke für deine Antwort. Ich kann also wieder über i2c schreiben und lesen auf das Register 14 und anschließend Daten hineinschreiben!?

Kann das dann so aussehen?

Gruß
TJ


void thtead3(void)
{

byte data;
word direction, range;
direction=0;

I2C_Start();
I2C_Write(0x70);
I2C_Write(0x14);
I2C_Stop();

I2C_Start();
I2C_Write(0x71);

data=I2C_Read_NACK();

if(direction==0)
{
range=2;
}
else
{
range=4;
}

I2C_Write(0x14 & 0b00011000 >> 3);
I2C_Stop();

}

michael_1104
11.11.2010, 21:19
Hi Leute,

bin neu hier im Forum und habe direkt mal eine Frage zum BMA020 Beschleunigungssensor und dem I2C Bus. Ich benutze das Modul von ELV, welches ich an meinen AtMega8 angeschlossen habe. Die Messwerte gebe ich mir anschliessend über den UART aus. Anbei mal mein Code, ich benutze die I2C Lib von P. Fleury. Könntet ihr mal schauen, ob der Code so in Ordnung ist. Denn die Daten die ich ausgebe, machen mich ein wenig stutzig (3328, 3330, sowas in der Art).



#include "data_logger.h"

#define I2C_BMA_W 0x70
#define I2C_BMA_R 0x71


int main()
{
io_init('D', 0xF0);
i2c_init();

char buf[16];

set_port('D', 0b00110000);

int16_t x, y, z;
uint8_t ret;
unsigned char ACK, NAK;
ACK = 1;
NAK = 0;

while(1)
{
ret = i2c_start(I2C_BMA_W);
ret = i2c_write(0x02);
i2c_stop();

ret = i2c_start(I2C_BMA_R);

ret= i2c_read(ACK); x = (int16_t)ret;
ret= i2c_read(ACK); x = x | ((int16_t)ret << 8);

ret= i2c_read(ACK); y = (int16_t)ret;
ret= i2c_read(ACK); y = y | ((int16_t)ret << 8);

ret= i2c_read(ACK); z = (int16_t)ret;
ret= i2c_read(NAK); z = z | ((int16_t)ret << 8);
i2c_stop();

itoa(x, buf, 10);
uart_send_string(buf);
uart_send_string("\t");
itoa(y, buf, 10);
uart_send_string(buf);
uart_send_string("\t");
itoa(z, buf, 10);
uart_send_string(buf);
uart_send_string("\r");
uart_send_string("\n");
_delay_ms(100);
}
return 0;
}



Der Code ist dem im Forum sehr ähnlich, lediglich erhalte ich keine plausible Ausgabe, ich erwarte: wenn der Sensor in Ruhe liegt, Werte um 0 herum.

Vielen Dank schonmal für die Hilfe

oberallgeier
11.11.2010, 21:47
Tja, was soll ich sagen. C&P ist doch eigentlich recht einfach. Man muss aber dann auch alles rauskopieren, was der Sternthaler, der Gute, reingeschrieben hat. Dann klappts auch mit den Werten.
... ob der Code so in Ordnung ist ...Nein, ist er nicht. Schau Dir mal das Original nochmal an und vergleiche es mit Deinem Code.
... Der Code ist dem im Forum sehr ähnlich ...Er ist so ähnlich, dass ich das Original daran erkenne. Aber . . . .

michael_1104
12.11.2010, 11:22
Sry, habe ich übersehen... Jetzt passt es!
Danke!

TJ_99
23.11.2010, 10:29
Hallo an alle,

ich habe noch mal mein Programm umgeschrieben bzgl. des g-Wertes.
Aber irgendwie ändert er sich nie bei mir was mache ich falsch?

Über eine kleine Hilfe von Euch wäre ich sehr dankbar.

Gruß
TJ

void g_Werte(void)
{

word adresse_g;
byte data;
adresse_g=0x14;

I2C_Start();
I2C_Write(0x70);
I2C_Write(adresse_g);
I2C_Stop();

I2C_Start();
I2C_Write(0x71);

data=I2C_Read_NACK();
I2C_Write(data & 00000000 ); //hier werden jetzt 2g eingestellt

I2C_Stop();

}

kaddi1989
25.11.2010, 17:27
Hallo!

Ich kann bei meinem Beschleunigungssensor die Daten mit Bascom und einem atmega88 auslesen. Jedoch bin ich noch Anfänger bei uc und bascom und habe folgendes Problem/Frage:

Ist es irgendwie möglich die Daten tabellarisch im Editor oder Excel abzuspeichern? Würde mit den Daten später gerne eine FFT machen?

Gruß

Kati

oberallgeier
26.11.2010, 21:12
Hi Kati,
willkommen im Forum und viel Erfolg bei Deinen Projekten.

... Ist es irgendwie möglich die Daten tabellarisch im Editor oder Excel abzuspeichern ...iUmfangreichere Messdaten hatte ich (z.B. bei meinem MiniD0) im Controller in Feldern wie mess03[100] notiert und am Ende der Messsequenz über die UART/RS2 32 ausgegeben. Die Messsequenz ist durch die Größe des SRAM begrenzt, daher hatte ich für umfangreichere Messungen statt eines sonst ausreichenden mega168 einen m328 genommen. Natürlich könnte man die Daten auch ins EEPROM schreiben. Diese Variante hatte ich nicht genutzt, weil Schreiben ins EEPROM deutlich langsamer geht als Daten im SRAM zu halten. Das ebenfalls langsame Lesen aus dem EEPROM würde bei der Datenausgabe über die serielle Schnittstelle kein Nachteil sein. Ich hatte deswegen Platzprobleme, da meine Daten größer als 1 Byte waren und bei 2-Byte-Feldern ist eben der Platz schneller alle. Wie Du mit Deinem m88 auskommst, siehst Du ja (ähhh - nun weiß ich nicht wie Du programmierst - bei mir, in C, im AVRStudio) im Build-Protokoll nach dem Kompilieren. Da steht dann so etwas wie "Data: 712 bytes (69.5% Full)". Um den nachlässigen Programmierer zu verwirren, gibts auch einen Data-Verbrauchs-Anzeige über 100 % - dann läuft manches nicht mehr (und ich hatte mal ewig lange gesucht, bis ich meine Dämlichkeit merkte).

So eine Ausgabe sieht am Terminal etwa so aus (klick hier). (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=433979#433979) Mit paste& copy habe ich die Daten entweder direkt ins Excel kopiert oder in eine ASCII-Datei abgespeichert. Danach eine Excelorgie je nach Bedarf und Geschmack. So ist dieses Diagramm entstanden (klick) (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=458181#458181) und ähnliche, mit mehreren Messwerten zu je hundert Messpunkten. Direkt ins Excel gehts wohl auch, wenn Du einen "Terminal"-Ersatz hast, der das kann. Meine Lösung reichte mir und benötigte keine Sonderheiten. Ein Trick beim Einfügen von ASCII-Daten ist Excel-usern bekannt: Daten, die mit TAB getrennt sind, werden in benachbarte Zellen geschrieben, Daten die mit CR/LF getrennt sind, in darunter liegende Zellen usf.

Klingt hausbacken, ich weiß (ich bin eben einfach gestrickt). Viel Erfolg

kekse
28.11.2010, 12:42
Hallo, ich benutze auch den BMA020 mit dem Modul von ELV. Bin ziemlich begeistert von dem Gerät. Auslesen funktioniert soweit auch ganz gut (mit Hilfe einiger Code-Schnipsel aus diesem Forum).

Jetzt möchte ich den Sensor aber im Interrupt-Betrieb betreiben. Habe mir das Datenblatt dazu mehrmals durchgelesen (ist ja im Grunde recht gut beschrieben). Leider funktioniert das ganze nicht wie es soll.
Der Sensor soll einen Interrupt schicken sobal er bewegt wird. Dazu dachte ich, dass ich eigentlich nur das any_motion Bit setzen muss.

Wäre euch dankbar wenn ihr mir sagen könntet welche Bits ich dazu alle setzen muss (und welche nicht).

Gruß
Jens

kekse
29.11.2010, 20:03
Ok, ich hab das Problem selber gefunden. Hatte das enable_adv_INT Bit falsch gesetzt. Jetzt klappts.

Edit
-----------------------
Ich habe da noch ein paar Fragen.

@mausi_mick:
Wie bist du vorgegangen um den Vektor zu normalisieren und um den Nullpunkt zu verschieben? Wie bist du auf die Werte gekommen??
Mit der Formel sqrt(x² + y² + z²) sollte ja das Ergebnis bei Ruhelage immer gleich bleiben. Egal auf welcher Seite der Sensor steht, solange er in Ruhelage ist. Aber ich erhalte unterschiedliche Werte je nach Lage und Ausrichtung.

Warum sprecht ihr eigentlich immer von einem Wertebereich zwischen +-256?? Bei 10 Bit habe ich doch eher einen Wertebereich zwischen +-512??

Gruß Jens

pandoraIII
08.12.2010, 13:59
Guten Tag die Herren,

freut mich das ich nicht der einzige bin der hier Probleme hat oder hatte ;)

ALSO :)

Zunächst ich programmiere mit C und steuere den Sensor über einen LPC 900 an, bzw LPC 935. . . . .....

Das macht es für mich nicht so einfach die Codes hier zu lesen und zu verstehen, aber denoch vill kann mir hier einen weiterhelfen.

Probiere seit längerem diesen Sensor auszulesen, wenn ich ihn über das ELV USB-I2C Interface Gerät auslese und einen Makro anwerfe dann passen die Werte 1a.

So bald ich mein selbst geschriebenes Programm komplett durch fahren lasse, dann kommen Werte die nicht stimmen bzw auch sehr stark schwanken!

ABER wenn ich dann im Singel Step mein Programm durch fahre, dann passen die Werte auch... denke es liegt dann an einer Delay Zeit die ich nicht einhalte!?!?!??

Weiß langsam nicht mehr so richtig weiter, vielleicht hat ja einer noch einer eine sinnvolle Idee hier scheinen mir genug kompetene Menschen zu sein.

Hat einer schon Erfahrung gemacht mit Interrupt??

Gruß


#include <REG935.H>
//--------------- Konstante für BMA020(werden aber nicht benutzt...)
const bma20_W = 0x70;
const bma20_R = 0x71;

//----------Programm....
void main ()
{


char xLSB02,xMSB03,xLSB04,xMSB05,xLSB06,xMSB07;

long int x,i;
char u = '-' ;



P1M1=0xFF; // Port Konfiguration
P1M2= 0x00;


P1M1 |= 0x0C; // SDA und SCL als Open-Drain
P1M2 |= 0x0C;

//EI2C = 1; // I2C Interrupt freigeben
//EA = 1; // allgemeine Interruptsperre aufheben

I2SCLH = 19; // 100khz
I2SCLL = 19;


// Auslesen des Beschleunigungssensors

do{
//

I2CON = 0x64; // Start, I²C Hardware wird aktiviert und als Master gesetzt
while (I2STAT != 0x08); // Warten auf Startbedingung
I2DAT = 0x70; // Schreibadresse wird dem Register I2Dat zugewiesen
I2CON = 0x44; //I2C Hardware aktiviert, ACK
while (I2STAT != 0x18); // SLA+ Wwurde gesendet, ACK wurde empfangen
I2DAT = 0x02; // Adresse von Register 02 wird I2Dat zugewiesen
I2CON = 0x44; //I2C Hardware aktiviert, ACK
while (I2STAT != 0x28); //Datenbyte wurde gesendet, ACK wurde empfangen
I2CON = 0x54; // Beenden

//--------------------Auslesen der Register 02-07


for (i=0; i<= 100 ; i++); // Delay Zeit wurde generiert...

I2CON = 0x64; //Start
while (!(I2STAT == 0x08 || I2STAT == 0x10));


I2DAT = 0x71; // Read Adresse...
I2CON = 0x44; //I2C Hardware aktiviert, ACK
while (I2STAT != 0x40); // SLA+R wurde gesendet, ACK wurde empfangen


I2CON = 0x44; //I2C Hardware aktiviert, ACK
while (I2STAT != 0x50); //Datenbyte wurde empfangen, mit ACk wurde geantwortet
xLSB02 = I2DAT;

I2CON = 0x44;
while (I2STAT != 0x50);
xMSB03 = I2DAT;

I2CON = 0x44;
while (I2STAT != 0x50);
xLSB04 = I2DAT;

I2CON = 0x44;
while (I2STAT != 0x50);
xMSB05= I2DAT;

I2CON = 0x44;
while (I2STAT != 0x50);
xLSB06 = I2DAT;


I2CON = 0x44;
while (I2STAT != 0x50);
xMSB07 = I2DAT;


I2CON = 0x54; // Beenden

for (i=0; i<= 100 ; i++); // Delay Zeit



//-----------------Algo für Umrechnen der Werte

x &= xLSB06;


x =x+ (xMSB07 << 2);

x = x& 0x03FF;


if ( x > 0x01FF)
{
x= x^= 0x03FF;

x= x*4;
}



}while(1);

}





EDIT:

Möchte hinzufügen. Das wenn ich das Programm komplett durch fahren lassen das dann Register06 und 07 gleich sind .... obwohl ich eine Schleife drin habe die als delay dienen soll...

damfino
26.12.2010, 18:19
Hi,
ich versuch schon seit Stunden den Sensor auszulesen, aber bekomme einfach keine Antwort.

Vielleicht übersehe ich die ganze Zeit den Fehler, vielleicht ist der Sensor aber einfach defekt.

Hier der Code:



void Sensortest()
{
unsigned char xl,xm,yl,ym,zl,zm;

xl=0;xm=0;yl=0;ym=0;zl=0;zm=0;x=0;


while(1)
{
if(!(i2c_start(0x70))) // start I2C bus
{
i2c_write(2); // register

i2c_rep_start(0x70+I2C_READ); // restart
xl = i2c_readAck();
xm = i2c_readAck();
yl = i2c_readAck();
ym = i2c_readAck();
zl = i2c_readAck();
zm = i2c_readNak();

i2c_stop();
}

Kompass();// TEST
_delay_ms(1);

// Ausgabe am LCD
while (TWI_bereit()!=0)
_delay_ms(1);

i2c_start(0xb0);
i2c_write(1); // (ab) register 1

i2c_write(8); // Modus Sensortest
i2c_write(xl);
i2c_write(xm);
i2c_write(yl);
i2c_write(ym);
i2c_write(zl);
i2c_write(zm);
i2c_write(kompass_akt); // TEST

i2c_stop();


i2c_start(0xb0); // Register 200 auf 1 setzen = neue Werte
i2c_write(200);
i2c_write(1);
i2c_stop();
LED_rot_aus;
_delay_ms(300);
LED_rot_ein;

}
}

Die Ausgabe erfolgt über I2C an den Slave der das LCD ansteuert. Um sicher zu sein dass es hier keinen Fehler gibt, lese ich zusätzlich den Kompass aus (auch über I2C) und zeige auch dessen Wert am LCD an.
Die Kompasswerte sehe ich auch, aber vom Sensor nichts. Bzw wenn ich die Abfrage von if(!(i2c_start(0x70))) auf i2c_start_wait(0x70); abändere habe ich 6x den Wert 113, dh h70+1.

LG!

oberallgeier
26.12.2010, 22:59
Hi damfino,

schau Dir mal Sternthalers Code an (dieser Thread, 21 Jun 2010, 0:56). Der Codezauberer Sternthaler hat dort für die x, y und z-Werte int16_t genommen. Das lässt doch nachdenklich werden ! ? Und genauso funktioniert das bei mir (auch - ich hab nämlich seinen Code geklaut). Ob das mit Deinen Low- und Highbytes klappt - na ich weiß (leider wirklich) nicht.

damfino
27.12.2010, 09:55
Hi,
an den Variablen kann es kaum liegen, ich bin derzeit nur am testen der ganzen I2C Verbindungen und lese daher nur die einzelnen Bytes aus. Da hat Sternthaler mit uint8_t die gleichen wie ich mit unsigned char. Der Zusammanbau von 2x8Bit auf 10Bit kommt erst wenn das mal funktioniert.

Ach ja, ich verwende die Fleury lib für den Master.

LG!

H.A.R.R.Y.
27.12.2010, 13:10
Hallo damfino,

Dein Code ist wohl nur ein Ausschnitt. Auf welche Geschwindigkeit ist der I²C eingestellt? Habe eben etwas über die max. Geschwindigkeit und Kabellänge am Sensor gelesen. Solltest 100kHz auf SCL nicht überschreiten. Leider finde ich auf die schnelle das Datenblatt des Sensors nicht (bei ELV ist jedenfalls kein direkter Download ode sowas zu sehen). Ohne Datenblatt kann ich aber die Sequenz nicht nachprüfen...

H.A.R.R.Y.

mausi_mick
27.12.2010, 17:19
Hallo Kekse,

war lange nicht im Forum und hab Deine Frage erst heute gesehen.
Hab mir das mit der Linearisierung relativ einfach gemacht und das eigentlich
nur auf +-255 normiert.
Wenn der Maximalmesswert bei 90° z.B. bei 280 lag und der Minimalwert z.B. bei -230, hab ich das auf +-255 umgerechnet und dazwischen dann eine Gerade gelegt (bei 0,5% Linearität eigentlich erlaubt).


Dafür hab ich bei meinem Exemplar folgende Parameter benutzt:

double const rad_to_grad = 57.29577951;
double const maxm = 256.00;
// Konstanten zur Eichung der acc-Kennlinie (von Exemplar zu Exemplar unterschiedlich)
double const x_norm = 1.080169; // x : 267 ... - 207 = 474 512/474 = 1.108169;
double const y_norm = 1.028112; // y : 227 ... - 271 = 498 512/498 = 1.102811;
double const z_norm = 1.015873; // z : 259 ... - 245 = 504 512/504 = 1.105873;
double const x_null = -32.405; // x : (267 - 32.405) * x_norm = 256;
double const y_null = 22.619; // y : (227 + 22.619) * y_norm = 256;
double const z_null = -7.11; // z : (259 - 7.11) * z_norm = 256;


Gruss mausi_mick

H.A.R.R.Y.
27.12.2010, 20:14
Hallo damfino,

bins nochmal - nachdem ich jetzt das Datenblatt vom Sensor habe, sehe ich einen möglichen Fehler in Deinem Code. Um zu lesen sendest Du ein WR-Befehl (0x70) mit Registeradresse 2. Danach eine RESTART-Sequenz. Im Gegensatz zu den diversen I²C-EEPROMs, die diese Sequenz kennen, kann der Sensor sie offenbar nicht! Im Datenblatt ist ganz eindeutig eine STOP-Sequenz und dann eine neue START-Sequenz, diesmal mit Lesebefehl (0x71), zu sehen. Keine RESTART-Sequenz! [Page 35, Figure 16]

Versuch mal dein Programm entsprechend zu ändern und bitte berichte über Erfolg oder Mißerfolg.

H.A.R.R.Y.

damfino
28.12.2010, 10:11
Hi,
das hatte ich auch schon probiert als ich hier die Codebeispiele durchging.
Code vom letzten Versuch gestern (im AVR Studio ists schön formatiert aber hier??):


i2c_start(0x70);

i2c_write(2);
i2c_stop(); _delay_ms(1);
i2c_start(0x70+I2C_READ);
xl = i2c_readAck();
xm = i2c_readAck();
yl = i2c_readAck();
ym = i2c_readAck();
zl = i2c_readAck();
zm = i2c_readNak();

i2c_stop();_delay_ms(1);

Ich habe auch kurze Delays eingebaut falls stop-start zu schnell hintereinander kommt, hat nichts geändert. Im Datenblatt steht vom Sensor eine maximale Busgeschwindigkeit von 3.4Mhz, aber keine Ahnung wie schnell die Pegelwandler von der ELV Platine arbeiten. Der I2C Bus ist auf 100khz eingestellt.
Bei dem obigen Beispiel erhalten ich für alle Bytes den Wert 113, dh hex71.

LG!

H.A.R.R.Y.
28.12.2010, 11:46
Das sieht immerhin schon mal so aus wie im Datenblatt dargestellt.

Mich irritiert aber Dein Rücklesewert von 0x71. Das ist ziemlich genau das was Du abschickst, als ob der USI noch gar nichts empfangen hätte. Oder der Sensor einfach nur ein Echo sendet.

Funktioniert genau dieses i2c_readAck() & Co mit dem Balancer oder Kompaß?

Als Referenz würde ich spätestens jetzt einen PCF8574 an den Bus anhängen, 4 LEDs zur Ausgabe und 4 Jumper, Taster, Schalter, Drahtbrücken oder was auch immer zur Eingabe dran. Wenn die Lib den sauber ansteuern kann, dann ist sie wohl auch grundsätzlich I²C-konform.

zweq000
31.12.2010, 17:38
Hab den gleichen Sensor von ELV ich hab ihn versucht mit dem I2C/USB Adapter auch von ELV auszulesen da kommt aber nur Müll raus welchen Bustakt solt ich einstellen bzw wie habt ihr das Makro abgeändert ?

monkey_cb
18.03.2011, 22:49
Hallo.

Erstmal wollte ich mich bedanken, da ich mit hilfe euer Codes erstmal einigermaßen verstanden habe wie der Sensor anzusprechen ist. Leider ist es mir nach einer Woche noch nicht gelungen die Kommunikation zwischen meinem TI 28016, welcher auf nem Olimex Development Board sitzt, und dem BMA020 auf die Beine zu stellen.
Meine µC-Kenntnis sind eher rudimentär und mit dem TI arbeite ich erst seit 3 Wochen. Deshalb habe ich versucht ein fertiges Snippet anzupassen, geschrieben von Brad Griffis 2008.
Das ist dabei rausgekommen:


//I2C test

#include "DSP280x_Device.h" // DSP280x Headerfile Include File
#include "DSP280x_Examples.h" // DSP280x Examples Include File

// Prototype statements for functions found within this file.
void I2CA_Init(void);
Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length);
Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length);

Uint16 Values[6];

void main(void)
{
InitSysCtrl(); // Step 1. Initialize System Control:
InitI2CGpio(); // Step 2. Initalize GPIO only for I2C functionality
I2CA_Init(); // Step 4. Initialize all the Device Peripherals

for(;;) // Application loop
{
I2C_Write(0x70,0x02,2);
I2C_Read(0x71,Values,6);
} // end of for(;;)
} // end of main


void I2CA_Init(void)
{
// I2caRegs.I2CSAR = 0x38; // Slave address - EEPROM control code
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
I2caRegs.I2CCLKL = 4200; // NOTE: must be non zero
I2caRegs.I2CCLKH = 4200; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x3E; // Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
// I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset, Stop I2C when suspended
// I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
// I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return;
}

Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length)
{
Uint16 i;
while (( I2caRegs.I2CSTR.bit.BB==1 )); //bus busy?
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
I2caRegs.I2CMDR.all = 0; //disable I2C during config
I2caRegs.I2CCNT = length; //number of bytes to be send
I2caRegs.I2CSAR = slvaddr; //setup receiver addr
// Mode settings
I2caRegs.I2CMDR.bit.IRS=1; //I2C module enable
I2caRegs.I2CMDR.bit.STT=1; //If master -> start condition generated
I2caRegs.I2CMDR.bit.STP=1; //If master -> stop condition generated if data counter=0
I2caRegs.I2CMDR.bit.TRX=1; //Transmitter mode
I2caRegs.I2CMDR.bit.MST=1; //Master mode
I2caRegs.I2CMDR.bit.FREE=1; //I2C module runs free
I2caRegs.I2CMDR.bit.RM=1;

/* Transmission*/
for(i=0;i<length;i++)
{
while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.b it.ARDY)); //wait for xdry flag before transmit data or ardy if NACK appears
if (I2caRegs.I2CSTR.bit.NACK==1) //if NACK appears -> SCL=low, STP=0
{
I2caRegs.I2CMDR.all=0; //reset I2C -> SCL not held low
}
I2caRegs.I2CDXR = data;
}
}

Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length)
{
Uint16 i;
while (( I2caRegs.I2CSTR.bit.BB==1 )); //bus busy?
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
I2caRegs.I2CMDR.all = 0; //disable I2C during config
I2caRegs.I2CCNT = length; //number of bytes to be send
I2caRegs.I2CSAR = slvaddr; //setup receiver addr
// Mode settings
I2caRegs.I2CMDR.bit.IRS=1; //I2C module enable
I2caRegs.I2CMDR.bit.STT=1; //If master -> start condition generated
I2caRegs.I2CMDR.bit.STP=1; //If master -> stop condition generated if data counter = 0
I2caRegs.I2CMDR.bit.MST=1; //Master mode
I2caRegs.I2CMDR.bit.FREE=1; //I2C module runs free
I2caRegs.I2CMDR.bit.NACKMOD=1;

/* Reception */
for(i=0;i<length;i++)
{
while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.b it.ARDY)); //wait for xdry flag before transmit data or ardy if NACK appears
if (I2caRegs.I2CSTR.bit.NACK==1) //if NACK appears -> SCL=low, STP=0
{
I2caRegs.I2CMDR.all=0; //reset I2C -> SCL not held low
}
while(I2caRegs.I2CSTR.bit.RRDY==1);
data[i] = I2caRegs.I2CDRR ;
}
}

//EOF


Das Ergebnis hab ich mir mit nem Oszi angeschaut: Nach dem ersten Senden wird SDI auf low gezogen und SCK bleibt high. Wenn ich die

while (( I2caRegs.I2CSTR.bit.BB==1 ));
in der Schreib- bzw. Lesefunktion auskommentiere kann ich folgendes Bild sehen:

http://img24.imageshack.us/img24/7899/bild0027h.jpg

Meiner laienhaften Meinung nach wird keine Stop Condition erzeugt, weshalb BB immer 1 ist.

Ein Versuch eine I2C-Minimalversion für diese Sache zu schreiben sah so aus:

//I2C test


#include "DSP280x_Device.h" // DSP280x Headerfile Include File
#include "DSP280x_Examples.h" // DSP280x Examples Include File

// Prototype statements for functions found within this file.
void I2CA_Init(void);

Uint16 Values[6],i;


void main(void)
{
InitSysCtrl(); // Step 1. Initialize System Control:
InitI2CGpio(); // Step 2. Initalize GPIO only for I2C functionality
I2CA_Init(); // Step 4. Initialize all the Device Peripherals:


for(;;) // Application loop
{
//---> Write instruction <--- //
I2caRegs.I2CMDR.bit.STT = 1;
I2caRegs.I2CSAR = 0x70; //Write addr
I2caRegs.I2CCNT = 3; //3bytes=2bytes addr + 1 byte instr
I2caRegs.I2CDXR = 0x02; //instr
I2caRegs.I2CMDR.bit.STP = 1;
// I2caRegs.I2CMDR.all = 0x2620; //Send data to setup EEPROM address


//---> Read values <--- //
I2caRegs.I2CMDR.bit.STT = 1;
I2caRegs.I2CSAR = 0x71; //Read addr
I2caRegs.I2CCNT = 1; //6bytes=2bytes per coordinate
Values[0] = I2caRegs.I2CDRR;
/*for(i=0;i<6;i++)
{
Values[i] = I2caRegs.I2CDRR;
}*/
I2caRegs.I2CMDR.all = 0x2C20; //Send restart as master receiver
I2caRegs.I2CMDR.bit.STP = 1;
} // end of for(;;)
} // end of main


void I2CA_Init(void)
{
// I2caRegs.I2CSAR = 0x38; // Slave address - EEPROM control code
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
I2caRegs.I2CCLKL = 4200; // NOTE: must be non zero
I2caRegs.I2CCLKH = 4200; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset, Stop I2C when suspended
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return;
}

//EOF
Führte aber leider auch nicht zum Ergebnis.

Falls es relevant ist ich nutze das Code Composer Studio V4.
Falls jemand hier Erfahrungen mit TI DSPs oder Vorschläge jeglicher Art zu meinen beiden Code-Versuchen hat wäre ich sehr dankbar.

Grüße
Stephan

monkey_cb
23.03.2011, 13:08
hallo,

habs jetzt hinbekommen und falls mal jemand den BMA020 mit TI C2000 DSPs nutzen will poste ich mal meinen, durchaus verbesserungswürdigen, Code, welcher hier bereits gepostete Codeschnipsel enthält.



//I2C test

#include "DSP280x_Device.h" // DSP280x Headerfile Include File
#include "DSP280x_Examples.h" // DSP280x Examples Include File

// Prototype statements for functions found within this file.
void I2CA_Init(void);

int Values[6]={0,0,0,0,0,0};
Uint16 instr=0x02;
int i,dx=0,dy=0,dz=0;
double D2G,gx=0,gy=0,gz=0;

void main(void)
{
InitSysCtrl(); // Step 1. Initialize System Control:
InitI2CGpio(); // Step 2. Initalize GPIO only for I2C functionality
I2CA_Init(); // Step 4. Initialize all the Device Peripherals

D2G=0.00390625; // 4g/1024

for(;;) // Application loop
{
I2caRegs.I2CSAR = 0x38; //Set slave address
I2caRegs.I2CCNT = 1; //Set count to 1 Byte for instr 0x02
I2caRegs.I2CDXR = 0x02; //Send instr
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow


while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
I2caRegs.I2CCNT = 6; //read 6 bytes from sensor
I2caRegs.I2CMDR.bit.TRX = 0; //Set to Recieve mode
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow
for(i = 0; i < 6; i++)
{
while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
Values[i] = I2caRegs.I2CDRR;
}
DELAY_US(100); //wait for new data provided
dx=Values[0]; //dataadaptation by malthy & Sternthaler
dx=(dx|((Values[1]<<8))>>6);
gx=dx*D2G;
dy=Values[2];
dy=(dx|((Values[3]<<8))>>6);
gy=dy*D2G;
dz=Values[4];
dz=(dx|((Values[5]<<8))>>6);
gz=dz*D2G;

} // end of for(;;)
} // end of main


void I2CA_Init(void)
{
I2caRegs.I2CSAR = 0x38; // Slave address - EEPROM control code
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
I2caRegs.I2CCLKL = 42; // NOTE: must be non zero
I2caRegs.I2CCLKH = 21; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x3E; // Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
I2caRegs.I2CMDR.bit.IRS = 1; // Take I2C out of reset, Stop I2C when suspended
I2caRegs.I2CFFTX.all = 0x0000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x0000; // Enable RXFIFO, clear RXFFINT,
return;
}

//EOF


An der Stelle nochmals danke an die "Code-Sponsoren".

Das einzige was mich im Betrieb stört ist, dass die Ergebnisse nicht konstant bleiben selbst wenn ich den Sensor fest einspanne. Dabei treten manchmal Sprünge von bis zu 0.5g auf, was für meine anschließende Aufgabe tötlich sein wird. Hat schon mal jemand in dem Zusammenhang mit den Filtern rumgespielt ?

monkey_cb
29.03.2011, 08:43
Hallo,

ich weiß nicht ob dass hier noch relevant ist, aber falls nochmal jemand auf schwankende Werte kommt kann ich empfehlen die Einstellung des im Sensor befindlichen Tiefpasses zu checken. Bei mir war die Einstellung für "bandwidth" (14h,bits 2-0) nämlich auf 750Hz, abweichend von der Standardbelegung mit 25Hz. Dadurch hatte ich bei einem Wertebereich von +/-256 einen Fehler von ca. +/-10. Mit 25Hz komm ich auf +/-2 und bin für meine Anwendung ausreichend schnell.

In dem Sinne fröhliches Beschleunigen