В мобильных телефонах и других устройствах, использующих 3-осевой электронный компас, для калибровки магнитометра используется движение в форме ∞ / 8 / S, как показано на этих видео .
Почему выполняется это движение, какова теория, и может ли кто-нибудь привести пример кода C для его реализации?
Вы должны пройти через мой другой похожий вопрос, содержащий больше информации.
Некоторая дополнительная информация для этого конкретного вопроса: Платформа 8-битная AtMega32, с использованием AVR Studio 5.
До сих пор я пытался: я пытался разделить среднее значение на 2 вектора значений магнитометра, делающего форму. Мышление может помочь в расчете смещений. Я думаю, что две одинаковые части / стороны фигуры нейтрализуют магнитное поле Земли и выдают значения смещения. Я могу быть не прав. Но особенно для калибровки на основе формы это то, где я сейчас нахожусь. Я думаю, что калибровка работает таким образом. Идея состоит в том, чтобы выяснить, так ли это работает?
Хорошо, код, по которому я могу вычислить смещения, а затем просто вычесть их из необработанного магнитного трехмерного вектора. Я могу быть совершенно неправ и не иметь объяснения, как это работает. Просмотр видео и данных, нанесенных на сферу, как-то ускорил мою мысль, и я использовал эту мысль в форме уравнения. B)
Код:
Функции Read_accl();
и Read_magnato(1);
считывают данные датчика. Я надеюсь, что код не требует пояснений. Надеюсь, мудрый человек будет использовать это гораздо лучше. : \
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;
}
}
}
После получения этих смещений я использовал их следующим образом:
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 ;
...
}
Как я уже заметил.