"9 Degrees of Freedom" IMU

12 Schritt:Schritt 1: I2C Kommunikation Schritt 2: LSM303 Schritt 3: ITG-3200 Schritt 4: Schaltplan und Layout-Vorstand in Eagle Schritt 5: Mühle PCB Schritt 6: Füllen PCB Schritt 7: Brennen Bootloader Schritt 8: Test Atmega Schritt 9: Sprechen Sie mit Ihrem Hardware via I2C Schritt 10: Sprechen Sie mit I2C Gyroskops Schritt 11: Sprecht mit Beschleunigungsmesser / Magnetometer mit I2C Schritt 12: 9 DOF Firmware und Kalibrierung

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

Ich arbeite an einem Projekt, das volle Orientierungsinformation erfordert arbeiten, so dass ich baute eine Inertial Measurement Unit von Grund auf neu. Ich mag die 9DOF IMU Brett, das Sparkfun macht - die Kalibrierung Code, der mit ihm kommt ist fantastisch - aber ich wollte das Board neu zu gestalten, damit könnte es zu einem viel niedrigeren Preis mit einem einseitig PCB Mühle hergestellt werden. Ich denke, dass die Elektronik kommen auf etwa 20 € für dieses Projekt. Alle Codes, Schaltpläne und PCB-Fräsen-Dateien sind auf Github (klicken Sie auf die Cloud-förmige Taste zum Download).
Hier ist, was es tut:



LISTE DER EINZELTEILE:
Gyro:

(X1) ITG-3200 3-Achsen-Gyro Component Distributors Inc ITG-3200 Sparkfun SEN-09793 Newark 37T8091
(X2) 4.7K Widerstand Digikey rP4.7KECT-ND
(X2) 0,1 uF Kondensator Digikey 1276-1017-1-ND
(X1) 10nF Kondensator Digikey 1276-1035-1-ND
(X1) 2,2 nF Kondensator Digikey 1276-1288-1-ND
Beschleunigungsmesser / Magnetometer:
(X1) LSM303 3 Achsen Beschleunigungsmesser / Magnetometer Digikey 497-13819-1-ND
(X1) 10uF Kondensator Digikey 1276-2876-1-ND
(X1) 0,1 uF Kondensator Digikey 1276-1017-1-ND
(X1) 4,7uF Kondensator Digikey 587-2994-1-ND
(X1) 0.22nF Kondensator Digikey 1276-2759-1-ND

AVR:

(X1) ATMEGA328P Mikrocontroller Digikey ATMEGA328P-AURCT-ND
(X1) 10K-Widerstand Digikey P10KECT-ND
(X1) Taktschalter Digikey SW262CT-ND
(X2) 0,1 uF Kondensator Digikey 1276-1017-1-ND
(X1) 8MHz Resonator Digikey 535-10004-1-ND
(X1) grüne LED (optional, wird aber bei der Fehlersuche zu helfen) Digikey 160-1404-1-ND
(X1) 1K Widerstand (optional, wird aber bei der Fehlersuche zu helfen) Digikey P1.0KECT-ND
Interface:
(X1), 6-polig Oberflächenmontage ISP Header Mouser 649-95278-101A06LF
(X1), 6-polig Durchgangsloch FTDI Kopf Mouser 571-3-644456-6
(I enthalten zwei zusätzliche Reihen von Durchgangsloch Überschriften in meinem PCB, um die Montage der Platine einfacher, in diesem Fall werden Sie 3 der Durchgangsbohrung 6 Stiftleisten müssen. Dies ist optional)

Leistung
(X1) 10uF Kondensator Digikey 1276-2876-1-ND
(X1) 0,1 uF Kondensator Digikey 1276-1017-1-ND
(X1) 1K Widerstand (optional, wird aber bei der Fehlersuche zu helfen) Digikey P1.0KECT-ND
(X1) rote LED (optional, wird aber bei der Fehlersuche zu helfen) Digikey 160-1405-1-ND
Sonstiges:
(X9) 0 Ohm-Widerstand (Jumper) Digikey P0.0ECT-ND
Fräsen:
(X1) 10 Millionen Metallfräser Hartmetall Depot CU 222737 (für die kleinsten Merkmale auf der Platine)
(X1) 1/64 "endmill Carbide Depot CU 129974 (zum Ausfräsen meisten Spuren)
(X1) 1/32 "Schaftfräser Hartmetall-Depot CU 129985 (zum Ausschneiden der Platine)

(X1) FR-1 bearbeitbar einseitig PCB blank Invent 24201-02
Ich habe ein Roland Modela für das Fräsen, obwohl ich glaube, dies könnte auf einem getan werden Shopping-Suchmaschine Desktop- oder ähnliche Maschine auch.
Diverses Zubehör
Lot
Lötkolben
Heißluftpistole
Flux-Pen
Pinzette
Multimeter
3.3V FTDI Kabel Digikey 768-1015-ND oder Board Sparkfun DEV-09873
(Sie können möglicherweise ein Bandkabel zu verwenden, aber ich bin nicht sicher, dass dies mit der 8Mhz Uhr arbeiten)
ISP-Programmer (oder verwenden Sie ein Arduino oder kreiere deine eigenen ) und 6 poligen Stecker und Flachbandkabel

Schritt 1: I2C Kommunikation




All die Kommunikation zwischen den Komponenten auf diesem Board geschieht über eine digitale Sprache namens I2C . Komponenten über I2C angeschlossen sind entweder Master oder Slave. Ein Master-Komponente wird die Uhr des I2C Kommunikation eingestellt und die Sklaven hören Sie dieses Taktsignals.
Alle Komponenten der Kommunikation über I2C werden durch die gleichen zwei Leitungen verbunden - SDA und SCL; um Verwechslungen zu vermeiden, hat jede Komponente eine eindeutige Adresse, wo sie Nachrichten senden oder empfangen kann, wird es Nachrichten, die an verschiedene Adressen ignoriert. Die Adressen für I2C-Komponenten sind in der Regel durch den Hersteller festgelegt, wenn Sie möglicherweise in der Lage, einige oder alle der Adressbits selbst (überprüfen Sie das Datenblatt) zu ändern.
Ich bin mit dem Draht -Bibliothek, um mit meiner Hardware via I2C Kommunikation - diese Bibliothek kommt automatisch in neueren Versionen des Arduino IDE installiert.
Wenn ich will, um ein Register auf einem meiner Sensoren festzulegen, führen I-Code, der wie folgt aussieht:
  Wire.beginTransmission (GYRO_ADDRESS);
   WIRE_SEND (0x16); // registrieren, um zu schreiben
   WIRE_SEND (0x1B); // Wert
   Wire.endTransmission (); 

Wenn ich will, um Daten von den Sensoren empfangen Ich laufe Code, der wie folgt aussieht:
  Wire.beginTransmission (GYRO_ADDRESS); 
   WIRE_SEND (0x1D);  // Sendet Adresse zum Lesen
   Wire.endTransmission ();


   Wire.beginTransmission (GYRO_ADDRESS);
   Wire.requestFrom (GYRO_ADDRESS, 6);  // Anfrage 6 Byte
   while (Wire.available ()) // ((Wire.available ()) && (i <6))
   { 
     Buff [i] = WIRE_RECEIVE ();  // Lesen eines Bytes
     i ++;
   }
   Wire.endTransmission (); 

Beide Sensoren Ich verwende für dieses Projekt haben viele benutzerdefinierte Parameter, die den Betrieb (Bereich von acc / mag / Kreisel Bedienung, Offsets, Alarme, Auflösung, Aktualisierungszeit, etc.) beeinflussen. In die Programmierung mit I2C-Geräte beginnen, werden Sie haben, um durch das Datenblatt, insbesondere der Abschnitt "Registerbeschreibung" zu lesen, so dass Sie wissen, wie man richtig jeden dieser Parameter auf 2 gesetzt chip.Step: LSM303

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

Die LSM303 ist ein 3-Achsen-Beschleunigungsmesser / Magnetometer, das nur € 04.03 kosten in Mengen von 1.
Ich habe die Diagramme oben vom Datenblatt des LSM303. Früher habe ich die mechanischen Zeichnungen und Pin-Layout, um eine benutzerdefinierte Komponente in Eagle für diesen Teil zu schaffen. Jede Verbindung auf der LSM303 verfügt über ein 0,25 mm-Pad mit 0,25 mm Abstand in einem 16-poligen, 3mm Paket. Ich folgte "9 Degrees of Freedom" IMU
Anweisungen, um die Komponente zu erstellen und hat es zu amanda.lbr . Sie können amanda.lbr in Ihre Adler-Umgebung mit installieren Sie diese Anweisungen .
Ein Hinweis aus dem Datenblatt I im Auge behalten, während Routing mein Board:
"Hochstrom in Leitungen und Leiterbahnen können die Ursache von Fehlern in Magnetfeldmessungen für compassing sein. Conductor-erzeugten Magnetfelder in den Magnetfeld der Erde zu schaffen Fehler in Kompasskurs Berechnungen. Behalten Ströme höher als 10 mA ein paar Millimeter weiter vom Sensor IC ". Schritt 3: ITG-3200

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

Die ITG-3200 ist ein 3-Achsen-Gyroskop, das ca. € 05.04 kosten in Mengen von 1, die gleiche Kreisel auf der Sparkfun Platte verwendet.
Ich änderte die ITG-3200 von der Sparkfun Adler-Bibliothek, um etwas kleiner Pads, die mit einer 10 Millionen-Schaftfräser verlegt werden können und hat es zu amanda.lbr. Die ITG-3200 hat den gleichen 0,5 mm Rastermaß, dass die LSM303 hat. Die Probe Schaltplan für den Chip ist über (von der gezeigten Datenblatt ).
Ein wichtiger Hinweis aus dem Datenblatt:
"Die exponierte Die-Pad ist nicht für Kühlkörper erforderlich ist, und sollte nicht auf die Leiterplatte, da Löten, um es zu Leistungsänderungen durch thermo-Paket trägt gelötet werden - mechanische Beanspruchung." Schritt 4: Schaltplan und Layout-Vorstand in Eagle

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

Ich überarbeitete die Schaltpläne von Sparkfun für ihre Bord, um die neue Beschleunigungsmesser / Magnetometer-Chip verwenden, zur Verfügung gestellt und alle Widerstands- / Kondensatorgrößen, mehr menschenfreundliche 1.206 Pakete. Ich habe ein paar 0ohm Widerstand Jumper auf Route die Schaltung in einer Schicht. Alle meine Adler-Dateien werden in der mitgelieferten GitHub-Repository .
Sie können sehen, dass es einen zusätzlichen Satz von Stiftverbindungen auf der rechten Seite der Platte, die nicht mit dem Rest der Schaltung verbunden ist. Ich habe diese auf meine Bord leichter montieren auf meinem bestimmtes Projekt. Sie könnten diese weglassen, wenn Sie want.Step 5: Mühle PCB

github
"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

Ich exportiert das Board-Layout Deckschicht aus Adler als Schwarz-Weiß-png bei 2400 dpi. Ich habe ein Bild von der sehr kleinen Details auf dem Brett, so dass ich einen zusätzlichen Durchgang der gerade diese Bereiche mit einem kleinen Fräser tun. Ich habe auch einen Entwurf Schicht, die mir erlauben, für die Durchgangsloch-Verbindungen schneiden Sie den Rand des Boards und Bohrlöcher werden. Sie können wählen, um diese Löcher weglassen, wenn Sie verwenden Surface Mount Header wollte. Ich habe alle pngs befestigt und das Photoshop-Dokument vor (neueste Zeug ist auf Github ).
Zu meinem Werkzeugbahnen erstellen, lief ich die Dateien durch die Online-fab-Module mit Eingabeformat png, Ausgabeformat Roland MDX-20, und Prozessmühle Leiterbahnen. Ich wollte all das unerwünschte Kupfer aus meinem Spiel zu entfernen und ich hatte eine Menge von Oberfläche zu bedecken, so habe ich eine 1/32 "Schaftfräser in der Roland und änderte den Durchmesser des Werkzeugs zu 0,79 mm. I auch die Anzahl der festgelegt Offsets auf -1, um die Karte vollständig zu füllen mit Pfaden Der resultierende Pfad sah wie folgt aus.:
"9 Degrees of Freedom" IMU

I die Datei gespeichert als 9Dof32RoughCut.rml (angebracht).
. Als nächstes ging ich in eine 1/64 "Schaftfräser und Fräst mehr Informationen Diesmal ich den Werkzeugdurchmesser bis 0,39 mm und die Anzahl der Offsets 1. Leider ist die resultierende Pfad:
"9 Degrees of Freedom" IMU

I die Datei gespeichert als 9Dof64FinishCut.rml (angebracht).
Weiter habe ich eine 10mil Schaftfräser, um das letzte Bit Detail Diesmal hochgeladen die details.png auf die fab-Module, setzen Durchmesser bis 0,25 mm und num Offsets auf 1 und die Geschwindigkeit auf 2 mm / s. Hier ist der Pfad:
"9 Degrees of Freedom" IMU

Ich sparte dies als 9DofFinish10milPass.rml (angebracht).
. Schließlich habe ich schneiden Sie die Platine und Bohrungen für die FTDI Kopfstifte mit einem 1/32 "Schaftfräser Ich lud die outline.png Datei in das fab-Module und ausgewählten PCB Umriss unter Prozess Hier ist, was der Weg aussieht.:
"9 Degrees of Freedom" IMU

und die Modela Datei heißt 9Dof32Outline.rml (angebracht).
Meine fertigen Platte ist oben dargestellt, wie sich heraus groß. Es gab ein paar kleinere Probleme, natürlich: es gab einen Kurzschluss übrig nach dem Mahlen, dass ich mit einer Rasierklinge zu entfernen, und ein paar der verwaisten führt zu meiner Gyro-Chip aufgetaucht während Fräsen - dies sollte nicht zu viel sein ein Problem. Ich habe auch versehentlich gruben sich in einem meiner Spuren, weil ich begann eine Veredelung mit den falschen Weg x / y-Offset - achten Sie darauf, überprüfen Sie diese, sobald Sie die Modela laufen. (Siehe Bild oben)
Tipps:
Ich würde auf jeden Fall empfehlen, Ihre Zeit bei seinem Rücktritt, um sehr kleine Stirnfräser zum Fräsen Teil dieses Projekts. Versuchen Sie, so viel Material mit den größeren Bits, wenn möglich raus. Auch stellen Sie sicher, dass Ihr Bett ist flach und die Z-Null korrekt über die gesamten Abmessungen des geschnittenen gesetzt. Ich brach eine 10mil Schaftfräser auf mein erster Versuch mit diesem Board, weil der einen Seite ragte eine Menge in der z-Richtung, so dass der Fräser wurde tiefer Graben in das Material. Ich ersetzte die Beute Bord und gründlich gereinigt alle Bandrückstand vor der Modela mit Alkohol. Ich brach eine zweite 10mil bisschen, weil ich links die Geschwindigkeit der Bahn an 4 mm / s und versuchte, Mühle durch das gesamte 0,1 mm in einem Arbeitsgang. Sobald ich verlangsamt Dinge nach unten konnte ich die ganze Arbeit, ohne zu brechen nichts (obwohl dauerte es etwa 1,5 Stunden durch alle Fräsen für dieses Boot zu holen) .Schritt 6 erledigen: Auffüllen PCB

Hier
"9 Degrees of Freedom" IMU

Anbringen diese winzigen Chips auf dem Board ist schwierig, versuchte ich ein paar Techniken, bevor ich auf etwas, das funktioniert gelandet.
Zuerst versuchte ich Lotpaste. Generell scheint Lotpaste wie eine gute Idee mit Oberflächenmontage-Komponenten. Bei meinem ersten Versuch I unten eine Linie von Lotpaste legte in den winzigen 0,5 mm Rastermaß führt, stecken Sie die Komponenten ab, und verwendet eine Heißluftpistole, alles zu setzen. Ich denke, dass diese Technik könnte auch auf einem professionell hergestellt Bord, wo die Spuren bündig mit der Oberfläche der Platte zu arbeiten. Meine gefräst Platte hatte Nuten zwischen jeder der Spuren, und die Lötpaste tendenziell in diesen Nuten anstatt Docht Richtung der Spuren stecken. Ich hatte auch eine härtere Zeit Steuerung der Menge der Lotpaste auf meinem Leitungen, und mit dieser Art der Sache, um so wenig wie möglich Lot verwenden möchten.
Next I Laser schneiden eine Ausrichtungsmaske mit mask.pdf (Anlage) - Ich dachte, das würde mich mit Futter alles bis zum Löten zu helfen. Am Ende hat die Maske Sie mich nicht mehr Präzision als Platzieren von Komponenten mit der Hand.
Hier ist die Technik, die für mich gearbeitet:
Zunächst bewarb ich mich ein klein wenig Lötzinn auf die Pads von meinem Board - versuchen, so wenig wie möglich zu verwenden, decken nur die Pads mit Lot. Seien Sie auch vorsichtig, keine Lot auf den Spuren unter der Kreisel zum Laufen zu bringen (sie sagte im Datenblatt, das an der Unterseite des Chip-Löten würde mechanische Belastung für das Gerät, das Kreisel-Auslese beeinflussen würden setzen). Dann geklemmt ich mein Board in einen Schraubstock und langsam brachte es bis zu Temperatur mit der Heißluftpistole. Dann, als ich sah, das Lot zu schmelzen beginnen (get glänzend) I langsam jeden Chip gebracht, hielt die Hitze auf sie für ein wenig, und legte sie auf den Pads. Früher habe ich eine Pinzette vorsichtig verschieben, bis sie den Chip fiel in Ausrichten (dies dauerte ein paar versucht, nur halten Aufwärmen mit der Heißluftpistole und Flussmittel, bis Sie die richtige Ausrichtung zu erhalten).
Hinweis - Die Gyro-Chip sollte mit Pin 1 auf der rechten unteren Ecke angebracht werden
Hier ist ein schönes Video, das zeigt etwa die gleiche Prozeß (aber nicht setzen Lot auf dem Mittelpolster des Kreisels!):

Sobald alles war cool, ausgespannt ich den Laster und überprüft, ob meine Chips wurden gelötet. Dann überprüft ich jede Minute mit einem Multimeter, auf der Suche nach Kurzschlüssen zwischen benachbarten Stiften. Überprüfen Sie, dass die Masse und Vcc nicht verbunden.
Einmal fühlte ich mich ziemlich sicher, dass die ersten beiden Chips waren unten, angebracht ich den Rest meines Komponenten. Ich musste sub in ein paar Durchgangsloch Widerstände und Kondensatoren auf meinem Board, da konnte ich nicht finden die richtige Oberflächenmontagekomponenten. Schließen Sie das Lötjumper auf die ISP-Header angeschlossen, wenn Sie sicher, dass Sie das tun möchten. Dies ermöglicht es Ihnen, Ihre Bord von einem 3,3V ISP Programmierer Leistung, aber wenn Sie ein 5V ISP Programmierer haben, werden Sie Ihre Chips zu braten.
Auch überprüfen, dass Masse und Vcc nicht vor proceeding.Step 7 verbunden: Brennen Bootloader


"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

"9 Degrees of Freedom" IMU

Schalten Sie das Brett mit dem 3,3 V FTDI Anschluss. Sie sollten die rote LED leuchten sehen. Wenn Sie das rote LED-Licht nicht sehen, dann können Sie ein Problem mit Ihrem 3.3V und Masseverbindungen müssen - mit einem Multimeter, dies zu debuggen.
Um das Board zu programmieren und senden serielle Daten über den FTDI-Anschluss, Sie haben werde, um den Arduino Bootloader brennen auf der Atmega328 Chip über den ISP-Header.
Stecken Sie das ISP-Programmierer, um das Board (müssen Sie auch die FTDI für die Stromversorgung angeschlossen).
Öffnen Arduino (Ich bin mit Arduino 1.0.1)
Unter Tools >> Vorstand wählen Arduino Pro oder Pro Mini (3,3 V, 8 MHz) w / Atmega328
Unter Tools >> Programmer wählen Sie Ihre aktuelle Konfiguration (ich verwende USBtinyISP, wenn Sie einen Arduino werden als ISP-Programmer werden Sie zum Arduino als ISP auszuwählen)
Wählen Werkzeug >> Brennen Bootloader. Die grüne LED sollte blinken, während dies geschieht. Irgendwann werden Sie eine Nachricht, die auf "Fertig brennBootLoader", sagt und die grüne LED blinkt, siehe etwa einmal pro second.Step 8: Test Atmega


Wenn Sie in der Lage, den letzten Schritt zu vervollständigen waren, ist deine Atmega Bord wahrscheinlich gut funktioniert. Nur um sicherzugehen, führen Sie diesen einfachen Skizze:
  int geführt = 13;

 Leere setup () {                
   pinMode (LED, Ausgang);     
 }

 Leere Schleife () {
   digital (LED, hohe);
   Verzögerung (100);
   digital (LED, LOW);
   Verzögerung (100);
 } 

Schließen Sie den FTDI-Kabel an den Vorstand (Sie werden nicht den ISP-Programmer für den Rest des Projektes müssen).
Unter Tools >> Vorstand wählen Arduino Pro oder Pro Mini (3,3 V, 8 MHz) w / Atmega328
Schlagen Sie Datei >> Laden, um die Skizze hochladen
Sie sollten sehen, die grüne LED blinkt bei einer Rate von 10 Hz (10 mal pro Sekunde). Wenn das alles so weit funktioniert, fahren Sie mit dem nächsten Schritt, wenn nicht, überprüfen Sie die Verbindungen mit einem Multimeter.
In meinem ersten Versuch, hatte ich ein paar Probleme mit der Aufrechterhaltung einer seriellen Verbindung zu meinem Board. Zu sein, dass Sie nicht mit diesem Problem laden Sie die folgenden Schritte aus: Schritt 9: Ihre Hardware Sprechen Sie über I2C


Führen Sie den folgenden Skizze zu sprechen beginnen, um Ihren Kreisel und acc / mag:
  #include <Wire.h>

 Leere setup () {
  
   Serial.begin (57600);
   Serial.println ("auf der Suche nach Hardware ...");
  
   Verzögerung (200);
   for (int-Adresse = 1; Adresse <= 126; Adresse ++) {
     Wire.beginTransmission (Adresse);  // Select-Adresse
     wenn Serial.println (Adresse) (Wire.endTransmission ()!);
   }
 }
 Leere Schleife () {
 } 

Diese Skizze sollte alle I2C-Adressen auf der Hardware auf dem Board ausdrucken. Öffnen Sie die Serial Monitor, um den Ausgang (Tools> Serial Monitor) zu sehen ist, lesen Sie die Baudrate auf 57600 in der unteren rechten Ecke des Serial Monitor eingestellt. Die Ausgabe von meinem Board ist oben dargestellt.
Der Beschleunigungsmesser / Magnetometerbrett ist an der Adresse 30 und der Kreisel an der Adresse 104.
Wenn Sie nicht sehen, nichts gedruckt wird, oder wenn Sie sehen seltsame Zeichen gedruckt sein, dass Ihre Baudrate auf 57600 gesetzt (rechten unteren Ecke des Serial Monitor, in einem Dropdown-Menü). Wenn Sie sehen, "auf der Suche nach Hardware ..." und nichts anderes ist die Atmega nicht in der Lage, Ihre Chips zu verbinden, überprüfen Sie alle Verbindungen wieder mit einem Multimeter. Möglicherweise müssen Sie die Verbindungen zu Ihrem Chip mit einer Heißluftpistole (die den Trick für mich getan hat) .Schritt 10 Reflow: Sprechen Sie mit I2C Gyroskops


Der folgende Code sollte drucken Sie die X, Y und Z raw Kreiseldaten an die Serial Monitor. Die Ausgabe für mein Board ist oben dargestellt.
  #include <Wire.h>

 #define GYRO_ADDRESS ((int) 0x68) // 0x68 = 0xD0 / 2
 #define OUTPUT__BAUD_RATE 57600
 #define STATUS_LED_PIN 13 // Pin Anzahl der Status-LED

 // Arduino Abwärtskompatibilität Makros
 #if ARDUINO> = 100
   #define WIRE_SEND (b) Wire.write ((byte) b) 
   #define WIRE_RECEIVE () Wire.read () 
 #else
   #define WIRE_SEND (b) Wire.send (b)
   #define WIRE_RECEIVE () Wire.receive () 
 #endif

 schweben Kreisel [3];
 int num_gyro_errors = 0;
 boolean output_errors = false;

 Leere setup ()
 {
   Wire.begin ();  // Beitreten I2C-Bus (Adresse optional für Master)
   Serial.begin (OUTPUT__BAUD_RATE);  // Beginnen Serien für die Ausgabe
  
   // Init-Status-LED
   pinMode (STATUS_LED_PIN, OUTPUT);
   digital (STATUS_LED_PIN, LOW);
  
   // Init-Sensoren
   Verzögerung (50);  // Gib Sensoren genug Zeit, um zu starten
   Gyro_Init ();
  
   // Sensoren gelesen, init DCM-Algorithmus
   Verzögerung (20);  // Gib Sensoren genug Zeit, um Daten zu sammeln
 }


 nichtig Gyro_Init ()
 {
   // Einschalten Reset defaults
   Wire.beginTransmission (GYRO_ADDRESS);
   WIRE_SEND (0x3E);
   WIRE_SEND (0x80);
   Wire.endTransmission ();
   Verzögerung (5);
  
   // Wähle Full-Scale-Bereich der Gyro-Sensoren
   // Set LP-Filterbandbreite bis 42Hz
   Wire.beginTransmission (GYRO_ADDRESS);
   WIRE_SEND (0x16);
   WIRE_SEND (0x1B);  // DLPF_CFG = 3, FS_SEL = 3
   Wire.endTransmission ();
   Verzögerung (5);
  
   // Setze Probe rato bis 50 Hz
   Wire.beginTransmission (GYRO_ADDRESS);
   WIRE_SEND (0x15);
   WIRE_SEND (0x0A);  // SMPLRT_DIV = 10 (50 Hz)
   Wire.endTransmission ();
   Verzögerung (5);

   // Setze Uhr PLL mit z Kreiselreferenz
   Wire.beginTransmission (GYRO_ADDRESS);
   WIRE_SEND (0x3E);
   WIRE_SEND (0x00);
   Wire.endTransmission ();
   Verzögerung (5);
 }


 // Liest x, y und z-Kreisels Registern
 nichtig Read_Gyro ()
 {
   int i = 0;
   Byte-Buff [6];
  
   Wire.beginTransmission (GYRO_ADDRESS); 
   WIRE_SEND (0x1D);  // Sendet Adresse zum Lesen
   Wire.endTransmission ();
  
   Wire.beginTransmission (GYRO_ADDRESS);
   Wire.requestFrom (GYRO_ADDRESS, 6);  // Anfrage 6 Byte
   while (Wire.available ()) // ((Wire.available ()) && (i <6))
   { 
     Buff [i] = WIRE_RECEIVE ();  // Lesen eines Bytes
     i ++;
   }
   Wire.endTransmission ();
  
   wenn (i == 6) // Alle empfangenen Bytes?
   {
     Kreisel [0] = -1 * ((((int) Buff [2]) << 8) | Buff [3]);  // X-Achse (interner Sensor-y-Achse)
     Kreisel [1] = -1 * ((((int) Buff [0]) << 8) | Buff [1]);  // Der Y-Achse (interner Sensor-x-Achse)
     Kreisel [2] = -1 * ((((int) Buff [4]) << 8) | Buff [5]);  // Z-Achse (interner Sensor-z-Achse)
   }
   sonst
   {
     num_gyro_errors ++;
     if (output_errors) Serial.println ("ERR: Lesen Kreisel");
   }
 }

 Leere Schleife () {
   Verzögerung (200);
   Read_Gyro ();
  
   Serial.print (Gyro [0]);
   Serial.print ("");
   Serial.print (Gyro [1]);
   Serial.print ("");
   Serial.println (Gyro [2]);  
 } 
Schritt 11: Sprecht mit Beschleunigungsmesser / Magnetometer mit I2C


Der folgende Code druckt raw Beschleunigung und magnetischen Daten für die X, Y, und Z-Achse (die ersten drei Zahlen X, Y, Z Beschleunigungs, letzten drei sind X, YZ Magnetfeld). die Ausgabe von meinem Board ist oben dargestellt.
  #include <Wire.h>

 #define ACC_MAG_ADDRESS ((int) 0x1E) // 0x1E = 0x3C / 2
 #define OUTPUT__BAUD_RATE 57600
 #define STATUS_LED_PIN 13 // Pin Anzahl der Status-LED

 // Arduino Abwärtskompatibilität Makros
 #if ARDUINO> = 100
   #define WIRE_SEND (b) Wire.write ((byte) b) 
   #define WIRE_RECEIVE () Wire.read () 
 #else
   #define WIRE_SEND (b) Wire.send (b)
   #define WIRE_RECEIVE () Wire.receive () 
 #endif

 Schwimmer nach [3];
 schwimmen mag [3];
 int num_mag_errors = 0;
 int num_acc_errors = 0;
 boolean output_errors = false;

 Leere setup ()
 {
   Wire.begin ();  // Beitreten I2C-Bus (Adresse optional für Master)
   Serial.begin (OUTPUT__BAUD_RATE);  // Beginnen Serien für die Ausgabe
  
   // Init-Status-LED
   pinMode (STATUS_LED_PIN, OUTPUT);
   digital (STATUS_LED_PIN, LOW);
  
   // Init-Sensoren
   Verzögerung (50);  // Gib Sensoren genug Zeit, um zu starten
   Acc_Mag_Init ();
  
   // Sensoren gelesen, init DCM-Algorithmus
   Verzögerung (20);  // Gib Sensoren genug Zeit, um Daten zu sammeln
 }


 Leere Acc_Mag_Init ()
 {

   // Setze Beschleunigungsdatenrate auf 50 Hz, aktivieren Sie alle acc Achsen
   Wire.beginTransmission (ACC_MAG_ADDRESS);
   WIRE_SEND (0x20); // CTRL1 Register
   WIRE_SEND (0x57); // 01.010.111
   Wire.endTransmission ();
   Verzögerung (5); 
  
   // Setze Beschleunigungsskala +/- 16G
   Wire.beginTransmission (ACC_MAG_ADDRESS);
   WIRE_SEND (0x21); // CTRL2 Register
   WIRE_SEND (0x20); // 0010000
   Wire.endTransmission ();
   Verzögerung (5); 
  
   // Setze Magnet Auflösung, hohe und Datenrate auf 50 Hz
   Wire.beginTransmission (ACC_MAG_ADDRESS);
   WIRE_SEND (0x24); // CTRL5 Register
   WIRE_SEND (0x70); // 01.110.000
   Wire.endTransmission ();
   Verzögerung (5); 
  
   // Setze magnetische Skala auf +/- 8 Gauss
   Wire.beginTransmission (ACC_MAG_ADDRESS);
   WIRE_SEND (0x25); // CTRL6 Register
   WIRE_SEND (0x40); // 01000000
   Wire.endTransmission ();
   Verzögerung (5); 
  
   // Setze Magnetometer auf Dauerbetrieb
   Wire.beginTransmission (ACC_MAG_ADDRESS);
   WIRE_SEND (0x26); // CTRL7 Register
   WIRE_SEND (0x00); //
   Wire.endTransmission ();
   Verzögerung (5); 
 
 }


 // Liest x, y und z acc / MAG-Register
 nichtig Read_Mag ()
 {
   int i = 0;
   Byte-Buff [6];
  
   Wire.beginTransmission (ACC_MAG_ADDRESS); 
   WIRE_SEND (0x08 | 0x80);  // Sendet Adresse zum Lesen
   Wire.endTransmission ();
  
   Wire.beginTransmission (ACC_MAG_ADDRESS);
   Wire.requestFrom (ACC_MAG_ADDRESS, 6);  // Anfrage 6 Byte
   while (Wire.available ()) // ((Wire.available ()) && (i <6))
   { 
     Buff [i] = WIRE_RECEIVE ();  // Lesen eines Bytes
     i ++;
   }
   Wire.endTransmission ();
  
   wenn (i == 6) // Alle empfangenen Bytes?
   {
     mag [0] = -1 * ((((int) Buff [1]) << 8) | Buff [0]);  // X Achse
     mag [1] = -1 * ((((int) Buff [3]) << 8) | Buff [2]);  // Y Achse
     mag [2] = -1 * ((((int) Buff [5]) << 8) | Buff [4]);  // Z-Achse
   }
   sonst
   {
     num_mag_errors ++;
     if (output_errors) Serial.println ("ERR: Lesen acc / MAG");
   }
 }

 Leere Read_Acc () {
   int i = 0;
   Byte-Buff [6];
  
   Wire.beginTransmission (ACC_MAG_ADDRESS); 
   WIRE_SEND (0x28 | 0x80);  // Sendet Adresse zum Lesen
   Wire.endTransmission ();
  
   Wire.beginTransmission (ACC_MAG_ADDRESS);
   Wire.requestFrom (ACC_MAG_ADDRESS, 6);  // Anfrage 6 Byte
   while (Wire.available ()) // ((Wire.available ()) && (i <6))
   { 
     Buff [i] = WIRE_RECEIVE ();  // Lesen eines Bytes
     i ++;
   }
   Wire.endTransmission ();
  
   wenn (i == 6) // Alle empfangenen Bytes?
   {
     acc [0] = -1 * ((((int) Buff [1]) << 8) | Buff [0]);  // X Achse
     acc [1] = -1 * ((((int) Buff [3]) << 8) | Buff [2]);  // Y Achse
     acc [2] = -1 * ((((int) Buff [5]) << 8) | Buff [4]);  // Z-Achse
   }
   sonst
   {
     num_acc_errors ++;
     if (output_errors) Serial.println ("ERR: Lesen acc / MAG");
   }
 }

 Leere Schleife () {
   Verzögerung (100);
   Read_Mag ();
   Read_Acc ();
  
   Serial.print (acc [0]);
   Serial.print ("");
   Serial.print (nach [1]);
   Serial.print ("");
   Serial.print (nach [2]);  
   Serial.print ("");
  
   Serial.print (mag [0]);
   Serial.print ("");
   Serial.print (mag) [1];
   Serial.print ("");
   Serial.println (mag) [2];  
 } 
Schritt 12: 9 DOF Firmware und Kalibrierung


"9 Degrees of Freedom" IMU

Der endgültige Code für den Vorstand finden Sie auf Github (klicken Sie auf die Cloud-förmige Taste zum Download). Das meiste davon wurde geschrieben von Peter Bartz für die Sparkfun IMU , ich habe gerade diese geändert werden, um mit dem LSM303 arbeiten. Öffnen Sie die Datei Arduino >> >> Razor_AHRS Razon_AHRS.ino und laden Sie sie auf dem Brett. Dieser Code nimmt die Rohdaten von allen Sensoren, filtert sie und kombiniert sie, um Nick-, Gier- und Roll berechnen. Klicken Sie auf das Serial Monitor zu sehen, die unkalibrierten Nick-, Gier- und Roll (gezeigt über meine Bretter Ausgang).
Die Kalibrierung ist wirklich wichtig, wenn Sie das Board optimal funktionieren soll. Hier ist meine unkalibrierten Board angeschlossen an eine Verarbeitungs Skizze:

Und hier ist es nach der Kalibrierung (Kalibrierung nicht einen großen Unterschied machen für mich, aber es kann für Sie):

Die verbleibenden Kalibrierungsschritte können auf Peter Bartz Tutorial finden Sie hier .