questa Volta possiamo costruire una Bussola digitale. Abbiamo bisogno di un Arduino Nano, un GY-271 Modulo e un RGB LED Ring. Finito il Dispositivo, possiamo semplicemente un 9V Batterieblock alimentare.
Circuito:
Il Circuito è molto semplice. GY-271 Modulo e il LED Ring essere alimentato a 5V. Quindi, GND collegare Vcc con 5V al Nano connettersi. L'I2C Bus, la GY-271 con l'I2C Porte del Nano collegato. E sebbene A4 con SDA e A5 con SCL. Per il LED Ring collegare la linea di Segnale con D4 al Nano. Per l'Alimentazione collegare il polo Negativo della Batterieblocks con GND e il 9V polo Positivo di un Interruttore con il Vin al Nano.
Il Codice
, La maggior parte delle Librerie sono per il HMC5883 non solo un diverso Indirizzo I2C ma anche diversa Registerbelegung ha. Ma il Controllo del QMC5883L è molto semplice, stavolta ho su l'Utilizzo di una Libreria di rinuncia.
Possiamo facilmente le Funzioni di Arduino I2C per utilizzare la Libreria.
Durante il Soft-Reset, abbiamo messo la Tassa di Registro del 10 e 11. Interessante è l'Registri 9 con i Parametri importanti del QMC5883L è in grado di impostare.
La Modalità di funzionamento Stand-By o continui Misurazione. Con la Velocità di Uscita si può definire come molte Misurazioni al Secondo, che devono essere resi. 10 Hz, 50 Hz, 100 Hz, 200 Hz possono essere scelti. Maggiore è la Frequenza e maggiore è il Consumo di energia. La Sensibilità in grado di RNG) indica la densità di flusso magnetico di Scala al. Qui può +/- 2 Gauss o +/- 8 Gauss essere scelto. La maggiore Sensibilità è importante notare che il disturbo Influenza di Fremdfeldern aumenta. Da ultimo, si può ancora l'Oversampling Rate. Si tratta di 64, 128, 256 e 512 regolabile. Un Valore superiore riduce i Filtri di Banda e di conseguenza Rumore fastidioso, ma prendi anche in questo modo, il Consumo di energia elettrica per.
Chi ancora conoscere più particolari, vuole trovare questi nellaScheda tecnica del prodotto QMC5883L .
Da letto Valori per x e y e l'Angolo di campo magnetico terrestre determina. Questo Valore è solo a metà strada esattamente se il Modulo non è più possibile in posizione orizzontale viene. Per la Rappresentazione e l'Angolo di +/- 180 Gradi da 0 a 360 Gradi equivalente e, quindi, dal 30 divide in modo che siamo in 12 Sezioni in base ai 12 Led dell'Anello ricevuto. La differenza viene poi usata per la Luminosità dei LED determinare. la Variazione negativa è anche la chiusa LED, altrimenti il seguente LED acceso. È il Valore, esattamente tra entrambi i Led si accendono immediatamente più chiaro.
Per il LED Ring abbiamo bisogno di un NeoPixelBus.h Biblioteca. La Biblioteca per l'I2C Bus Wire.h appartiene alla installazione di default.
Attenzione Avviso importante:Ho durante la Compilazione di una interna Kompilerfehler ottenere. Ricerche in Internet, è emerso che si tratta di un Problema con l'ultima Arduino-Hardware Biblioteca. Una Installazione della Versione precedente, è stato affrontato il Problema. Nel Boardverwalter semplicemente la Versione 1.6.22 invece dell'attuale 1.6.23 selezionare e Installare clic.
#include <Wire.h> //I2C Arduino Libreria #include <NeoPixelBus.h> //library for led strip //I2C address of the QMC5883L #define ADDR 0x0d //values for the QMC5883 control register 1 //operating mode #define Mode_Standby 0b00000000 #define Mode_Continuous 0b00000001 //Output data rate #define ODR_10Hz 0b00000000 #define ODR_50Hz 0b00000100 #define ODR_100Hz 0b00001000 #define ODR_200Hz 0b00001100 //Measure range #define RNG_2G 0b00000000 #define RNG_8G 0b00010000 //Over sampling rate #define OSR_512 0b00000000 #define OSR_256 0b01000000 #define OSR_128 0b10000000 #define OSR_64 0b11000000 //some costanti for the LED ring #define MAXBRIGHT 64 #define LEDCOUNT 12 #define SIGNALPIN 4 //initialize LED strip driver NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(LEDCOUNT, SIGNALPIN); //define color black to switch led off RgbColor black(0,0,0); //function to write data into a registro on QMC5883L void writeRegister(uint8_t reg, uint8_t val){ Wire.beginTransmission(ADDR); //start talking Wire.write(reg); Wire.write(val); Wire.endTransmission(); } //function to read results from QMC5883L void readData(uint16_t * x, uint16_t * y, uint16_t * ad) { Wire.beginTransmission(ADDR); Filo di.scrivere(0x00); Filo.endTransmission(); Filo.requestFrom(ADDR, 6); *x = Filo.di lettura(); //LSB x *x |= Filo.di lettura() << 8; //MSB x *y = Filo.di lettura(); //LSB z *y |= Filo.di lettura() << 8; //MSB z *z = Filo.di lettura(); //LSB y *z |= Filo.di lettura() << 8; //MSB y } //funzione per impostare il registro di controllo 1 su QMC5883L void setCtrlRegister(uint8_t overSampling, uint8_t gamma, uint8_t dataRate, uint8_t modalità) { writeRegister(9,overSampling | gamma | dataRate | modalità); } //funzione per ripristinare QMC5883L void softReset() { writeRegister(0x0a,0x80); writeRegister(0x0b,0x01); } //preparare l'hardware void setup(){ di Serie.iniziano(9600); Filo di.iniziare la(); Serie.println("Start"); softReset(); setCtrlRegister(OSR_128,RNG_2G,ODR_100Hz,Mode_Continuous); di Serie.println("init fatto"); } void loop(){ int x,y,z; //tripla asse di dati float azimut; uint16_t azi; //azimut solo positiv as integer uint8_t led1,led2; uint8_t val1,val2; int8_t diff; // in questo modo si resetta tutti i neopixels in stato off striscia di.Iniziare(); strip.Show(); readData(&x, &y, &z); //lettura dei dati dal sensore //calcolare l'angolo tra x e y //wechange le signe dato che i led sul ring ordinati in senso orario azimut = -atan2(y,x) * 180.0/PI; //aggiungi a 180 gradi per avere solo valori positivi azi = azimut+180; //abbiamo 12 led ogni 30 gradi led1=(azi/30) % 12; //si calcola la differenza tra l'angolo originale //e angolo del led dà a un massimo di +/- 30 diff = azi - led1 *30; //vogliamo mostrare entrambi i led di destra e di sinistra per la //angolo originale se (diff>0) { //se la differenza è positiva, abbiamo impostato i seguenti led led2 = led1++; se (led2 > 11) led2 = 0; val1 = diff; val2 = 30-diff; } else { //se la differenza è negativa, abbiamo impostato il precedente led led2 = led1--; se (led2<0) led2 = 11; val1 = -diff; val2 = 30+diff; } //spegnere tutti i led sono spenti striscia.ClearTo(nero); //imposta il wo led del valore calcolato con il rosso RgbColor col1(val1*MAXBRIGHT/30,0,0); striscia.SetPixelColor(led1,col1); RgbColor col2(val2*MAXBRIGHT/30,0,0); striscia.SetPixelColor(led2,col2); //invio dati per l'anello di led strip.Show(); // Mostra valori su linea seriale Serial.print("Valore di X: "); Serial.println(x); Serial.print("Valore di Y: "); Serial.println(y); Serial.print("il Valore Z: "); Serial.println(z); Seriale.di stampa("Richtung: "); Seriale.stampa(azimut); di Serie.println("°"); Seriale.di stampa("LED 1 = "); Serial.stampa(led1); Seriale.di stampa(" bright = "); Seriale.println(val1); Seriale.di stampa("LED 2 = "); Serial.stampa(led2); Seriale.di stampa(" bright = "); Seriale.println(val2); di Serie.println(); //attendere 1 secondo di ritardo(1000); }
Viel Spass mit dem Kompass
Gerald
13 commenti
Roland
Vorsicht mit der I2C-Adresse! Es sind auch Module mit der Adresse 0×1E (ursprüngliche Standardadresse) im Umlauf. Das Datenblatt von Honeywell enthält 0×3C und 0×3D.
Unter https://playground.arduino.cc/Main/I2cScanner/ findet man einen einfachen Adressscanner
Simon
Hallo, muss das Modul nicht kalibriert werden? Bei mir zeigt er nur 4 LEDs an (Ring getestet) und liefert utopische Werte im Serial Monitor.
LG
Simon
Rüdiger Sachse
Ich habe mir den GY-271 besorgt, um mein (Arduino)-Autopilot-Projekt zu verbessern.
Normalerweise ist der AP durchaus in der Lage einen stabilen Kurs zu einem Waypoint zu fahren. Die Navigationsdaten bekommet er von einem GPS-Plotter. Peilung und Crosstrack-Error sind kein Problem, da sich die Werte relativ langsam ändern, aber der aktuelle Kurs und insbesondere die schnelle Kursänderung werden nur verzögert (alle 2-3 Sek) ausgegeben. Das Schiff muss eine gewisse Strecke fahren um den GPS-basierten Kurs zu erhalten. Bei langsamer Fahrt wird die Berechnung immer ungenauer. Mit dem GY-Modul hoffe ich besseren Werte für die schnellen Kursänderungen und damit ein besseres Steuerverhalten zu erzielen.
Hier ist mir etwas merkwürdiges aufgefallen! Die Werte für die X-Y-Z-Achsen werden mit Hilfe der Arduino-Lib Wire.h ausgelesen.
Die Registerinhalte stimmen nicht mit dem Datenblatt überein, Z und Y sind vertauscht!!
code:
x = Wire.read()<<8; //X msb //16bit int X-Achse x |= Wire.read(); //X lsb z = Wire.read()<<8; //Z msb //nach datenblatt Y-Achse ?? z |= Wire.read(); //Z lsb y = Wire.read()<<8; //Y msb //nach datenblatt Z-Achse ?? y |= Wire.read(); y+=180; //Y lsb // +180 addieren ??Wire.requestFrom(I2C_address, 6); //6 bytes lesen
Die X-Werte liegen symmetrisch zur 0-Linie, bei den Y-Werten muss 180 addiert werden.
Die Z-Werte sind wesentlich höher (bis 900).
Beim Drehen des Moduls um 360 Grad auf dem platten Tisch erhalte ich für X und Y zwei schöne sinusförmige Kurven mit 90 Grad Phasenversatz (COS für X, SIN für Y). Die Minima und Maxima liegen wie zu erwarten bei je 0 (bzw 360), 90, 180 und 270 Grad bezogen auf magnetisch Nord. Die Kurven sind allerdings nicht symmetrisch zur 0-Linie (bei jedem Chip anders), daher muss der Offset-Wert ermittelt werden. Man dreht einen Vollkreis und nimmt die Mitte von Min und Max.
Daraus lässt sich der Radiant, bzw Kompasswinkel mit der Funktion
rad= atan2(y,x) errechnen und bekommt eine tadellose Kompassdarstellung.
Jetzt muss ich nur noch die Einflüsse durch Rollbewegungen kompensieren, aber das ist eine andere Geschichte…
Gerald
Hallo Sven offenbar hast Du ein Board mit einem HMC5883. Der Sketch ist für den QMC5883L wie er auf dem Modul von AZ-Delivery verbaut ist. Der HMC5883 hat eine andere I2C Adresse. Folgende Änderung im Sketch ist notwendig damit der HMC5883 funktioniert.
//I2C address of the QMC5883L
#define ADDR 0×17
Dann sollte es funktionieren.
sven
ich habe das problem,
X Value: -1
Y Value: -1
Z Value: -1
Richtung: 135.00°
LED 1 = 11 bright = 15
LED 2 = 10 bright = 15
es zeigt immer die selben werte an.
Beim arduino example HMC5883L geht es.
Ulrich Engel
Hallo Gerald,
nun funktioniert der Kompass wie gewünscht. Es waren aber Änderungen notwendig.
Erst einmal habe ich, auf Anraten eines “Profis”, das GY-271 Modul etwas (8-10 cm) vom Ring und dem Nano entfernt, um Magnetfeldeinflüsse durch Strom zu verhindern. Dann habe ich das Modul untersucht und festgestellt, dass es sich nicht um einen “original/generic” Chip handelt. Man erkennt dieses Original am Aufdruck auf dem kleinen schwarzen Chip auf dem Modul. Beim Original steht “L5883 2120”. Beim Fake, der nicht funktioniert steht “DA 5883 8012”.
Ulrich Engel
Hallo Gerald,
vielen Dank für die Antwort. Ich habe noch einmal gemäß Deiner Beschreibung die Verdrahtung kontrolliert. Dann habe ich den Kompass von Google Maps auf dem Handy eingeschaltet. Der zeigt stabil nach N wenn ich das Handy auf dem Tisch flach drehe.
Eigentlich hatte ich dieses auch für die LEDs im Ring erwartet. Es sollten doch die leuchtenden LEDs (2 Stück) beim flachen Drehen der Schaltung (x-Y des Sensors) immer in die gleiche Richtung zeigen. Nämlich nach N.
Das ist bei mir leider nicht der Fall. Es bleiben immer die gleichen LEDs an und drehen mit.
Ich habe noch kein Projekt mit einem Nano gemacht. Ist es normal, dass der schwarze Chip sehr heiß wird?
Viele Grüße aus Berlin
Ulli
Gerald
Hallo Ulrich
Ich habe jetzt die Schaltung nochmals aufgebaut. Beim Erdmagnetfeld sollten die Werte für X und Y in einem Bereich von +/- 2000 liegen und für Z bei -3000 bis -5000. Dein Y Wert ist ziemlich konstant bei etwa -6000. Ich vermute daher, dass ein externes Magnetfeld in Y Richtung vorhanden ist, das den Einfluß des Erdmagnetfeldes überdeckt. Du solltest mal die Schaltung mit Batterie betreiben und möglichst von Störquellen (Elektrogeräte) entfernt testen.
Ulrich Engel
Hallo Gerald,
eigentlich hatte ich erhofft, dass ich Euren Erfahrungsschatz nutzen kann und Unterstützung bei meinem Problem erhalte. Ich würde gerne das Projekt fertig bekommen und bei meinem Geo-Cacher (Projekt von Euch) nutzen.
Viele Grüße
Ulli aus Berlin
Ulrich Engel
Hallo,
super Idee. Tolle Ergänzung zum Tutorial “Geocaching”.
Kompilieren und Hochladen (wenn man auf Old Bootloader umschaltet) funktioniert fehlerfrei.
Mein Problem ist leider, dass die Daten, die auf den serial monitor ausgegeben werden sehr wir sind. Auch bleiben die LEDs immer an der gleichen Stelle an, wenn ich den ganzenAufbau drehe.
Hier ein Auszug. Wo könnte ich den die Ergebnisliste als Datei posten?
Start
init done
X Value: 0Y Value: 0Z Value: 0Richtung:
0.00°LED 1 = 5 bright = 0LED 2 = 6 bright = 30
X Value: -1187Y Value: -8795Z Value: -6610Richtung:
97.69°LED 1 = 10 bright = 7LED 2 = 9 bright = 23
X Value: -1177Y Value: -8857Z Value: -6552Richtung:
97.57°LED 1 = 10 bright = 7LED 2 = 9 bright = 23
X Value: -1245Y Value: -8765Z Value: -6572Richtung:
98.08°LED 1 = 10 bright = 8LED 2 = 9 bright = 22
X Value: -1270Y Value: -6092Z Value: -6647Richtung:
101.78°LED 1 = 10 bright = 11LED 2 = 9 bright = 19
X Value: -1265Y Value: -5975Z Value: -6615Richtung:
101.95°LED 1 = 10 bright = 11LED 2 = 9 bright = 19
X Value: -1335Y Value: -5960Z Value: -6662Richtung:
102.63°LED 1 = 10 bright = 12LED 2 = 9 bright = 18
X Value: -1317Y Value: -5950Z Value: -6657Richtung:
102.48°LED 1 = 10 bright = 12LED 2 = 9 bright = 18
X Value: -1355Y Value: -6017Z Value: -6720Richtung:
102.69°LED 1 = 10 bright = 12LED 2 = 9 bright = 18
X Value: -1302Y Value: -6042Z Value: -6630Richtung:
102.16°LED 1 = 10 bright = 12LED 2 = 9 bright = 18
X Value: -4462Y Value: -6542Z Value: -6672Richtung:
124.30°LED 1 = 11 bright = 4LED 2 = 10 bright = 26
X Value: -4375Y Value: -6430Z Value: -6657Richtung:
124.23°LED 1 = 11 bright = 4LED 2 = 10 bright = 26
X Value: -4197Y Value: -6415Z Value: -6695Richtung:
123.19°LED 1 = 11 bright = 3LED 2 = 10 bright = 27
X Value: -4232Y Value: -6390Z Value: -6705Richtung:
123.52°LED 1 = 11 bright = 3LED 2 = 10 bright = 27
X Value: -4232Y Value: -6425Z Value: -6732Richtung:
123.37°LED 1 = 11 bright = 3LED 2 = 10 bright = 27
Könnte dieses an dem Sensor liegen? Wie ich gelesen habe, werden ja oft auch unter gleichem Namen auch Nicht-Originale angeboten, die man nur am Aufdruck auf dem Chip identifizieren kann.
Ich habe wohl so einen “Fake” erwischt.
Wolfgang
Danke Gerald,
ich habe die Fehler gefunden.
Das Hochladen des Programmes ohne zusätzliches Modul hat es dann gebracht.
Frohe Ostern an alle
Wolfgang
Gerald
Hallo Wolfgang, die Fehlermeldung “stray 302” bedeutet dass ein Sonderzeichen im code vorkommt. Es gibt dazu einen sehr ausführlichen Blog Beitrag, der zeigt wie man diesen Fehler finden und beheben kann. Suche einfach nach “kodierungsfehler-schnell-beheben”.
Im Bereich Posts findest Du dann den Link.
Wolfgang Butenhoff
Hallo,
bei der Programmzeile:
setCtrlRegister(OSR_128,RNG_2G,ODR_100Hz,Mode_Continuous);
bekomme ich immer wieder die Meldung: " stray’ \302’ in program"
Wo ist der Fehler? Der Hinweis mit Version 1.6.22 ist berücksichtigt.
Für die Software brauche ich Hilfe ….die Hardware ist bestimmt richtig “verdrahtet”.