Open PaulStoffregen opened 8 years ago
Sorry, can't work on this right now. All my dev cycles are going into a USB Host library at the moment.
And I'm sure that will be a killing :)
I made a little patch. It's not well written at all be it does the job ...
So, in NXPmotionSense.h add this to public function :
void setAccelCal(float calA[3]) {
cal[0]=calA[0];
cal[1]=calA[1];
cal[2]=calA[2];
}
void setGyroCal(float calG[3]) {
cal[3]=calG[0];
cal[4]=calG[1];
cal[5]=calG[2];
}
And in your just declare arrays to store calibration datas :
float calGyro[3] = {-2,-0.7,-0.6};
float calAccel[3] = {0,0,0};
And use setGyroCal() and setAccelCal() AFTER begin() :
imu.begin();
imu.setAccelCal(calAccel);
imu.setGyroCal(calGyro);
Note :
@battosai30 did you have to change the way the app reads information as well?
Not at all. I made an inclinometer on IP (with PropShield + W5200 shield) and I just need to directly correct accel and gyro offsets
How did you dierectly connect this offsets I don't understand? On Sun, May 7, 2017 at 4:11 AM battosai30 notifications@github.com wrote:
Not at all. I made an inclinometer on IP (with PropShield + W5200 shield) and I just need to directly correct accel and gyro offsets
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/PaulStoffregen/MotionCal/issues/2#issuecomment-299692160, or mute the thread https://github.com/notifications/unsubscribe-auth/AItw9JFcis-bMMBg8Yxil2BWSbqGafEYks5r3YqngaJpZM4H-qft .
@battosai30 Does this work with the motion cal tool. To display the offsets afterwards. I am confused where can I get the calibration data from? Does it print out serially after using calibrating sensor program?
Yes you just have to use the raw example which print out value of each sensor. For gyro, just let it on your table with no movements and note values, the're offsets. It's useful to modify the code to output a mean value. For accel I think I did nothing, accel offsets are not as important as gyro's.
@battosai30 - Thanks for that! I was just looking at calibration.
Question: once I get the running average gyro values (eg. -9, 5, 2) are these the offset values or do I have to negate them (eg. 9, -5, -2) ?
You should get the offset value, as in library we find :
ax = (float)accel_mag_raw[0] * G_PER_COUNT - cal[0];
ay = (float)accel_mag_raw[1] * G_PER_COUNT - cal[1];
az = (float)accel_mag_raw[2] * G_PER_COUNT - cal[2];
gx = (float)gyro_raw[0] * DEG_PER_SEC_PER_COUNT - cal[3];
gy = (float)gyro_raw[1] * DEG_PER_SEC_PER_COUNT - cal[4];
gz = (float)gyro_raw[2] * DEG_PER_SEC_PER_COUNT - cal[5];
Ah, so obvious. Thanks for the tip, much appreciated!
I would've thought the offsets would be raw values but from that code I see they must be in g and deg/s respectively, so should be G_PER_COUNT and DEG_PER_SEC_PER_COUNT. Unless I'm missing something.
If you use readMotionSensor() values are already converted :
void readMotionSensor(float& ax, float& ay, float& az, float& gx, float& gy, float& gz) {
if (!newdata) update();
newdata = 0;
ax = (float)accel_mag_raw[0] * G_PER_COUNT;
ay = (float)accel_mag_raw[1] * G_PER_COUNT;
az = (float)accel_mag_raw[2] * G_PER_COUNT;
gx = (float)gyro_raw[0] * DEG_PER_SEC_PER_COUNT;
gy = (float)gyro_raw[1] * DEG_PER_SEC_PER_COUNT;
gz = (float)gyro_raw[2] * DEG_PER_SEC_PER_COUNT;
}
Ah, okay. I was using
void readMotionSensor(int& ax, int& ay, int& az, int& gx, int& gy, int& gz, int& mx, int& my, int& mz)
so was getting raw values like {-9, 5, 2}. To apply them to cal[3]..cal[5] I'd then have to convert them to deg/s. So to expand your code from above I did:
void setGyroCal(float calG[3]) {
cal[3]=calG[0] * DEG_PER_SEC_PER_COUNT;
cal[4]=calG[1] * DEG_PER_SEC_PER_COUNT;
cal[5]=calG[2] * DEG_PER_SEC_PER_COUNT;
}
I see now how I could just use the readMotionSensor(float& ax,...
version and obtain converted values. Subtle difference to be aware of when writing the cal routine!
For reference, here's how I wrote the cal offsets to EEPROM. I could've refined it to write only the gyro offsets but this worked for my purposes. The mag calibration must be run first as it clears both the gyro and accel offsets. I also added clearCal()
.
class NXPMotionSense {
public:
...
bool writeCal();
void clearCal() {
// from NXPMotionSense::begin()
memset(cal, 0, sizeof(cal));
cal[9] = 50.0f;
}
...
}
bool NXPMotionSense::writeCal()
{
uint8_t data[NXP_MOTION_CAL_SIZE];
// First two bytes are 117,84
data[0] = 117;
data[1] = 84;
// Copy the cal data
memcpy(data+2, cal, sizeof(cal));
// Calculate the crc value that will be stored in the last 2 bytes
uint16_t crc;
uint8_t i;
crc = 0xFFFF;
// Count all values up to but excluding the last 2 bytes
for (i=0; i<NXP_MOTION_CAL_SIZE-2; i++) {
crc = _crc16_update(crc, data[i]);
}
// Save the crc value in the last 2 bytes
memcpy(&data[i], &crc, 2);
return writeCalibration(data);
}
Looks like the gui display update in MotionCal is at these TODOs:
Hi,
No update about this point ? Is there any other method to easily calibrate acc and gyro ?