Nei telefoni cellulari e in altri dispositivi che utilizzano una bussola elettronica a 3 assi, un movimento a forma di ∞ / 8 / S viene utilizzato per calibrare il magnetometro come mostrato in questi video .
Perché viene eseguito questo movimento, qual è la teoria e qualcuno può dare qualche esempio di codice C per implementarlo?
Devi passare attraverso un'altra mia domanda simile contenente maggiori informazioni.
Alcune informazioni aggiuntive per questa particolare domanda: La piattaforma è AtMega32 a 8 bit, utilizzando AVR Studio 5.
Fino ad ora ho provato: ho provato a dividere la media per 2 dei valori vettoriali del magnetometro creando la forma. Il pensiero potrebbe aiutare nel calcolo degli offset. Penso in qualche modo come le due parti / lati identici della forma stiano cancellando il campo magnetico terrestre e producendo i valori di offset. Potrei sbagliarmi. Ma in particolare per la calibrazione basata sulla forma, questo è dove sono attualmente. Penso che la calibrazione funzioni in questo modo. L'idea è di scoprire che funziona in questo modo?
Ok il codice con cui posso calcolare gli offset e successivamente sottrarre semplicemente quelli dal vettore magnetico 3D Raw. Potrei sbagliarmi totalmente e non avere spiegazioni su come funzioni. Vedendo dopo il video e i dati tracciati sulla sfera, in qualche modo ha accelerato il mio pensiero e ho usato quel pensiero su una forma di equazione. B)
Codice:
Le funzioni Read_accl();
e Read_magnato(1);
stanno leggendo i dati del sensore. Spero che il codice sia autoesplicativo. Sperando che il saggio ppl lo userà sicuramente in modi molto migliori. : \
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;
}
}
}
Dopo aver ottenuto questi offset li ho usati come segue:
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 ;
...
}
Come ho già detto.