Autor Tema: Magnetometro - UAV's  (Leído 26322 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Magnetometro - UAV's
« en: 05 de Enero de 2014, 11:51:14 »
Los magnetómetro son sensores que miden la el campo magnético (en gauss) al cual son sometidos. Si bien existen sensores que miden en uno o dos ejes, hoy en día son muy comunes los giróscopos que miden en los tres ejes. Son lo suficientemente sensibles como para medir el campo magnético de la tierra y por ellos son excelentes para obtener el ángulo que hemos rotado nuestro UAV respecto del Norte (Yaw angle).
En mi caso estoy trabajando y mostraré resultados aquí del hmc5883l de Honeywell. Lo tengo montado una plaquita que compre en dx.com.
Esta es la página del datasheet.

Como todos los sensores que hemos visto hasta ahora, los magnetómetros tienen 4 parámetros fundamentales. EL/los rangos de operacion, la sensibilidad, el Output data rate y el Zero level offset.
El magnetómetro es un sensor "lento" ya que puede trabajar a apenas 75-160 Hz dependiendo si está configurado como medicion continua o como medicion única.
La sensibilidad del sensor puede elegirse entre +-0.88 Ga hasta +-8.1Ga. Por defecto el sensor está en +-1.3Ga. Dependiendo del rango elegido tendremos una sensibilidad determinada. Por ejemplo, en +-1.3Ga la sensibilidad es de 0.92 mG/LSB.

Debido a que queremos usar el magnetómetro para medir el débil campo magnetico de la tierra debemos tener en cuenta ciertos puntos importantes.
El magnetómetro es de 3 ejes, normalmente mediremos el campo magnético con los ejes X e Y.
El vector flujo magnético terreste no es paralelo a la tierra, está levemente apuntando hacia abajo y el ángulo con respecto a la superficie terrestre depende de la latitud en donde nos encontremos.
El vector flujo no apunta directamente al Norte, esta levemente desplazado. Dependiendo de donde nos encontremos será el ángulo de desviacion.
El campo magnético de la tierra es muy debil y por lo tanto es suceptible de ser modificado o perturbado por varios factores. Debido a esto se hace necesaria la calibracion denominada soft iron y la denominada hard iron.

Hay muchas notas de aplicacion y material en la web sobre este tema, ya que es bastante complejo. Nosotros haremos algunas simplificaciones al principio para poder avanzar y luego veremos como mejorar los resultados obtenidos.
Algunos links interesantes:
http://www.varesano.net/blog/fabio/first-steps-hmc5843-arduino-verify-accuracy-its-results - Fabio Versano ha escrito mucha informacion sobre sensores (gyro, accel, mag), IMU, navegacion, etc.
http://memsense.com/support

Calibración:
http://www.bot-thoughts.com/2011/04/quick-and-dirty-compass-calibration-in.html
http://forum.arduino.cc/index.php/topic,38104.0.html
https://forum.sparkfun.com/viewtopic.php?f=14&t=18510

Bueno, vamos a tratar de poner en marcha el magnetómetro directamente para ir viendo los problemas que encontremos para ir resolviéndolos.

Saludos!
« Última modificación: 26 de Enero de 2014, 20:59:11 por elgarbe »
-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Magnetometro - UAV's
« Respuesta #1 en: 05 de Enero de 2014, 11:53:43 »
Leyendo los registros Identification

Bueno, veamos un pequeño ejemplo para leer el registro Identification Register A, B y C y verificar el funcionamiento de la comunicacion:

Lamentablemente para muchos, mi placa de desarrollo es la LPCXpresso, por lo que el código que propongo es para ella. Es C, por lo que se podrá modificar facilmente a cualquier otro uC.

Bueno, este es mi archivo HMC5883L.h
Código: [Seleccionar]
/*
 * HMC5883L.h
 *
 *  Created on: 04/12/2013
 *      Author: elgarbe
 */

#ifndef HMC5883L_H_
#define HMC5883L_H_

#include "i2c.h"
#include <math.h>

extern volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint32_t I2CReadLength[I2C_PORT_NUM];
extern volatile uint32_t I2CWriteLength[I2C_PORT_NUM];

#define HMC5883L_READ_ADDR       0x3D
#define HMC5883L_WRITE_ADDR      0x3C

#define Config_Reg_A             0x00
#define Config_Reg_B             0x01
#define Mode_Reg                 0x02
#define X_MSB_Reg                0x03
#define X_LSB_Reg                0x04
#define Z_MSB_Reg                0x05
#define Z_LSB_Reg                0x06
#define Y_MSB_Reg                0x07
#define Y_LSB_Reg                0x08
#define Status_Reg               0x09
#define ID_Reg_A                 0x0A
#define ID_Reg_B                 0x0B
#define ID_Reg_C                 0x0C

#define PORT_USED 1

short make_word(unsigned char HB, unsigned char LB);
void HMC5883L_init();
char HMC5883L_read(unsigned char reg);
char HMC5883L_write(unsigned char reg_address, unsigned char value);



short make_word(unsigned char HB, unsigned char LB){
   return ((HB << 8) | LB);
}

void HMC5883L_init(){

   HMC5883L_write(Config_Reg_A, 0x70); //Configuramos el magnetómetro
   HMC5883L_write(Config_Reg_B, 0xA0);
   HMC5883L_write(Mode_Reg, 0x00);
}


char HMC5883L_read(unsigned char reg){
I2CWriteLength[PORT_USED] = 2;
I2CReadLength[PORT_USED] = 1;
I2CMasterBuffer[PORT_USED][0] = HMC5883L_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg;
I2CMasterBuffer[PORT_USED][2] = HMC5883L_READ_ADDR;

I2CEngine( PORT_USED );

return(I2CSlaveBuffer[PORT_USED][0]);
}


char HMC5883L_write(unsigned char reg_address, unsigned char value){

I2CWriteLength[PORT_USED] = 3;
I2CReadLength[PORT_USED] = 0;
I2CMasterBuffer[PORT_USED][0] = HMC5883L_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg_address;
I2CMasterBuffer[PORT_USED][2] = value;

return(I2CEngine( PORT_USED ));
}

#endif /* HMC5883L_H_ */


Bueno, como ven al principio estan todos los define con las direcciones de cada registro. Luego tengo las funciones típicas necesarias para usar el Mag en esta aplicacion.

Mi main.c es este:

Código: [Seleccionar]
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>
#include "i2c.h"
#include "HMC5883l.h"
#include "uart2.h"


/*******************************************************************************
**   Main Function  main()
*******************************************************************************/
int main (void){
unsigned char dev_id;

I2C1Init(); /* initialize I2c1 */
HMC5883L_init();
UART2_Init(115200); // Inicializo el UART a 115200

UART2_PrintString ("\rMagnetómetro HMC5883L\r\n");
UART2_PrintString ("======== elgarbe ==========\r\n");

dev_id=HMC5883L_read(ID_Reg_A);
UART2_PrintString("\r\nEl registro Identificatio Register A contiene: ");
uart2_printUint32(dev_id, 10);

dev_id=HMC5883L_read(ID_Reg_B);
UART2_PrintString("\r\nEl registro Identificatio Register B contiene: ");
uart2_printUint32(dev_id, 10);

dev_id=HMC5883L_read(ID_Reg_C);
UART2_PrintString("\r\nEl registro Identificatio Register C contiene: ");
uart2_printUint32(dev_id, 10);

while ( 1 ){
}
}

Simplemente se inicializa el I2C, luego se inicializa el Mag. Para ello solo hace falta escribir 2 registros. el Config_Reg_A y el Config_Reg_B

Finalmente inicializamos la UART, escribimos un mensaje para luego leer los registros de identificación y mostrar su valor.

El terminal obtengo la siguiente salida



Saludos!
« Última modificación: 26 de Enero de 2014, 21:38:18 por elgarbe »
-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Magnetometro - UAV's
« Respuesta #2 en: 26 de Enero de 2014, 22:03:06 »
Leyendo los datos RAW

Bueno, ahora que ya estamos "hablando" con el Mag, debemos poder leer la informacion de los Gauss que está midiendo.
Para ello simplemente voy a agregar una funcion que me permita leer los 6 registros de datos y unir X_L con X_H para obtener el dato completo del eje X (al igual que con los otros ejes) ya que la lectura es de 16 bits con signo (complemento a 2).

Código: [Seleccionar]
char HMC5883L_read_data(){

uint32_t result=0;
I2CWriteLength[PORT_USED] = 2;
I2CReadLength[PORT_USED] = 6;
I2CMasterBuffer[PORT_USED][0] = HMC5883L_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = X_MSB_Reg;
I2CMasterBuffer[PORT_USED][2] = HMC5883L_READ_ADDR;

result=I2CEngine( PORT_USED );

X_axis = make_word(I2CSlaveBuffer[PORT_USED][0], I2CSlaveBuffer[PORT_USED][1]);
Z_axis = make_word(I2CSlaveBuffer[PORT_USED][2], I2CSlaveBuffer[PORT_USED][3]);
Y_axis = make_word(I2CSlaveBuffer[PORT_USED][4], I2CSlaveBuffer[PORT_USED][5]);

return(result);
}

Como se puede ver se leen 6 registros, a partir de la direccion X_MSB_Reg. Luego se arma el dato combinando de a dos los registros leídos para armar un short con signo (16 bits).

En el main tenemos:
Código: [Seleccionar]
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>

signed short mag_X, mag_Y, mag_Z;

volatile uint32_t msTicks; /* counts 1ms timeTicks */
// ****************
// systick_delay - creates a delay of the appropriate number of Systicks (happens every 1 ms)
__INLINE static void delay_ms (uint32_t delayTicks) {
  uint32_t currentTicks;

  currentTicks = msTicks; // read current tick counter
  // Now loop until required number of ticks passes.
  while ((msTicks - currentTicks) < delayTicks);
}


#include "i2c.h"
#include "HMC5883l.h"
#include "uart2.h"

void SysTick_Handler(void) {
msTicks++; /* increment counter necessary in Delay() */
}

/*******************************************************************************
**   Main Function  main()
*******************************************************************************/
int main (void)
{
//Configuro el SysTick para que interrumpa cada 1mseg
if (SysTick_Config(SystemCoreClock / 1000)) {
while (1);  // Capture error
}

I2C1Init(); // Inicializamos el bus I2C
HMC5883L_init(); // Inicializamos el Magnetómetro
UART2_Init(115200); // Inicializamos el UART a 115200

UART2_PrintString ("\rMagnetómetro HMC5883L\r\n");
UART2_PrintString ("======== elgarbe ==========\r\n");

UART2_PrintString ("\r\nRAW X\tRAW Y\tRAW Z\r\n");

while ( 1 ){
HMC5883L_read_data();

uart2_printInt32(mag_X, 10);
UART2_Sendchar('\t');
uart2_printInt32(mag_Y, 10);
UART2_Sendchar('\t');
uart2_printInt32(mag_Z, 10);
UART2_Sendchar('\r');
UART2_Sendchar('\n');

delay_ms(500);
}

}

Como se puede ver, tenemos 3 variables globales signed short para almacenar los datos del Mag.
Aquí estamos haciendo uso del SysTick timer de los Cortex M3. Está configurado para que interrumpa cada 1 mseg, lo usamos para crear la funcion delay_ms.
Como antes, inicializamos el bus I2C, el magnetómetro y la UART. Luego llamamos a la funcion read_data del HMC5883L e imprimimos en la UART el resultado.

Esta es una imagen de nuestra terminal:



Bien, esos son los datos crudos del mag, no son gauss ni grados de desvío del polo Norte. Podemos ver que cuando giré el sensor los datos en el eje X y Y cambiaron un poco, mientras que los del eje Z son bastantes estables.

Bien, entonces el siguiente paso lógico sería convertir los datos RAW en Gauss.

Eso quedará para la próxima entrega.
Saludos!
-
Leonardo Garberoglio

Desconectado jonathanPIC888

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 306
Re: Magnetometro - UAV's
« Respuesta #3 en: 27 de Enero de 2014, 16:33:37 »
Para las personas que están utilizando microcontroladores PIC y CCS, tenemos la siguiente librería para el magnetómetro HMC5883L:

Encabezado de la librería.


Código: C
  1. // CCS library compilation [2014]
  2. // Driver para el magnetometro HMC5883L.
  3. // Programador: Moyano Jonathan
  4. // Compilador: CCS v4.140
  5. // Version de la libreria: v1.0 Revision: 0.1
  6. // Fecha de modificacion: Enero de 2014.
  7.  
  8. // Incluimos librerias utilizadas.
  9. #include <math.h>
  10.  
  11. #define HMC5883L_READ_ADDR       0x3D
  12. #define HMC5883L_WRITE_ADDR      0x3C
  13.                            
  14. #define ConfiguratioRegisterA    0x00
  15. #define ConfiguratioRegisterB    0x01
  16. #define ModeRegister             0x02
  17. #define X_MSB_Reg                0x03
  18. #define X_LSB_Reg                0x04
  19. #define Z_MSB_Reg                0x05
  20. #define Z_LSB_Reg                0x06
  21. #define Y_MSB_Reg                0x07
  22. #define Y_LSB_Reg                0x08
  23. #define Status_Reg               0x09
  24. #define ID_Reg_A                 0x0A              
  25. #define ID_Reg_B                 0x0B
  26. #define ID_Reg_C                 0x0C
  27.  
  28. #define Measurement_Continuous   0x00
  29. #define Measurement_SingleShot   0x01
  30. #define Measurement_Idle         0x03
  31.        
  32. #define declination_angle      5.818 // Determinar segun el lugar donde vivas.
  33. // Determinar la declinacion:  http: //magnetic-declination.com/
  34. // Conversion de unidades:     http: //www.wolframalpha.com/
  35.                                    
  36. // Definimos los pines utilizados para la comunicacion (POR DEFECTO).
  37. #define _SDA PIN_B0
  38. #define _SCL PIN_B1
  39.  
  40. // Configuramos el puerto utilizado para la comunicacion I2C a 400Khz.
  41. #use i2c(Master,Fast, SDA=_SDA, SCL=_SCL)  
  42.                                              
  43. // Variables auxiliares.                                    
  44. register signed long X_axis = 0x00;
  45. register signed long Y_axis = 0x00;                                  
  46. register signed long Z_axis = 0x00;
  47.  
  48. // Factor de escala.
  49. float m_scale = 1.0;
  50.  
  51. // Escribe un registro del HMC5838L.
  52. void HMC5883L_write(unsigned char reg_address, unsigned char value);
  53. // Lee un registro del HMC5838L.
  54. unsigned char HMC5883L_read(unsigned char reg);
  55. // Escalamos los valores.
  56. void HMC5883L_set_scale(float gauss);
  57. // Setea el modo de medicion.
  58. void SetMeasurementMode(unsigned char mode);
  59. // Inicializa el magnetometro HMC5883L.
  60. void HMC5883L_init();  
  61. // Lee los datos sin escalar.
  62. void HMC5883L_read_data_raw();
  63. // Escalamos los datos.
  64. void HMC5883L_ReadScaledAxis();
  65. // Conversion de los datos a grados.
  66. float HMC5883L_headingDegree();


Aquí hay que ver un punto importante, el ángulo de declinación, que cambia según el punto geográfico donde estemos ubicados. Para esto tenemos 2 páginas web que nos
ayudarán mucho:

Ángulo de declinación

Acá tenemos que determinar donde estamos:



Luego con el dato obtenido, tenemos que convertirlo a miliradianes. Para ello tenemos la siguiente página:

Conversión de unidades



Ahora la página nos dá el valor final que tenemos que incluir en nuestro encabezado:



Luego en el archivo .h cambiamos según localidad:

Código: C
  1. #define declination_angle      5.818 // Acorde a la localidad donde vivas.

El archivo .C con el desarrollo de funciones:

Código: C
  1. // CCS library compilation [2014]
  2. // Driver para el magnetómetro HMC5883L.
  3. // Programador: Moyano Jonathan
  4. // Compilador: CCS v4.140
  5. // Versión de la librería: v1.0 Revisión: 0.1
  6. // Fecha de modificación: Enero de 2014.
  7.  
  8. // Incluimos librerías utilizadas.
  9. #include <HMC5883L.h>
  10. // Desarrollo de las funciones de usuario.
  11.  
  12. void HMC5883L_write(unsigned char reg_address, unsigned char value){
  13.  
  14.    i2c_start();                     // Inicializa comunicación I2C, condición de start.
  15.    i2c_write(HMC5883L_WRITE_ADDR);  // Envíamos la dirección del dispositivo + comando para escritura.
  16.    i2c_write(reg_address);          // Indicamos que registro será escrito.
  17.    i2c_write(value);                // Enviamos el nuevo valor al registro.
  18.    I2c_Stop();                      // Condición de stop.
  19.  
  20. }
  21.  
  22. unsigned char HMC5883L_read(unsigned char reg){
  23.  
  24. unsigned char val = 0x00;           // Variable auxiliar.
  25.    
  26.    i2c_start();                     // Inicializa comunicación I2C, condición de start.
  27.    i2c_write(HMC5883L_WRITE_ADDR);  // Envíamos la dirección del dispositivo + comando para escritura.
  28.    i2c_write(reg);                  // Indicamos que registro será leído.
  29.    i2c_start();                     // Reiniciamos la comunicación.
  30.    i2c_write(HMC5883L_READ_ADDR);   // Envíamos la dirección del dispositivo + comando para lectura.
  31.    val = i2c_read(0);               // Leemos el registro.        
  32.    i2c_stop();                      // Condición de stop.
  33.    return(val);                     // Retornamos con el valor leído.
  34. }
  35.  
  36. void HMC5883L_set_scale(float gauss)                      
  37. {
  38.    unsigned char value = 0x05;    
  39.    
  40.     if(gauss == 0.88){value = 0x00; m_scale = 0.73;}  
  41.     else if(gauss == 1.3){value = 0x01; m_scale = 0.92;}  
  42.     else if(gauss == 1.9){value = 0x02; m_scale = 1.22;}  
  43.     else if(gauss == 2.5){value = 0x03; m_scale = 1.52;}  
  44.     else if(gauss == 4.0){value = 0x04; m_scale = 2.27;}
  45.     else if(gauss == 4.7){value = 0x05; m_scale = 2.56;}  
  46.     else if(gauss == 5.6){value = 0x06; m_scale = 3.03;}    
  47.     else if(gauss == 8.1){value = 0x07; m_scale = 4.35;}        
  48.                                                
  49.    value <<= 5;
  50.    HMC5883L_write(ConfiguratioRegisterB, value);
  51. }
  52.  
  53. void SetMeasurementMode(unsigned char mode){
  54.  
  55. HMC5883L_write(ModeRegister,mode);
  56.  
  57. }
  58.  
  59. void HMC5883L_init(){
  60.  
  61.    HMC5883L_write(ConfiguratioRegisterA, 0x70);
  62.    HMC5883L_write(ConfiguratioRegisterB, 0xA0);
  63.    SetMeasurementMode(Measurement_Continuous);
  64.    HMC5883L_set_scale(1.3);
  65. }
  66.  
  67. void HMC5883L_read_data_raw(){
  68.  
  69. unsigned char lsb = 0;
  70. unsigned char msb = 0;
  71.    
  72.    i2c_start();                     // Inicializa comunicación I2C, condición de start.
  73.    i2c_Write(HMC5883L_WRITE_ADDR);  // Envíamos la dirección del dispositivo + comando para escritura.
  74.    i2c_Write(X_MSB_Reg);            // Accedemos a la parte alta del registro que contiene los datos en el eje X.
  75.    i2c_Start();                     // Reiniciamos la comunicación.
  76.    i2c_Write(HMC5883L_READ_ADDR);   // Envíamos la dirección del dispositivo + comando para lectura.
  77.    
  78.    msb = i2c_Read();                // Lee MSB del registro que contiene los datos en el eje X.
  79.    lsb = i2c_Read();                // Lee LSB del registro que contiene los datos en el eje X.
  80.    X_axis = make16(msb,lsb);        // Guarda los datos en una variable auxiliar.
  81.                            
  82.    msb = I2C_Read();                // Lee MSB del registro que contiene los datos en el eje Z.
  83.    lsb = I2C_Read();                // Lee LSB del registro que contiene los datos en el eje Z.
  84.    Z_axis = make16(msb,lsb);        // Guarda los datos en una variable auxiliar.
  85.                    
  86.    msb = I2C_Read();                // Lee MSB del registro que contiene los datos en el eje Y.
  87.    lsb = I2C_Read(0);               // Lee LSB del registro que contiene los datos en el eje Y.
  88.    Y_axis = make16(msb,lsb);        // Guarda los datos en una variable auxiliar.    
  89.                        
  90.    i2c_stop();                      // Condición de stop.
  91. }
  92.  
  93. void HMC5883L_ReadScaledAxis(){
  94.  
  95.    X_axis *= m_scale;
  96.    Z_axis *= m_scale;                            
  97.    Y_Axis *= m_scale;
  98. }
  99.  
  100. float HMC5883L_headingDegree(){
  101.  
  102. register float heading = 0.00;
  103.    
  104.    HMC5883L_read_data_raw();
  105.    HMC5883L_ReadScaledAxis();
  106.    heading = atan2(Y_axis, X_axis);
  107.    float _declinationAngle = declination_angle/1000.0;
  108.     heading += _declinationAngle;    
  109.                  
  110.     if(heading < 0.0)
  111.     {
  112.       heading += (2.0 * PI);
  113.     }
  114.    
  115.     if(heading > (2.0 * PI))                
  116.     {                            
  117.       heading -= (2.0 * PI);
  118.     }                    
  119.                    
  120.    heading *= (180.0 / PI);
  121.                    
  122.    return heading;
  123. }

La función float HMC5883L_headingDegree(), obtiene el rumbo o dirección en grados.

Para ver el funcionamiento del mag, tenemos el siguiente main:

Código: C
  1. // Programa: Prueba del sensor HMC5883L.
  2. // Programador: Moyano Jonathan.
  3. // Fecha: Enero de 2014.
  4. // Versión: v1.0
  5. // Revisión: r0.1
  6. /////////////////////////////////////////
  7.  
  8. // Incluimos plantilla.
  9. #include <Plantilla_UconnectME28.h>  // Drivers de periféricos.
  10.  
  11.  
  12.  
  13. void main () {
  14.  
  15. // Inicializamos el sensor.
  16. HMC5883L_init();
  17.  
  18.    while(true){
  19.  
  20.       // Leemos los datos sin escalar.
  21.       HMC5883L_read_data_raw();
  22.        fprintf(DEBUG,"xRaw:%lu yRaw:%lu zRaw:%lu\r\n",X_axis,Y_axis,Z_axis);
  23.       // Leemos los datos escalados.
  24.       HMC5883L_ReadScaledAxis();
  25.        fprintf(DEBUG,"xScaled:%lu yScaled:%lu zScaled:%lu\r\n",X_axis,Y_axis,Z_axis);
  26.       // Leemos el ángulo en grados.
  27.        fprintf(DEBUG,"Heading:%03.2f\r\n\r\n",HMC5883L_headingDegree());
  28.       // 250 ms entre lecturas.
  29.       delay_ms(250);
  30.  
  31.    }  
  32.    
  33.     }

Para más información, podemos recurrir a la siguiente página (puede ser un poco lenta la carga): http://www.loveelectronics.co.uk/Tutorials/8/hmc5883l-tutorial-and-arduino-library

El tutorial es para arduino, pero sirve para cualquier plataforma.

Todavía falta implementar la compensación de inclinación, utilizando un acelerómetro, pero lo dejaremos para más adelante. Mientras tanto, pueden ver la implementación
con arduino en el siguiente enlace: http://www.loveelectronics.co.uk/Tutorials/13/tilt-compensated-compass-arduino-tutorial

Saludos !  :-/


Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Magnetometro - UAV's
« Respuesta #4 en: 27 de Enero de 2014, 17:18:59 »
Muy, pero muy bueno Jonathan!!!!!

Que bueno que compartas con nosotros tus avances! Desde ya que voy a tomar muchos de tus criterios de programacion para mejorar mis librerías!!!

Saludos y estamos en contacto
-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Magnetometro - UAV's
« Respuesta #5 en: 27 de Enero de 2014, 21:24:53 »
Obteniendo Gauss - Verificando calibracion

Bueno, llegó el momento de que este bichito empiece a dar informacion que sirva para algo!

Como ya hemos comentado y como bien nos ha mostrado jonathan, el magnetómetro mide el campo magnético de la tierra. En mi caso estoy usando la medicion con los eje X e Y paralelos a la tierra. Por lo tanto, con ellos realizaré la medicion.
Así como los gyro y accel tenían probelmas de zero rate level y había que hacer una calibracion más o menos complicada, los magnetómetro tienen lo suyo.
El campo magnético de la tierra es muy débil y por lo tanto suceptible a muchas perturbaciones. un imán cercano, una mesa metálica, un motor eléctrico funcionando cerca, son todas fuentes de perturbaciones. Por lo tanto es de esperarce que para un correcto funcionamiento se deba calibrar el magnetómetro en el dispositivo final en el que será usado.

Bueno, veamos el código.
Mi HMC5883L.h es el siguiente:

Código: [Seleccionar]
#ifndef HMC5883L_H_
#define HMC5883L_H_

#include "i2c.h"
#include <math.h>

extern volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint32_t I2CReadLength[I2C_PORT_NUM];
extern volatile uint32_t I2CWriteLength[I2C_PORT_NUM];

#define HMC5883L_READ_ADDR       0x3D
#define HMC5883L_WRITE_ADDR      0x3C

#define Config_Reg_A             0x00
#define Config_Reg_B             0x01
#define Mode_Reg                 0x02
#define X_MSB_Reg                0x03
#define X_LSB_Reg                0x04
#define Z_MSB_Reg                0x05
#define Z_LSB_Reg                0x06
#define Y_MSB_Reg                0x07
#define Y_LSB_Reg                0x08
#define Status_Reg               0x09
#define ID_Reg_A                 0x0A
#define ID_Reg_B                 0x0B
#define ID_Reg_C                 0x0C

#define PORT_USED 1

short make_word(unsigned char HB, unsigned char LB);
void HMC5883L_init();
char HMC5883L_read(unsigned char reg);
char HMC5883L_write(unsigned char reg_address, unsigned char value);
char HMC5883L_read_data();


short make_word(unsigned char HB, unsigned char LB){
   return ((HB << 8) | LB);
}

void HMC5883L_init(){

   HMC5883L_write(Config_Reg_A, 0b00010000); //Configuramos el magnetómetro sin promedio de muestras
   HMC5883L_write(Config_Reg_B, 0b00100000); //15Hz de ODR, Normal mode, 1.3Ga de rango
   HMC5883L_write(Mode_Reg, 0x00); //Modo de sensado continuo
}


char HMC5883L_read(unsigned char reg){
I2CWriteLength[PORT_USED] = 2;
I2CReadLength[PORT_USED] = 1;
I2CMasterBuffer[PORT_USED][0] = HMC5883L_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg;
I2CMasterBuffer[PORT_USED][2] = HMC5883L_READ_ADDR;

I2CEngine( PORT_USED );

return(I2CSlaveBuffer[PORT_USED][0]);
}


char HMC5883L_write(unsigned char reg_address, unsigned char value){

I2CWriteLength[PORT_USED] = 3;
I2CReadLength[PORT_USED] = 0;
I2CMasterBuffer[PORT_USED][0] = HMC5883L_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg_address;
I2CMasterBuffer[PORT_USED][2] = value;

return(I2CEngine( PORT_USED ));
}

char HMC5883L_read_data(){

uint32_t result=0;
I2CWriteLength[PORT_USED] = 2;
I2CReadLength[PORT_USED] = 6;
I2CMasterBuffer[PORT_USED][0] = HMC5883L_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = X_MSB_Reg;
I2CMasterBuffer[PORT_USED][2] = HMC5883L_READ_ADDR;

result=I2CEngine( PORT_USED );

mag_X = make_word(I2CSlaveBuffer[PORT_USED][0], I2CSlaveBuffer[PORT_USED][1]);
mag_Z = make_word(I2CSlaveBuffer[PORT_USED][2], I2CSlaveBuffer[PORT_USED][3]);
mag_Y = make_word(I2CSlaveBuffer[PORT_USED][4], I2CSlaveBuffer[PORT_USED][5]);

return(result);
}
#endif /* HMC5883L_H_ */

Como se puede ver en la inicializacion solo configuramos el sensor para que haga lecturas continuas, sin promediarlas, un ODR de 15Hz y un rango de +-1.3Gauss. Con este rango, la sensibilidad queda determinada en 0.92mgauss/LSB.

En esta aplicacion lo que estoy buscando es mostrar gráficamente los datos que devuelve el magnetómetro con y sin perturvaciones. Es por ello que no haeré aún el cálculo del ángulo respecto del Norte.

Mi main.c es el siguiente:

Código: [Seleccionar]
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>

signed short mag_X = 0;
signed short mag_Y = 0;
signed short mag_Z = 0;

volatile uint32_t msTicks; /* counts 1ms timeTicks */
// ****************
// systick_delay - creates a delay of the appropriate number of Systicks (happens every 1 ms)
__INLINE static void delay_ms (uint32_t delayTicks) {
  uint32_t currentTicks;

  currentTicks = msTicks; // read current tick counter
  // Now loop until required number of ticks passes.
  while ((msTicks - currentTicks) < delayTicks);
}


#include "i2c.h"
#include "HMC5883l.h"
#include "uart2.h"

void SysTick_Handler(void) {
msTicks++; /* increment counter necessary in Delay() */
}

/*******************************************************************************
**   Main Function  main()
*******************************************************************************/
int main (void)
{
float gaus_X=0.0;
float gaus_Y=0.0;
float gaus_Z=0.0;

//Configuro el SysTick para que interrumpa cada 1mseg
if (SysTick_Config(SystemCoreClock / 1000)) {
while (1);  // Capture error
}

I2C1Init(); // Inicializamos el bus I2C
HMC5883L_init(); // Inicializamos el Magnetómetro
UART2_Init(115200); // Inicializamos el UART a 115200

UART2_PrintString ("\rMagnetómetro HMC5883L\r\n");
UART2_PrintString ("======== elgarbe ==========\r\n");

UART2_PrintString ("\r\nGauss X\tGauss Y\tGauss Z\r\n");

while ( 1 ){
HMC5883L_read_data();

gaus_X = (float)mag_X * 0.92/1000;
gaus_Y = (float)mag_Y * 0.92/1000;
gaus_Z = (float)mag_Z * 0.92/1000;

uart2_printDouble(gaus_X, 4);
UART2_Sendchar('\t');
uart2_printDouble(gaus_Y, 4);
UART2_Sendchar('\t');
uart2_printDouble(gaus_Z, 4);
UART2_Sendchar('\r');
UART2_Sendchar('\n');

delay_ms(500);
}

}

Como se puede observar simplemente leemos los datos RAW y los multiplicamos por la sensibilidad. La divicion por 1000 es para obtener el resultado en gauss. Según la wikipedia el campo magnético de la tierra ronda los 0.25 a 0.65 gauss.

Veamos que obtenemos nosotros:



como se puede ver estamos en concordancia con lo esperado.

Bueno, ahora biene lo importante, antes de poder leer el ángulo de desviacion respecto al Norte magnético (o al norte geográfico si hacemos la correccion que explicó jonathan en 2 post más arriba) debemos asegurarnos que el offset y la sensibilidad de cada eje sea correcto. Para ello vamos a loguear datos cada xx mseg del eje X y del eje Y. Luego haremos un gráfico X vs Y en excel para ver la figura que se forma. La teoría dice que debería ser un círculo centrado en el origen... veamos que obtengo:



Bueno, como puede observarse tenemos un círculo casi perfecto, el tema es que lejos está de estar centrado en el origen.
Bueno, empecemos a estudiar los datos. Lo primero que debemos obtener es el máximo y el mínimo en cada eje, en mi caso obtengo:

Maximo X   0,3551   Minimo X   0,011
Maximo Y   -0,1592   Minimo Y   -0,495

con estos datos podemos obtener el rango en cada eje:

Rango X   0,3441
Rango Y   0,3358

Como podemos ver son muy parecidos, por lo que no parece requerir ajuste de sensivilidad. Incluso la pequeña diferencia puede deberse a alguna inclinacion involuntaria del sensor mientras lo giraba...

Bueno, con estos datos calculo el offset con el que hay que ajustar cada eje para obtener el círculo centrado en el origen:

Offset X   0,18305
Offset Y   -0,3271

restando dicho valor a cada lectura del magnetómetro obtendremos la lectura corregida.

Veamos ahora el resultado aplicando ese offset a los datos previamente logueados:



Bueno, ahora sí! un círculo casi perfecto!!!!

Este algoritmo de calibración debería implementarse en el uC y ejecutarlo al montarlo en el dispositivo final. Esos valores de offset deberían ser definitivos.
Pueden ver en el primer post la llamada calibracion para hard iron y para soft iron.

Bueno, con el magnetómetro corregido podemos obtener el tan deseado ángulo respecto al norte. Para ello utilizaremos el trabajo de Jonathan y sus librerías.

Saludos!
-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Magnetometro - UAV's
« Respuesta #6 en: 27 de Enero de 2014, 22:37:12 »
Obteniendo el Heading (° respecto del norte)

Bueno, ahora si estamos en condiciones de probar lo que nos propone Jonathan, el cálculo del ángulo de giro respecto del Norte, o Heading.
Como les venía comentando, en mi caso no necesito una medicion absoluta (posicion respecto del Norte geográfico) sino que necesito una medicion relatuva, por lo menos por ahora. Es por ello que voy a ovbiar por ahora el dato declination del lugar.

Sin mucho que agregar a lo que escribio jonathan, este es mi main.c:

Código: [Seleccionar]
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>

signed short mag_X = 0;
signed short mag_Y = 0;
signed short mag_Z = 0;
#define PI  3.141592653589793238462643383279502884197f

volatile uint32_t msTicks; /* counts 1ms timeTicks */
// ****************
// systick_delay - creates a delay of the appropriate number of Systicks (happens every 1 ms)
__INLINE static void delay_ms (uint32_t delayTicks) {
  uint32_t currentTicks;

  currentTicks = msTicks; // read current tick counter
  // Now loop until required number of ticks passes.
  while ((msTicks - currentTicks) < delayTicks);
}


#include "i2c.h"
#include "HMC5883l.h"
#include "uart2.h"

void SysTick_Handler(void) {
msTicks++; /* increment counter necessary in Delay() */
}

/*******************************************************************************
**   Main Function  main()
*******************************************************************************/
int main (void)
{
float gaus_X=0.0;
float gaus_Y=0.0;
float gaus_Z=0.0;
float heading=0.0;

//Configuro el SysTick para que interrumpa cada 1mseg
if (SysTick_Config(SystemCoreClock / 1000)) {
while (1);  // Capture error
}

I2C1Init(); // Inicializamos el bus I2C
HMC5883L_init(); // Inicializamos el Magnetómetro
UART2_Init(115200); // Inicializamos el UART a 115200

UART2_PrintString ("\rMagnetómetro HMC5883L\r\n");
UART2_PrintString ("======== elgarbe ==========\r\n");

UART2_PrintString ("\r\nGauss X\tGauss Y\tHeading\r\n");

while ( 1 ){
HMC5883L_read_data();

gaus_X = (float)mag_X * 0.92/1000 - 0.18305; //Resto el offset obtenido en el Excel
gaus_Y = (float)mag_Y * 0.92/1000 + 0.3271;
gaus_Z = (float)mag_Z * 0.92/1000;

heading = atan2(gaus_Y, gaus_X); //Calculo el ángulo respecto al Norte Magnético
if(heading < 0.0){ //Si el valor es negativo
heading += (2.0 * PI); //sumamos 2*Pi para que no queden cortes en transiciones
} // de 179° a -180°
if(heading > (2.0 * PI)){ // Por si el valor es mayor a 2 PI
heading -= (2.0 * PI);
}
heading *= (180.0 / PI); //Paso a °

uart2_printDouble(gaus_X, 4);
UART2_Sendchar('\t');
uart2_printDouble(gaus_Y, 4);
UART2_Sendchar('\t');
uart2_printDouble(heading, 4);
UART2_Sendchar('\r');
UART2_Sendchar('\n');

delay_ms(500);
}

}

La gran diferencia es que ahora ajustamos con el Offset calculado en el post anterior para poder obtener lecturas correctas.
Bien, con esa correccion y agregando el cálculo del heading obtengo lo siguiente en el terminal:

Código: [Seleccionar]

Magnetómetro HMC5883L
======== elgarbe ==========

Gauss X Gauss Y Heading
0.1629 0.0318 11.0411
0.1675 0.0088 3.0011
0.1629 -0.0170 354.0482
0.1583 -0.0418 345.1989
0.1564 -0.0455 343.7822
0.1518 -0.0602 338.3654
0.1417 -0.0777 331.2639
0.1316 -0.0933 324.6510
0.1104 -0.1127 314.4273
0.1003 -0.1292 307.8212
0.0773 -0.1393 299.0228
0.0470 -0.1513 287.2397
0.0304 -0.1559 281.0305
0.0065 -0.1614 272.2953
-0.0202 -0.1596 262.7822
-0.0395 -0.1577 255.9313
-0.0763 -0.1412 241.6018
-0.1067 -0.1265 229.8468
-0.1288 -0.1035 218.7801
-0.1444 -0.0777 208.2825
-0.1610 -0.0519 197.8833
-0.1610 -0.0372 193.0193
-0.1711 -0.0115 183.8321
-0.1711 0.0180 174.0008
-0.1674 0.0391 166.8408
-0.1545 0.0778 153.2824
-0.1380 0.1054 142.6278
-0.1233 0.1201 135.7416
-0.1067 0.1348 128.3564
-0.0966 0.1422 124.1847
-0.0782 0.1569 116.4832
-0.0542 0.1679 107.9021
-0.0276 0.1735 99.0311
-0.0037 0.1753 91.1928
0.0120 0.1716 86.0036
0.0267 0.1689 81.0115
0.0543 0.1633 71.6082
0.0764 0.1523 63.3628
0.0985 0.1376 54.4076
0.1169 0.1201 45.7809
0.1288 0.1045 39.0364
0.1463 0.0805 28.8317
0.1555 0.0640 22.3633
0.1638 0.0327 11.2904

Podemos observar un giro completo.  :-/

Bueno, queda pendiente algunas de las cosas más importantes, incluir la rutina de calibracion en el código (requiere de interaccion del usuari ocon el sistema), estudiar la calibracion necesaria cuando el sensor está cerca de objetos que perturben el campo de la tierra y finalmente la compensación por inclinacion...

Saludos!
-
Leonardo Garberoglio

Desconectado jonathanPIC888

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 306
Re: Magnetometro - UAV's
« Respuesta #7 en: 27 de Enero de 2014, 22:44:28 »
En este semana voy a modificar las librerías para poder añadir tu rutina de calibración y voy a corroborar para ver si obtengo resultados similares.

Desconectado PCCM

  • PIC16
  • ***
  • Mensajes: 109
Re: Magnetometro - UAV's
« Respuesta #8 en: 28 de Enero de 2014, 18:29:58 »
Recuerda que la calibración debe ser en 3D, ya que los UAV no realizan movimientos solo en 2D.
La calibración cuando esta cerca de objetos que perturban el campo magnético de la tierra se hace la misma calibración pero con aquellos elementos.
En cuanto la compensación por inclinación si no me convence como escribí en el otro post. Asi se use los ángulos de inclinación para corregirlos, no se obtiene buenos resultados, llega a los 40 grados(ejem. cabeceo) aprox y a partir de ahí tengo una desviación de hasta 20 grados en azimut(cuando llega a 90 grados en cabeceo).

Espero que alguien me confirme o diga que si funciona para todos los angulos y como lo hizo. :mrgreen:
Ya que en lo que he leído sobre la corrección de inclinación no he visto que hagan pruebas para ángulos pronunciados.

Saludos.

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Magnetometro - UAV's
« Respuesta #9 en: 28 de Enero de 2014, 19:27:01 »
Recuerda que la calibración debe ser en 3D, ya que los UAV no realizan movimientos solo en 2D.
La calibración cuando esta cerca de objetos que perturban el campo magnético de la tierra se hace la misma calibración pero con aquellos elementos.
En cuanto la compensación por inclinación si no me convence como escribí en el otro post. Asi se use los ángulos de inclinación para corregirlos, no se obtiene buenos resultados, llega a los 40 grados(ejem. cabeceo) aprox y a partir de ahí tengo una desviación de hasta 20 grados en azimut(cuando llega a 90 grados en cabeceo).

Espero que alguien me confirme o diga que si funciona para todos los angulos y como lo hizo. :mrgreen:
Ya que en lo que he leído sobre la corrección de inclinación no he visto que hagan pruebas para ángulos pronunciados.

Saludos.

El tema me parece que pasa por que en los UAV "caseros" el magnetómetro es un "accesorio". Se utiliza, generalmente, para ajustar la deriva del giróscopo, como ya bien sabes. Entonces no se esfuerzan demasiado en hacerlo funcionar en cualquier ángulo. yo no he visto tampoco aplicaciones funcionando bien con grandes inclinaciones.... aparte si queremos hilar fino, ni siquiera el acelerómetro sirve para medir ángulos cercanos a los 90°. Pasando los 45° pierde la linealidad y la gran sensivilidad que tiene la funcion seno con ángulos pequeños...
En tu caso necesitás si o sí presicion en cualquier ángulo?.

Saludos!
-
Leonardo Garberoglio

Desconectado PCCM

  • PIC16
  • ***
  • Mensajes: 109
Re: Magnetometro - UAV's
« Respuesta #10 en: 30 de Enero de 2014, 21:50:19 »
Para las inclinaciones pronunciadas hay varias aplicaciones en videojuegos por ejemplo. y el magnetómetro creo que es muy importante(u otro sensor que sense el azimut) no lo veo que alguien lo utilice como accesorio sobre todo en UAV caseros. Lo que quiero mas que precisión es robustes, ya que para que un dato de azimut varié mucho ante una inclinación no me da confiabilidad de aplicar otros algoritmos y que se comporten bien.(y en otras pruebas variaba hasta mas, llegaba a mas de 40 grados, analizándolo con los datos guardados ya que yo veia 20 grados a puro ojo nomas.)

Bueno escribo para responder a mi pregunta, el cual estaba convencido de que se puede hacer un buen funcionamiento del magnetómetro para inclinaciones pronunciadas después de ver el siguiente video.


Desde el minuto 2:30 me respondió a mi pregunta.

Lo que sucedía era de que la calibración lo realizaba en otra hoja, pero lo raro es que el programa no realizaba la corrección de la calibración(es bien raro). Bueno lo que hice es hacer la calibración en la hoja principal.

Obteniendo buenos resultados.


Como se puede observar en la leyenda para angulos de cabeceo de [-75.6 hasta 79]  y banqueo de[-74.7 hasta 84] el azimut permanecía en promedio de 158 grados. bueno con un rango de 15 grados, pero eso se debe a al movimiento en azimut que realizaba mientras cabeceaba o banqueaba. hice otra prueba mas precisa y se desviaba promedio 5 grados, a veces se desviaba solo 1 grados. esas variaciones creo se deben al calculo de la actitud ya que el filtro kalman que aplico aún no es robusto y tiene una pequeña latencia en la estimación del angulo. ya que parece que aún no tuneo bien la covarianza del error en el proceso. o bien aplicar el kalman extendido, lo cual aún voy a probar.  

Aunque en el video dice que las inclinaciones le afectan minimamente no dice cuanto es "minimamente". pero por ahora me conformo con la respuesta.
En la parte derecha por si alguien quiere analizar estan las lecturas del magnetometro, todo analizado en las 548 muestras.

Saludos.

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Magnetometro - UAV's
« Respuesta #11 en: 31 de Enero de 2014, 21:08:24 »
Hola!

Como yo lo veo, usando la matriz DCM, el sensor principal es el giróscopo. Ese es el sensor que debe funcionar lo mejor posible y el que hay que calibrar lo mejor posible. Luego, el resto son "accesorios", el acelerómetro permitirá corregir uno de los vectores de la DCM y el magnetómetro otro vector. Incluso el MatrixPilot que es más para aviones utiliza el GPS para el heading y corregir el yaw. Son sensores que se usan para "corregir" el drift del gyro. El peso que se le da a la correccion ronda el 1% por lo que es muy poco lo que corrige.
Incluso imaginate que si el gyro deriva muy poco, con corregir una vez cada tanto alcanzaría. uno podría ovbiar la medicion del magnetómetro cuando el UAV este inclinado cierto ángulo si quisiera...
Lo qu eplanteo es el caso extremo, si se puede calibrar bien el acelerómetro y el magnetómetro todo funcionará mejor, pero no lo veo tan crítico. Ahora estoy por agregar el acelerómetro a la DCM para ver que resultados tenemos...

Saludos
-
Leonardo Garberoglio

Desconectado chavaroon

  • PIC10
  • *
  • Mensajes: 4
Re: Magnetometro - UAV's
« Respuesta #12 en: 20 de Octubre de 2014, 14:48:33 »
Oye elgarbe, ¿al obtener los datos en Excel (Que no sé cómo lo haces), lo haces moviendo de algún modo al Magnetómetro? ¿O dejas al sensor estático? Tengo esa curiosidad, pues estoy tratando de calibrar el mío. Para calibrarlo en realidad solo hago múltiples mediciones y obtengo los mínimos y máximos de los ejes X y Y. Tomo esa diferencia en los ejes y se la resto a las nuevas mediciones. Pero no logro obtener buenos resultados. Supongo pues que es en la calibración.

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Magnetometro - UAV's
« Respuesta #13 en: 20 de Octubre de 2014, 15:18:26 »
Oye elgarbe, ¿al obtener los datos en Excel (Que no sé cómo lo haces), lo haces moviendo de algún modo al Magnetómetro? ¿O dejas al sensor estático? Tengo esa curiosidad, pues estoy tratando de calibrar el mío. Para calibrarlo en realidad solo hago múltiples mediciones y obtengo los mínimos y máximos de los ejes X y Y. Tomo esa diferencia en los ejes y se la resto a las nuevas mediciones. Pero no logro obtener buenos resultados. Supongo pues que es en la calibración.

para calibrar tenes que rotar 360º el sensor en un solo eje y almacenar lo obtenido, luego en otro eje y luego en otro. Luego se grafica en excel y se obtiene el offset en cada eje.
No debe haber objetos metálicos serca ni campos magneticos ni electricos potentes.

sds.
-
Leonardo Garberoglio

Desconectado chavaroon

  • PIC10
  • *
  • Mensajes: 4
Re: Magnetometro - UAV's
« Respuesta #14 en: 14 de Enero de 2015, 22:57:58 »
Oye elgarbe, ¿al obtener los datos en Excel (Que no sé cómo lo haces), lo haces moviendo de algún modo al Magnetómetro? ¿O dejas al sensor estático? Tengo esa curiosidad, pues estoy tratando de calibrar el mío. Para calibrarlo en realidad solo hago múltiples mediciones y obtengo los mínimos y máximos de los ejes X y Y. Tomo esa diferencia en los ejes y se la resto a las nuevas mediciones. Pero no logro obtener buenos resultados. Supongo pues que es en la calibración.

para calibrar tenes que rotar 360º el sensor en un solo eje y almacenar lo obtenido, luego en otro eje y luego en otro. Luego se grafica en excel y se obtiene el offset en cada eje.
No debe haber objetos metálicos serca ni campos magneticos ni electricos potentes.

sds.

Gracias por el dato, oye y aprovechando ¿Cómo haces las gráficas X y Y? ¿Qué software utilizas o qué onda?
Ah, por cierto. En tu opinión: ¿Qué objetos afectan la calibración del Magnetómetro? Porque tengo en mi escritorio Bocinas, Celulares, un RadioControl, una Batería y motores DC y Brushless Jaja
« Última modificación: 14 de Enero de 2015, 23:00:15 por chavaroon »


 

anything