PROYECTO DE BRÚJULA DIGITAL.
Creado en Diciembre 2017
INTRODUCCIÓN.
En la actualidad estamos rodeados de dispositivos inteligentes como móviles, GPS, tabletas, etc. en los cuales viene integrada una brújula mediante la cual se logra orientar el dispositivo, detectando la posición de apaisado a vertical que tiene nuestro móvil o la dirección del polo Norte en el GPS, ect. La brújula digital es un sensor que mide el valor del campo magnético en tres ejes, con esto es posible estimar la orientación del dispositivo respecto al campo magnético de la tierra.
En este tutorial veremos como utilizar la brújula digital o magnetómetro HMC5883L, tratando de explicar y realizar ejemplos con Arduino.
EL HMC5883L es un sensor magnetómetro de 3 ejes, se encuentra integrado en módulos como la GY-273 que incorporan la electrónica necesaria para conectarla de forma sencilla a un Arduino, de forma que podamos detectar y leer el campo magnético terrestre y así calcular la orientación con respecto al norte magnético de la tierra, siempre que nuestro sensor no este expuesto a algún campo magnético externo o cerca de algún objeto metálico que pueda perturbar el campo magnético terrestre.
Fig. 1 Módulo brújula digital.
Este pequeño módulo HMC5883L incorpora tres sensores de magnetorresistencia, cancelación de desfases, y conversores de 12 bits, lo que le proporciona una precisión de ±2ºC, trabaja con un tensión de 1.8 a 3.3V, pero algunos tienen un regulador interno por lo que se puede alimentar con 5V o con 3.3V en sus pines respectivos, asegúrese de estos datos. Este módulo de Honeywell HMC5883L, se comunica a través del bus I2C, cuya dirección fija es 0x1E, por lo que es sencillo obtener los datos medidos.
Actualmente, con el uso de sistemas de navegación en robots y otros vehículos, como cuadricópteros, las brújulas magnéticas son dispositivos ampliamente empleados. La medición con estos sensores se ve afectada por la presencia de campos magnéticos y metales. Por tanto, para aplicaciones de navegación es necesario combinar estos sensores con acelerómetros y giroscopios.
Para realizar los ejemplos que siguen, tenemos que instalar las librerías siguientes:
- https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/HMC5883L
- https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/I2Cdev
Para trabajar los siguientes ejercicios es necesario instalar las librerías en el IDE Arduino. En este tutorial utilizamos la biblioteca HMC5883L.h, facilitando así la programación. Una vez descargada la librería instálela, vaya al menú Programa-> Incluir librería-> Añadir Librería .ZIP y seleccione la instalación desde el archivo recién descargado, o siga los pasos de la imagen.
Una de las opciones de lectura que se puede hacer con el magnetómetro, es identificar en qué dirección está el polo norte magnético. En el tutorial de hoy mostraremos cómo puede usted fácilmente utilizar la brújula digital (magnetómetro) utilizando el Arduino.
EL ESQUEMA.
En esta ocasión vamos a utilizar 8 LEDs en circulo que nos indiquen en que dirección esta el polo Norte geográfico de la Tierra, haciendo así una brújula electrónica. Para lo cual utilizamos la biblioteca HMC5883L.h, es una biblioteca muy útil y sencilla de utilizar, con la que podemos recoger toda la información que nos brinda la brújula digital HMC5883L.
El HMC5883L se comunica con un lenguaje serial llamado I2C (Wire.h) que requiere solo dos hilos para la comunicación: uno para un reloj (SCL) y otro para los datos (SDA).
EL CÓDIGO.
Brújula digital con sensor magnetómetro HMC5883.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
// // Código brújula digital con sensor magnetometro HMC5883 // Basado en el código de http://www.ardumania.es/brujula-digital-hmc5883l/ // // Añadi LEDs para que indiquen la dirección y así no depender // del monitor Serial. // #include <Wire.h> #include <HMC5883L.h> //Include a biblioteca HMC5883L.h #include <Adafruit_HMC5883_U.h> // Se definen los LED y el pin correspondiente. #define led1 2 //Define led1 como pin2 #define led2 3 //Define led2 como pin3 #define led3 4 //Define led3 como pin4 #define led4 5 //Define led4 como pin5 #define led5 6 //Define led5 como pin6 #define led6 7 //Define led6 como pin7 #define led7 8 //Define led7 como pin8 #define led8 9 //Define led8 como pin9 HMC5883L brujula; //Instância a biblioteca para a bússola int i; //Variable para contar float grados; //Variable para almacenar el valor evaluado float preciso; //Variable para o mejorar la precison de valor medido // Asignacion de una identificacion a la brujula Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345); void displaySensorDetails(void) { sensor_t sensor; mag.getSensor(&sensor); Serial.println("------------------------------------"); Serial.print ("Sensor: "); Serial.println(sensor.name); Serial.print ("Driver Ver: "); Serial.println(sensor.version); Serial.print ("ID unica: "); Serial.println(sensor.sensor_id); Serial.print ("Valor Maximo: "); Serial.print(sensor.max_value); Serial.println(" uT"); Serial.print ("Valor Minimo: "); Serial.print(sensor.min_value); Serial.println(" uT"); Serial.print ("Resolucion: "); Serial.print(sensor.resolution); Serial.println(" uT"); Serial.println("------------------------------------"); Serial.println(""); delay(500); } void setup(void) { Serial.begin(9600); Serial.println("Magnetometro HMC5883 Test"); Serial.println(""); /* Inicializamos el sensor */ if(!mag.begin()) { // Si hay algun problema con el HMC5883 sale el aviso de que revise las conexiones Serial.println("Ooops, no se ha detectado el HMC5883 ... revisa las conexiones!"); while(1); } pinMode(led1, OUTPUT); //Define pin 2 como salída pinMode(led2, OUTPUT); //Define pin 3 como salída pinMode(led3, OUTPUT); //Define pin 4 como salída pinMode(led4, OUTPUT); //Define pin 5 como salída pinMode(led5, OUTPUT); //Define pin 6 como salída pinMode(led6, OUTPUT); //Define pin 7 como salída pinMode(led7, OUTPUT); //Define pin 8 como salída pinMode(led8, OUTPUT); //Define pin 9 como salída Wire.begin(); //Inicia la comunicacion I2C //Configura a brújula brujula = HMC5883L(); brujula.SetScale(1.3); brujula.SetMeasurementMode(Measurement_Continuous); //=================== // Muesta la información básica del sensor displaySensorDetails(); } void loop(void) { // Hacemos que el sensor tome una nueva muestra sensors_event_t event; mag.getEvent(&event); /* Sostenga el módulo de manera que Z esté señalando arriba y se pueda medir con el título X e Y Calcular la medida cuando el magnetómetro esté nivelado, y luego corregir los signos de eje */ // inicialmente los LED estarán apagados. digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); digitalWrite(led5, LOW); digitalWrite(led6, LOW); digitalWrite(led7, LOW); digitalWrite(led8, LOW); float muestra = atan2(event.magnetic.y, event.magnetic.x); preciso = 0; //A cero, la variable para una nueva lectura /* Una vez tengamos la muestra tomada, a continuación debemos agregar el "Ángulo de declinación" el ángulo de declinación es el "error" del campo magnético en su ubicación. Puede encontrar el suyo aquí: http://www.magnetic-declination.com/ Si no encuentra su ángulo de declinación, comente las dos líneas siguientes, la brújula estará ligeramente desviada*/ float declinacionAngulo = 0.13; // Valencia, angulo de declinación 0.13 muestra += declinacionAngulo; // corrige los valores negativos if(muestra < 0) muestra += 2*PI; // Comprueba si hay error debido a la adición de la declinación. if(muestra > 2*PI) muestra -= 2*PI; // Convierte los radianes a grados float muestraangulo = muestra * 180/M_PI; /* A continuación vamos a mostrar por pantalla los diferentes valores y puntos cardinales en función de las muestras tomadas. Al añadir los LEDs se puede ver la dirección con el LED encendido. */ if (muestraangulo > 350){ Serial.print("N "); Serial.print(muestraangulo); Serial.println(" LED 1"); // añadido digitalWrite(led1, HIGH);// añadido delay(500); } if (muestraangulo <= 10){ // <=15 Serial.print("N "); Serial.print(muestraangulo); Serial.println(" LED 1"); // añadido digitalWrite(led1, HIGH);// añadido delay(500); } if (muestraangulo > 10 && muestraangulo <= 80){ // >15 <=75 Serial.print("NE "); Serial.print(muestraangulo); Serial.println(" LED 2"); // añadido digitalWrite(led2, HIGH); // añadido delay(500); } if (muestraangulo > 80 && muestraangulo <= 100){ // >75 <=105 Serial.print("E "); Serial.print(muestraangulo); Serial.println(" LED 3"); // añadido digitalWrite(led3, HIGH); //añadido delay(500); } if (muestraangulo > 100 && muestraangulo <= 170){ // >105 <=165 Serial.print("SE "); Serial.print(muestraangulo); Serial.println(" LED 4"); // añadido digitalWrite(led4, HIGH); // añadido delay(500); } if(muestraangulo > 170 && muestraangulo <= 190){ // >165 <=195 Serial.print ("S "); Serial.print(muestraangulo); Serial.println(" LED 5"); // añadido digitalWrite(led5, HIGH); // añadido delay(500); } if(muestraangulo > 190 && muestraangulo <= 260){ // >195 <=255 Serial.print ("SW "); Serial.print(muestraangulo); Serial.println(" LED 6"); // añadido digitalWrite(led6, HIGH); // añadido delay(500); } if(muestraangulo > 260 && muestraangulo <= 290){ // >255 <=285 Serial.print ("W "); Serial.print(muestraangulo); Serial.println(" LED 7"); // añadido digitalWrite(led7, HIGH); // añadido delay(500); } if(muestraangulo > 290 && muestraangulo <= 350){ // >285 <=350 Serial.print ("NW "); Serial.print(muestraangulo); Serial.println(" LED 8"); // añadido digitalWrite(led8, HIGH); // añadido delay(500); } } |
Como ya se sabe, el código residente dentro de la función setup(), se ejecuta una vez al principio. En él, se inicializa la comunicación Serial a 9600/../115200 baudios, la que interese, la comunicación serial para enviar datos de cada eje a la computadora, también inicializamos I2C. Después, realizamos una operación de ‘escritura’ al HMC5883L, el motivo de esta operación de ‘escritura’ es ajustar el valor en el registro de configuración del HMC5883L para indicarle que está en modo de operación continua para realizar lecturas continuas de los datos de los ejes.
Nota. Por defecto, el chip está en modo de lectura única, lo que significa que después de leerlo una vez, estará inactivo para ahorrar energía. Una vez inactivo, le escribimos para activarlo antes de que podamos leer de nuevo; más información sobre los registros en las hojas de datos.
Una vez más, la función loop() se ejecutará permanentemente una y otra vez mientra tenga energía la tajeta. Se han añadido las sentencias digitalWrite a cada LED puesto a LOW, para que estén apagados.
-
- digitalWrite(led1, LOW);
- digitalWrite(led2, LOW);
- digitalWrite(led3, LOW);
- digitalWrite(led4, LOW);
- digitalWrite(led5, LOW);
- digitalWrite(led6, LOW);
- digitalWrite(led7, LOW);
- digitalWrite(led8, LOW);
Hasta que la dirección señalada mediante las sentencias if, encienda el led que corresponda en cada rumbo. Para ejecutar el ejemplo, mantenga la tarjeta en posición horizontal, de modo que el eje Z no varíe mucho su posición, ya que no se ha contemplado su valor.
Para obtener la orientación respecto del norte geográfico de la Tierra, usted deberá introducir la declinación de la posición en la que se encuentra. Puede consultar este valor en www.ign.es o también en www.ngdc.noaa.gov
Los datos de los ejes x, y, z se envían en serie al computador, estos valores se pueden ver utilizando el monitor ‘Serial’ del entorno de desarrollo Arduino, como se muestra en la imagen anterior. No utilizaremos los datos del eje Z. En el vídeo que sigue, se puede observar el funcionamiento del proyecto.
Vídeo
En este proyecto es posible ver con el magnetómetro, e identificar en qué dirección está el polo norte magnético. En nuestra demostración utilizamos ocho LEDs, de los cuales apuntará en la dirección que esté el Polo Norte geográfico de la Tierra, obteniendo así, una brújula electrónica.
REFERENCIAS.
- https://www.luisllamas.es/brujula-magnetica-con-arduino-compass-digital-hmc5883/
- http://www.naylampmechatronics.com/blog/49_tutorial-magnetometro-hmc5883l.html
- http://labdegaragem.com/profiles/blogs/tutorial-bussola-eletronica-com-hmc5883l
- https://www.sparkfun.com/tutorials/301
hola! quisiera descargar las librerias para realizar una practica pero no puedo descarlas no tienen la opción para ello
Hola Alejandra
Las librerías que necesitas para esta práctica las puedes encontrar en google.com donde mas opciones tendrás, además podrás encontrar más ejemplo.
Espero haber resuelto tu consulta.
Un saludo.
Es una mierda
Buenos días Vicente.
Tengo que trabajar con un campo magnético que gira, y según su posición que me transmita un valor para Arduino. En un principio había pensado utilizar este sencillo módulo, pero me encuentro con la interferencia del campo magnético terrestre.
Sabes cómo podría hacer para que no influya?
Gracias.
Muy interesante.
Muchas gracias Vicente!