Hallo Zusammen,
ich habe das mit folgender Routine bis jetzt immer versucht, bin mir aber nicht sicher ob das so richtig ist.
Code:
void getLSM303_CalibrationValues(void)
{
int16_t MinValues[3],MaxValues[3];
int16_t Average[3],i,y,iValue;
float Average_rad;
for (i=0;i<3;i++) // Setup the Min/max values
{
MaxValues[i]= -32760;
MinValues[i] = 32760;
}
Serial_string_printf("\n\nStart of calibration Move around all directions\n\r");
Serial_string_printf("Press any key to abort the calibration\n\r");
read_Array_LH_I2c(LM303_ADR,ADDR_READ_AUTOINCREMENT + ADDR_OUT_X_L_M,LM303_magnet_raw,sizeof(LM303_magnet_raw));
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_X_L_M, 0); // Clear the existing Offset value of the chip
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_X_H_M, 0);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Y_L_M, 0); // Clear the existing Offset value of the chip
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Y_H_M, 0);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Z_L_M, 0); // Clear the existing Offset value of the chip
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Z_H_M, 0);
for(i=0;i<32000;i++)
{
read_LSM303();
// read_Array_LH_I2c(LM303_ADR,ADDR_READ_AUTOINCREMENT + ADDR_OUT_X_L_M,LM303_magnet_raw,sizeof(LM303_magnet_raw));
if( (i % 100) == 0 ) // show every 100 readings
STATUS_LED_TOOGLE; // Show Updating of values by toggle bit
if( (i % 1000) == 0 ) // show every 1000 readings
{
Serial_string_printf("Loop Value : ");
Serial_int16_printf(i);
Serial_string_printf("\r");
}
for (y=0;y<3;y++) // Setup the Min/max values
{
if (LM303_magnet[y] > MaxValues[y] ) // Find the max value of the Sensor
MaxValues[y] = LM303_magnet[y];
if (LM303_magnet[y] < MinValues[y] ) // Find the min value of the sensor
MinValues[y] = LM303_magnet[y];
}
}
for (i=0;i<3;i++) // Average distance from the center
{
iValue =((MinValues[i] + MaxValues[i]) / 2); // get the average distance from the center
MaxValues[i] = MaxValues[i] - iValue ; //
MinValues[i] = MinValues[i] - iValue ;
Serial_string_printf("\r\n Min: ");
Serial_float_printf(MinValues[i]);
Serial_string_printf(" Max: ");
Serial_float_printf(MaxValues[i]);
}
Average_rad =0.0;
for (i=0;i<3;i++) // Setup the Min/max values
{
Average[i] = (MaxValues[i] + (-1*MinValues[i]) / 2 );
LM303_magnet_offset[i] = (MaxValues[i] + MinValues[i]) / 2 ;
Average_rad += (float) Average[i];
}
Average_rad /= 3.0;
//Finally calculate the scale factor by dividing average radius by average value for that axis.
for (i=0;i<3;i++)
{
LM303_magnet_scaling[i] = Average_rad / Average[i];
}
// Store the final values in the chip
initLSM303_Offset();
cli();
eeprom_write_block((void*)&LM303_magnet_scaling, (void *) LSM303_MAG_GAIN, sizeof(LM303_magnet_scaling));
eeprom_write_block((void*)&LM303_magnet_offset, (void *) LSM303_MAG_OFFSET, sizeof(LM303_magnet_offset));
sei();
// Gain of the value
Serial_string_printf("\n\n\rCalibration is finished\n\n\r");
}
Init des Offset vom Chip direkt:
Code:
void initLSM303_Offset(void)
{
int8_t LowByte,HighByte;
LowByte = (int8_t) (LM303_magnet_offset[0] & 0xFF);
HighByte = (int8_t) (LM303_magnet_offset[0] >> 8);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_X_L_M, LowByte); // Store the new value of the X offset
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_X_H_M, HighByte);
LowByte = (int8_t) (LM303_magnet_offset[1] & 0xFF);
HighByte = (int8_t) (LM303_magnet_offset[1] >> 8);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Y_L_M, LowByte); // Store the new value of the Y offset
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Y_H_M, HighByte);
LowByte = (int8_t) (LM303_magnet_offset[2] & 0xFF);
HighByte = (int8_t) (LM303_magnet_offset[2] >> 8);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Z_L_M, LowByte); // Store the new value of the Z offset
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Z_H_M, HighByte);
}
gelesen wird dann hiermit
Code:
void read_LSM303(void)
{
int8_t i;
read_Array_LH_I2c(LM303_ADR,ADDR_READ_AUTOINCREMENT + ADDR_OUT_X_L_M,LM303_magnet_raw,sizeof(LM303_magnet_raw));
read_Array_LH_I2c(LM303_ADR,ADDR_READ_AUTOINCREMENT + ADDR_OUT_X_L_A,LM303_accel_raw,sizeof(LM303_accel_raw));
for(i=0;i<3;i++)
{
LM303_magnet[i] = (float)(LM303_magnet_raw[i]) * LM303_magnet_scaling[i] * LSM303D_M_GN_2MG_GAUSS;
LM303_accel[i] = LM303_accel_raw[i] * LSM303D_LA_SO_2G;
}
}
Wenn ich dann die grafische Kontrolle mache, sehe ich eigentlich, das es noch nicht sauber zentriert ist.

Wo ist mein Fehler ?
Ich kann die Werte auch direkt eingeben und komme aber nicht zu einem "sauberen" Kreis" in der Grafik.
In welcher Einheit arbeitet Ihr eigentlich für die einzelnen Sensoren ?
mg und mgauss oder in g und gauss
Viele Grüße
R.
Lesezeichen