En los teléfonos móviles y otros dispositivos que usan una brújula electrónica de 3 ejes, se usa un movimiento en forma de ∞ / 8 / S para calibrar el magnetómetro como se muestra en estos videos .
¿Por qué se realiza este movimiento, cuál es la teoría, y alguien puede dar algún código C de ejemplo para implementarlo?
Debes revisar mi otra pregunta similar que contiene más información.
Alguna información adicional para esta pregunta en particular: la plataforma es AtMega32 de 8 bits, usando AVR Studio 5.
Hasta ahora lo he intentado: he intentado dividir el promedio entre 2 de los valores vectoriales del magnetómetro que forma la figura. Pensar podría ayudar a calcular las compensaciones. Creo que de alguna manera las dos partes / lados idénticos de la forma están cancelando el campo magnético de la Tierra y dando los valores de desplazamiento. Podría estar equivocado. Pero particularmente para la calibración basada en la forma, aquí es donde estoy actualmente. Creo que la calibración funciona de esta manera. La idea es descubrir si eso funciona de esta manera.
Ok, el código por el cual puedo calcular los desplazamientos y luego simplemente restarlos del vector 3D magnético sin procesar. Podría estar totalmente equivocado y no tengo explicación de cómo funciona. Al ver el video y los datos trazados en la esfera, de alguna manera ha acelerado mi pensamiento y usé ese pensamiento en forma de ecuación. SI)
Código:
Las funciones Read_accl();
y Read_magnato(1);
están leyendo los datos del sensor. Espero que el código se explique por sí mismo. Esperando que las personas sabias seguramente usen esto de maneras mucho mejores. : \
void InfinityShapedCallibration()
{
unsigned char ProcessStarted = 0;
unsigned long cnt = 0;
while (1)
{
Read_accl();
// Keep reading Acc data
// Detect Horizontal position
// Detect Upside down position
// Then detect the Horizontal position again.
// Meanwhile an infinity shaped movement will be created.
// Sum up all the data, divide by the count, divide by 2 .
// !We've offsets.
if (ProcessStarted!=3)
{
//
//USART_Transmit_String("\r");
//rprintfFloat(4, g_structAccelerometerData.accx_RAW);
//USART_Transmit_String(",");
//rprintfFloat(4, g_structAccelerometerData.accy_RAW);
//USART_Transmit_String(",");
//rprintfFloat(4, g_structAccelerometerData.accz_RAW);
}
if (
abs( g_structAccelerometerData.accx_RAW) < 100
&& abs(g_structAccelerometerData.accy_RAW) < 100
&& g_structAccelerometerData.accz_RAW < -350
&& ProcessStarted != 2 && ProcessStarted != 3 && ProcessStarted != 1 )
{
ProcessStarted = 1;
}
if (ProcessStarted==1)
{
Read_magnato(1);
structMagnetometerOffsetDataToEEPROM.Off_X += g_structMegnetometerData.magx_RAW;
structMagnetometerOffsetDataToEEPROM.Off_Y += g_structMegnetometerData.magy_RAW;
structMagnetometerOffsetDataToEEPROM.Off_Z += g_structMegnetometerData.magz_RAW;
cnt++;
}
if ( g_structAccelerometerData.accz_RAW > 350
&& ProcessStarted==1)
{
ProcessStarted = 2;
}
if ( g_structAccelerometerData.accz_RAW < -350
&& ProcessStarted == 2 )
{
ProcessStarted=3;
structMagnetometerOffsetDataToEEPROM.Off_X /= cnt;
structMagnetometerOffsetDataToEEPROM.Off_X /= 2;
structMagnetometerOffsetDataToEEPROM.Off_Y /= cnt;
structMagnetometerOffsetDataToEEPROM.Off_Y /= 2;
structMagnetometerOffsetDataToEEPROM.Off_Z /= cnt;
structMagnetometerOffsetDataToEEPROM.Off_Z /= 2;
UpdateOFFSETDATAinEEPROM();
break;
}
}
}
Después de obtener estas compensaciones, las usé de la siguiente manera:
void main()
{
...
Read_magnato(1);
g_structMegnetometerData.magx_RAW -= structMagnetometerOffsetDataToEEPROM.Off_X ;
g_structMegnetometerData.magy_RAW -= structMagnetometerOffsetDataToEEPROM.Off_Y ;
g_structMegnetometerData.magz_RAW -= structMagnetometerOffsetDataToEEPROM.Off_Z ;
...
}
Como he mencionado.