Bei Mobiltelefonen und anderen Geräten, die einen elektronischen 3-Achsen-Kompass verwenden, wird das in diesen Videos gezeigte Magnetometer mit einer Bewegung in shaped / 8 / S-Form kalibriert .
Warum wird diese Bewegung ausgeführt, wie lautet die Theorie, und kann jemand einen Beispiel-C-Code angeben, um sie zu implementieren?
Sie müssen meine andere ähnliche Frage durchgehen , die mehr Informationen enthält.
Einige zusätzliche Informationen zu dieser Frage: Die Plattform ist 8-Bit-AtMega32 mit AVR Studio 5.
Bis jetzt habe ich versucht: Ich habe versucht, den Durchschnitt durch 2 der Vektorwerte des Magnetometers zu teilen , um die Form zu erhalten. Denken könnte bei der Berechnung von Offsets helfen. Ich denke, wie die zwei identischen Teile / Seiten der Form das Erdmagnetfeld aufheben und die Versatzwerte ausgeben. Ich könnte falsch liegen. Aber gerade für die formbasierte Kalibrierung bin ich gerade hier. Ich denke, die Kalibrierung funktioniert so. Die Idee ist herauszufinden, ob das so funktioniert.
Ok, der Code, mit dem ich die Offsets berechnen und später einfach vom rohen magnetischen 3D-Vektor subtrahieren kann. Ich könnte völlig falsch liegen und keine Erklärung haben, wie es funktioniert. Nachdem ich das Video und die auf der Kugel aufgezeichneten Daten gesehen habe, hat sich mein Denken irgendwie beschleunigt, und ich habe diesen Gedanken in Form einer Gleichung verwendet. B)
Code:
Die Read_accl();
und Read_magnato(1);
Funktionen lesen die Sensordaten. Ich hoffe, der Code ist selbsterklärend. In der Hoffnung, dass ppl dies auf viel bessere Weise nutzen wird. : \
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;
}
}
}
Nachdem ich diese Offsets erhalten hatte, benutzte ich sie wie folgt:
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 ;
...
}
Wie ich schon sagte.