Sonntag, 3. Juni 2012

Beschleunigungssensor auslesen mit einem Arduino Nano 3.0



image
Arduino Nano 3.0 und Modul mit einem Beschleunigungssensor
Zugegeben habe ich etwas lange gebraucht, um zu verstehen, wie ich diesen Sensor auslesen kann. Das liegt einerseits daran, dass ich bisher noch nichts mit I²C oder SPI gemacht habe. Nachdem ich die Anleitung gelesen hatte, habe ich erst mal nur Bahnhof verstanden. Das änderte sich, als ich es hinbekam, die gemessenen Daten auszulesen.
Da frage ich mich manchmal, warum ich das nicht gleich verstanden habe. Zum Glück gibt es ja google, das mich hin und wieder auf die richtige Seite bringt. Allerdings enthielten die Erklärungen teilweise große Lücken im Verlauf. Vielleicht schaffe ich es hier in meinem Blog dies näher und leichter zu erläutern. Und wenn nicht, kann hier entsprechend auch einen Kommentar abgeben werden für Verbesserungen. Dafür bin ich immer offen.
Zunächst haben wir hier den Sensor von Bosch Sensortec, den BMA020. Auf den 2 Bildern ist das Modul zu sehen, auf den der Sensor gelötet ist. Im Grunde ist es der kleine schwarze SMD Chip, der die Beschleunigung ausliest. Das Modul selbst besteht aus verschiedenen Schaltungen, um z.B. eine stabile Spannungsversorgung zu gewährleisten. Bestellt habe ich mir das Modul bei Amazon, wobei hier anzumerken ist, das der eigentliche Händler ELV ist. Für die Montage selbst müssen die Steckleisten verlötet werden.
imageimage
Unterseite mit den bestückten SMD KomponentenOberseite mit den Beschriftungen und Ausrichtungen des Sensors
Als zweites habe ich den Arduino Nano 3.0, der mit einem ATMega 328 bestückt ist und für seine Baugröße zahlreiche Ein- und Ausgänge bereit stellt. Für das Auslesen, brauchen wir Pin A4 und Pin A5 für die I²C Verbindung zum Sensor Modul.
image
Arduino Nano 3.0
Jetzt müssen die beiden nur richtig verbunden werden. Hierzu sind nur wenige Kabelverbindungen notwendig, wie bereits hier im Schaltbild zu sehen ist.
image
Links der Beschleunigungssensor, rechts der Arduino Nano 3.0
Als weiteres benötigen wir in C geschriebenes Programm. Hierfür habe ich in verschiedenen Foren gesucht und wurde auch fündig. Am Ende ist dieser Code  herausgekommen.
#include <Wire.h>
#define AccelerometerAddress 0x38
#define Axis_X_Out1 0x02
#define Axis_X_Out2 0x03
#define Axis_Y_Out1 0x04
#define Axis_Y_Out2 0x05
#define Axis_Z_Out1 0x06
#define Axis_Z_Out2 0x07

void setup()
{
  Wire.begin();
  Serial.begin(9600);
}

void loop()
{
  Serial.println();
  Serial.print("X1:");
  Serial.print(readAcceleration(Axis_X_Out1), BIN);
  Serial.print("SX2:");
  Serial.print(readAcceleration(Axis_X_Out2), BIN);
  Serial.print("@Y1:");
  Serial.print(readAcceleration(Axis_Y_Out1), BIN);
  Serial.print("SY2:");
  Serial.print(readAcceleration(Axis_Y_Out2), BIN);
  Serial.print("@Z1:");
  Serial.print(readAcceleration(Axis_Z_Out1), BIN);
  Serial.print("SZ2:");
  Serial.print(readAcceleration(Axis_Z_Out2), BIN);
 
  delay(500);
}

byte readAcceleration(byte address)
{
  byte val = 0x00;
  Wire.beginTransmission(AccelerometerAddress);
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom(AccelerometerAddress, 1);
  val = Wire.read();
  return val;
}
Die Ausgabe kann über die Serielle Verbindung gelesen werden.
Um eine gewisse Übersicht zu behalten, habe ich darauf geachtet, dass der Code auch wirklich kurz gehalten ist und keine unnötigen weiteren Funktionen hat.
Mit #include wird die Library eingebunden, die für die I²C Verbindung erforderlich ist. Die darauf folgenden #define sind Adressen für das auslesen des Sensors. Die erste davon ist die Adresse vom Sensor selbst, da an dem I²C Bus auch mehrere Geräte oder Module Angeschlossen werden können. Mit “Axis_X_Out1” werden die ersten zwei Bits gelesen. Um die eine Achse von ihren Werten vollständig zu erhalten, ist anschließend die Abfrage mit der Adresse “Axis_X_Out2” erforderlich. Zusammengesetzt sind es dann 10 Bits. Die ersten 2 Bits sagen aus, mit wie viel G einwirkt. Die weiteren 8 Bits geben dann den eigentlichen Wert wieder. Das gleiche gilt auch für die weiteren 2 Achsen.
Nun zur Methode “byte readAcceleration(byte address)”. Sie erledigt die eigentliche Aufgabe, die gewünschten Daten aus dem Sensor zu bekommen. Mit “Wire.beginTransmisson” und der Übergabe der Adresse zum Sensor stellen wir eine Verbindung her. Anschließend mit “Wire.write” übergeben wir nun die Adresse für eine der Achsen und mit “Wire.endTransmission” geben wir hier ebenfalls die Adresse des Sensors, um die Verbindung zu beenden. Im folgenden muss noch die Methode “Wire.requestFrom” mit der Adresse des Sensors und ein weiterer Wert für die Anzahl zu erwartenden Bytes.
So, das war die Beschreibung zum Code, der auf dem Arduino ausgeführt wird. Nun will man ja auch das ganze auf dem Bildschirm sehen.
image
Alle Werte der 3 Achsen, allerdings noch in Binär. Das ist für die meisten schlecht zu lesen.
Zur Not kann auch der Serial Monitor vom Arduino Programm verwendet werden, oder man schreibt sich eine Desktop Anwendung, die das auch visualisiert.
image
Desktop Anwendung für die Visualisierung der gemessenen Daten aus dem Sensor.
Da die Beschreibung der Anwendung meinen Rahmen für einen Blog Eintrag sprengen würde, belasse ich es hierbei. Als Hinweis gebe ich jedoch, wer hier mit dem .Net Framework arbeitet, benutzt am besten die Klasse “SerialPort”. Die kann alles, was man für das Auslesen zu einer seriellen Verbindung benötigt.

Kommentare:

Valentin Schaller hat gesagt…

Das Programm Funktioniert bei mir nicht ich würde mich über Hilfe oder eine Antwort sehr freuen

JPL hat gesagt…

Hallo Herr Schaller,

ich freue mich über Ihren Besuch meines Bloggs und gerne helfe ich Ihnen bei Ihrem Anliegen.

Normalerweise sollte dies auf Anhieb klappen, es können aber durch die neue Version mit dem Arduino Compiler eventuell Schwierigkeiten auftreten. Gibt es hier an der stelle einen Kompilierungsfehler? Dann ist nur eine kleine Anpassung notwendig, was ich dann auch dringend neu schreiben sollte.

Falls nichts bei der Ausgabe über den Monitor gegeben wird, dann ist vielleicht das Anpassen der Bautrate auf 9600 Baut erforderlich.

In den nächsten Tagen werde ich mal die neue Version installieren und prüfen, ob mein Code noch so funktioniert.

Ich hoffe, ich kann mit meinen Hinweisen schon mal weiterhelfen, ich werde jedoch in den nächsten Tagen den Inhalt des Post neu abgleichen.

Grüße von
meiner Welt aus meinem Kopf

Valentin Schaller hat gesagt…

Das programm konnte ich kompelieren doch der serial monitor zeigt 1er an. Hätten sie vieleicht ein einfaches programm mit dem ich testen könnte ob mein sensor funktioniert?

JPL hat gesagt…

Hallo Herr Schaller,

Kürzer lässt sich der Code leider nicht schreiben. Die meisten Einträge sind jedoch ausschließlich für die Monitor Ausgabe da.

Die eigentliche Arbeit macht die Methode "readAcceleration". Das Einsen erscheinen, ist ein gutes Zeichen und bedeutet, das Arduino und der Code funktioniert. Es ist wahrscheinlich die Verbindung zwischen Arduino und Sensor, da diese Ausgabe mit nur Einsen auch bei nicht angeschlossenem Sensor vorkommt.

Die Verkabelung wie auf meinem Bild muss leider genau so aufgestellt werden, damit der Sensor ordnungsgemäß über den I2C Bus kommunizieren kann. Ich setze mal auf meine ToDo Liste, mal mein Schaltbild zu erneuern, da es farblich etwas unglücklich erscheint.
Am Anfang hatte ich damit etwas Schwierigkeiten, als ich noch die anderen Steckverbinder verwendet und nicht bemerkt habe, das sich ein Wackelkontakt eingeschlichen hat.


Grüße von
Meine Welt von meinem Kopf

Valentin Schaller hat gesagt…

Hallo

Ich wollte sagen das ich die schaltung mitlerweile schon 5 mal aufgebaut habe aber es kommen immer nur 1er auf allen feldern nur 1er! Ich benutze einen arduino Leonardo kann es daran liegen? Als ich den sonsor einfach nur ausgelesen habe kamen auch nur werte von 1023. Kann es sein das mein sensor kapput ist? Bzw. in beim löten beschädigt habe.

JPL hat gesagt…

Das ist Ärgerlich. Jedoch habe ich selbst keine Erfahrungen, wie viel ein Sensor dieser Bauart aushält.

Das einzige was mir einfällt, das bei Arduino Leonardo die I2C Verbindung an Pin 2 und 3 sind, die sich wiederum vom Arduino Nano unterscheiden.

Valentin Schaller hat gesagt…

Hallo
Ich habe den Fehler in der schaltung gefunden. Denn das arduino leonardo board besitzt einen SDA und einen SCL anschluss. Wenn ich nun den serial Monitor öffne passiert garnichts! Es wird garnichts mehr angezeigt!

Moses Wurst hat gesagt…

Hallo JPL,

ich muss als ein Schulprojekt ein Beschleunigungssensor mit einem Android Handy auslesen. Als erstes wollte ich die Hardware zusammen bauen. Das Beschelunigungsensor BMA020 habe ich mir bei Ebay bestellt. Haben Sie für mich ein Tipp wo man günstig das Arduino Nano 3.0 im Internet bestellen kann. Bei Ebay habe ich einige gesehen aus China, ich weiß nicht wie gut die Teile aus China sind.

LG MW

JPL hat gesagt…

Hallo MW,

mein Arduino Nano 3.0 habe ich aus China und es funktioniert hervorragend. Es ist günstig, aber es dauert 2 bis 4 Wochen bis die Lieferung ankommt.

Die Entscheidung zu treffen, aus China oder in Europa zu bestellen, liegt darin wie akut der Artikel benötigt wird. ;)

Grüße von
JPL

Moses Wurst hat gesagt…

Hi JPL,

danke für das erneute hoch laden deines Beitrags. Ich will die Beschleunigungsdaten an mein Android Handy übertragen, am besten per Bluetooth. Wenn ich ein Mini USB Bluetooth Adapter (oder sollte ich es mit Arduino Bluetooth Module Slave Wireless Serial Board Module -> aus China realisieren?) an das Nano 3.0 anstecke kann ich das Nano an Pin VIN mit Extern 5 versorgen?
Kennst du ein einfachen Arduino Beispiel Code denn ich für die Bluetooth Übertragung verwenden könnte das auch einfach zu verstehen ist. Hab gegoogelt und viele Code Beispiele gefunden und den Überblick verloren welches einfach zu verstehen und umzusetzen ist, für einen Programmierleihen wie ich. Anschließen würde ich an meinem Handy mit BlueTerm (Android App) die Daten anzeigen lassen. Lg MW

Moses Wurst hat gesagt…

Hallo JPL

eine weitere Frage. Wie wandelst du die Messwerte LSB/g in SI-Einheit m/s^2, bzw. wie sollte das Formel im Arduino Sketch Code aussehen damit die die Beschleunigungswerte in m/s^2 angezeigt werden. Liege ich richtig mit: Messwert * 3.9 mg * 1000 ??

Lg MW

JPL hat gesagt…

Hallo Moses Wurst,

leider habe ich selber noch kein Beispiel. In meinen Blog Posts habe ich bisher nur mit den UART WLAN Modul etwas geschrieben, dass über Funk die Daten sendet. Davon abgesehen, wenn es sich ebenfalls um eine Serielle Schnittstelle handelt bei einem Bluetooth Modul, dann kann hier ebenfalls der Serielle Ausgang vom Arduino verwendet werden, um entsprechende Daten zu senden. Allerdings plane ich dem nächsten ein, ein paar Bluetooth Module zu bestellen.

Der VIN ist als Eingangs Spannung gedacht und ermöglicht Spannungen anzuschließen von 7V bis 12V. Für weitere Module verwendest du entweder den 3,3V oder 5V Ausgang auf dem Arduino Nano.

Was den BMA020 angeht, habe ich bisher nur als Lage Sensor verwendet, dass auf meinem PC dargestellt wird. Später habe ich den Sensor durch den MPU6050 ersetzt.

Pro Achse werden vom BMA020 Sensor 2 Byte gelesen. Aus dem ersten werden nur die ersten zwei Bits benötigt und aus dem 2 Byte alle 8 Bits. Zusammengesetzt sind es 10Bits. (Erstes Byte= 1100 0000, Zweites Byte=1111 1111, zusammengesetzt =11 1111 1111, und dann von Binar in Dezimal umrechnen).

Was das Umrechnen der Werte angeht, habe ich bisher noch nichts geschrieben. Im Handbuch dürfte ggf. deine Umrechnung der Einheiten zu finden sein http://www.elv-downloads.de/Assets/Produkte/9/915/91521/Downloads/91521_bma020_data.pdf.

Hoffe ich konnte dir etwas weiter helfen. Bei weiteren Fragen, einfach mir passend zu Post schreiben ;)

Grüße von
JPL