Dans les téléphones mobiles et autres appareils utilisant une boussole électronique à 3 axes, un mouvement en forme de ∞ / 8 / S est utilisé pour calibrer le magnétomètre comme indiqué dans ces vidéos .
Pourquoi ce mouvement est-il effectué, quelle est la théorie, et quelqu'un peut-il donner un exemple de code C pour l'implémenter?
Vous devez avoir à passer par ma autre question similaire contenant plus d'informations.
Quelques informations supplémentaires pour cette question particulière: La plate-forme est AtMega32 8 bits, utilisant AVR Studio 5.
Jusqu'à présent, j'ai essayé: j'ai essayé de diviser la moyenne par 2 des valeurs vectorielles du magnétomètre faisant la forme. La réflexion pourrait aider à calculer les décalages. Je pense que certains comment les deux parties / côtés identiques de la forme annulent le champ magnétique terrestre et donnent les valeurs de décalage. J'ai peut être tort. Mais en particulier pour l'étalonnage basé sur la forme, c'est là que je suis actuellement. Je pense que l'étalonnage fonctionne de cette façon. L'idée est de savoir si cela fonctionne de cette façon?
Ok le code par lequel je peux calculer les décalages et plus tard simplement soustraire ceux du vecteur 3D magnétique brut. Je me trompe peut-être totalement et je n'ai aucune explication sur le fonctionnement. Voir la vidéo et les données tracées sur la sphère a quelque peu accéléré ma pensée et j'ai utilisé cette pensée sous forme d'équation. B)
Code:
Les fonctions Read_accl();
et Read_magnato(1);
lisent les données du capteur. J'espère que le code est explicite. En espérant que ppl sage l'utilisera sûrement bien mieux. : \
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;
}
}
}
Après avoir obtenu ces décalages, je les ai utilisés comme suit:
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 ;
...
}
Comme je l'ai mentionné.