Em telefones celulares e outros dispositivos usando uma bússola eletrônica de 3 eixos, um movimento em forma de ∞ / 8 / S é usado para calibrar o magnetômetro, como mostrado nesses vídeos .
Por que esse movimento é realizado, qual é a teoria e alguém pode dar um exemplo de código C para implementá-lo?
Você deve ter que passar por minha outra pergunta semelhante contendo mais informações.
Algumas informações adicionais para esta pergunta em particular: A plataforma é o AtMega32 de 8 bits, usando o AVR Studio 5.
Até agora, tentei: tentei dividir a média por 2 dos valores vetoriais do magnetômetro que faz a forma. Pensar pode ajudar no cálculo de compensações. Eu acho que de alguma forma as duas partes / lados idênticos da forma estão cancelando o campo magnético da Terra e fornecendo os valores de deslocamento. Eu posso estar errado. Mas particularmente para a calibração baseada em formas, é onde estou atualmente. Eu acho que a calibração funciona dessa maneira. A idéia é descobrir se isso funciona dessa maneira?
Ok, o código pelo qual eu posso calcular as compensações e mais tarde simplesmente subtrair as do vetor 3D magnético Raw. Eu posso estar totalmente errado e não ter explicação sobre como isso funciona. Vendo o vídeo e os dados plotados na esfera, de alguma forma acelerou meu pensamento e usei esse pensamento na forma de equação. B)
Código:
As funções Read_accl();
e Read_magnato(1);
estão lendo os dados do sensor. Espero que o código seja auto-explicativo. Esperando que as pessoas sábias certamente usem isso de maneiras muito melhores. : \
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;
}
}
}
Depois de obter essas compensações, usei-as da seguinte maneira:
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 ;
...
}
Conforme mencionei.