Hi ich Programier noch nicht lang und dachte mir, zum lernen schreib ich
mal ne BMA020 Klasse.
Ich nutze eclipse zusammen mit einem Arduino Uno.
Soweit klappt auch alles, jetzt schreib ich aber die Funktion um den
Selftest_0 auszuführen. Aber ich bekomm immer nur 0 also nicht
geschafft.
Meine Frage also hab ich nen Logikfehler oder ist der BMA020 kaputt?
1
boolBMA020_AIO::selftest(){
2
uint8_treg=readRegister(REG_ST);
3
reg|=(1<<2);
4
setRegister(REG_ST,reg);
5
6
while(!(readRegister(REG_ST)&(1<<2)));
7
return(readRegister(REG_STR)&(1<<8))?1:0;
8
}
readRegister und setRegister funktionieren und sind jawohl
sebstsprechend ;)
Danke schon mal im vorraus.
Gruß Robin
Juhuu. Vielen dank für den tipp es funkt^^
Aber da muss ich gleich noch ne frage dran hängen.
Wenn man im BMA020 nen Interrupt erzeugt geht der dann immer auf den
pin-INT oder ist da irgent was über twi? Hab mich noch nicht wirktlich
mit Interrupts auseinander gesetzt.
Über den INT-Pin. Das ist ja das tolle daran, dass du nicht ständig über
TWI pollen musst, sondern den µC schlafen legen kannst und ihn über den
Interrupt wecken lassen kannst.
Einfach mal das Datenblatt aufmerksam lesen, dann klappt das schon ;)
Der Slave (BMA020) kann nicht von sich aus senden sondern muss immer vom
Master abgefragt werden (Polling). Deswegen gibt es den Interrupt-Pin um
den Master über neue Daten o.ä. zu informieren.
Ahso jetzt hab ichs kapiert. Danke für die erklärung.
Hab das Datenblatt zwar gelesen aber da waren so viele Fremdwörter da
war mein Englisch dann nicht mehr gut genug ;)
Und noch was versteh ich net Selftest_1 steht:
"This self test bit (address 0Ah, bit3) does not generate any
electrostatic force in the MEMS
element but is used to verify the interrupt function is working
correctly and that microprocessor
is able to react to the interrupts.
0g acceleration is emulated at ADC input and the user can detect the
whole logic path for
interrupt, including the PCB path integrity. The LG_thres register must
be set to about 0.4g
while LG_dur = 0 to generate a low-g interrupt"
Aber wo kann man das ergebnis abfragen? Auch im selftest_result?
Das Ergebnis vom Selbsttest 1 ist ein Interrupt Signal am
Interrupt-Ausgang. Du musst die Leitung mit dem Mikrocontroller
verbinden, um sie abzufragen.
Über den I2C oder SPI Bus kannst Du nur das Interrupt Status Flag
abfragen, was allerdings nicht der Sinn dieses Tests ist. Der Selbsttest
1 ist dazu gedacht, die Funktion der Interrupt-Leitung zu testen.
sei() erlaubt Interrupts allgemein. Du must aber auch noch festlegen,
daß Interrupts von dem Eingang INT0 erlaubt werden sollen, sonst sind
effektiv immer noch keine Interrupts erlaubt.
Siehe Bit 0 in Register PCMSK0.
Weiterhin muss du nach Absetzen des Befehl zum BMA020 auch abwarten, bis
er mit seinem Test fertig ist. Du fragst momentan sofort nach Absetzen
des Befehl ab, ob ein Interrupt ausgelöst wurde. Aber so schnell ist der
Chip nicht. Der Selbsttest dauert eine Weile.
Irgendwo im Datenblatt müsste stehen, wie lange die beiden Tests dauern.
Ich habe die Angabe beim schnellen Überfliegen jedoch nicht gefunden.
Füge eine Wartepause ein, zwischen dem Absetzen des Test-Kommandos und
dem Auslesen des Ergebnisses. Ich würde es einfach mal mit einer Sekunde
versuchen, das sollte reichen. Wenn das klappt, kanst Du ja
experimentiell herausfinden, wieviel Zeit der Test wirkloiuch benötigt.
Aber jetzt kommt wenn ich den Arduino anstöpsel kommt "Selftest_0
result: 1", "Selftest_1 result: 0" und bei einem reset über den taster
kommt bei beidem 0.
Reduziere das ganze Programm auf ein Minimum, falls nicht bereits
geschehen. Und dann zeige uns mal den gesamten Quelltext und den
gesamten Schaltplan.
Denn mit jedem Stück Quelltext hast du mehr wichtige Teile ausgelassen.
Ach lol hab voll die beschaltung vergessen...
Ich nutze das BMA020 Modul von elv
http://www.elv.de/controller.aspx?cid=683&detail=10&detail2=211450
und den Arduino Uno Rev.2
Am BMA020 Modul hab ich UIN mit CSB/UPullup verbunden.
Und die Verbindungen vom BMA020 zum Arduino
UIN mit 3,3V,
GND mit GND,
SCK mit A5,
SDI mit A4
und INT mit 2.
hoffe ich hab nicht noch was vergessen.
Gruß Robin
Du hast etwas vergessen: Schau Dir mal das Foto an. Wenn Du einen
Tropfen Zinn auf die Kontakteflächen J1 lötest, brauchst Du keine
externen Pull-Up Widerstände. Es fehlt die blaue Verbindung.
Ich bin kein Arduino Spezialist, aber in diversen Tutorials über
Interrupts habe ich weder sei() noch cli() Befehle gesehen. cli()
verbietet Interrupts, ist also ganz sicher falsch. Wenn schon, dann muss
es sei() heissen, aber bei Arduino scheint ein etsprechender Aufruf
schon in attachInterrupt() zu stecken.
Durch die verbindung von UIN und UPullup brauch ich auch keine externen
wiederstände. Und wenn ich nur attachInterrupt nehme spielt das programm
vllt 10ms wenns hoch kommt. Und da über die "Winterrupts.c" auch die
"acr/interrupt.h" eingebunden wird warum soll ichs dann nicht nutzen?
Eigentlich funktioniert ja auch alles nur mit den Interrupts bekomm ich
das halt noch net so hin weil ich damit gerade erst anfang.
Hallo Robin,
ich habe DIr ja auch geschrieben, dass Du keine externen Pull-Ups
brauchst.
Hast Du die blaue Brücke eingelötet? Wenn nicht, dann mach das erstmal,
denn die sind mit Sicherheit nötig. Das geht aus der Beschreibung des
Moduls von ELV hervor.
Und cli() ist definitiv falsch. Wie gesagt, verbietet cli()
Interrupts.DU kannst nicht erwarten, dass der Interrupt ausgeführt wird,
wenn Du ihn vorher ausdrücklich verboten hast.