Ralph Trimnell
Member
I have tried 2 versions of the windows calibrate utility. Supposedly continued data gathering will reduce errors and turn the graphic into a perfect? sphere but the opposite is happening and the save calibration button in inactive. The raw serial data looks as it should. What could be wrong? Here is the CalibrateSensors code-----Thanks for anyl help, Ralph.
#include <NXPMotionSense.h>
#include <Wire.h>
#include <EEPROM.h>
#include <util/crc16.h>
NXPMotionSense imu;
const int ledPin = 13;
int ledState = LOW;
int ledFastblinks = 0;
elapsedMillis ledMillis = 0;
int loopcount = 0;
void receiveCalibration();
void setup() {
Serial.begin(115200);
while (!Serial) ; // wait for serial port open
imu.begin();
pinMode(ledPin, OUTPUT);
}
void loop() {
int ax, ay, az;
int gx, gy, gz;
int mx, my, mz;
// get and print uncalibrated data
if (imu.available()) {
imu.readMotionSensor(ax, ay, az, gx, gy, gz, mx, my, mz);
Serial.print("Raw:");
Serial.print(ax);
Serial.print(',');
Serial.print(ay);
Serial.print(',');
Serial.print(az);
Serial.print(',');
Serial.print(gx);
Serial.print(',');
Serial.print(gy);
Serial.print(',');
Serial.print(gz);
Serial.print(',');
Serial.print(mx);
Serial.print(',');
Serial.print(my);
Serial.print(',');
Serial.print(mz);
Serial.println();
loopcount = loopcount + 1;
}
// check for incoming calibration
receiveCalibration();
// occasionally print calibration
if (loopcount == 50 || loopcount > 100) {
Serial.print("Cal1:");
float caloffsets[9], calmag;
imu.getCalibration(caloffsets, NULL, &calmag);
for (int i=0; i<9; i++) {
Serial.print(caloffsets, 3);
Serial.print(',');
}
Serial.println(calmag, 3);
loopcount = loopcount + 1;
}
if (loopcount >= 100) {
Serial.print("Cal2:");
float calsoftiron[9];
imu.getCalibration(NULL, calsoftiron, NULL);
for (int i=0; i<9; i++) {
Serial.print(calsoftiron, 4);
if (i < 8) Serial.print(',');
}
Serial.println();
loopcount = 0;
}
// blink LED, slow normally, fast when calibration written
if (ledMillis >= 1000) {
if (ledFastblinks > 0) {
ledFastblinks = ledFastblinks - 1;
ledMillis -= 125;
} else {
ledMillis -= 1000;
}
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
byte caldata[68]; // buffer to receive magnetic calibration data
byte calcount=0;
void receiveCalibration() {
uint16_t crc;
byte b, i;
if (Serial.available()) {
b = Serial.read();
if (calcount == 0 && b != 117) {
// first byte must be 117
return;
}
if (calcount == 1 && b != 84) {
// second byte must be 84
calcount = 0;
return;
}
// store this byte
caldata[calcount++] = b;
if (calcount < 68) {
// full calibration message is 68 bytes
return;
}
// verify the crc16 check
crc = 0xFFFF;
for (i=0; i < 68; i++) {
crc = _crc16_update(crc, caldata);
}
if (crc == 0) {
// data looks good, use it
imu.writeCalibration(caldata);
calcount = 0;
loopcount = 10000;
ledFastblinks = 16; // Toggle LED faster the next 16 times
return;
}
// look for the 117,84 in the data, before discarding
for (i=2; i < 67; i++) {
if (caldata == 117 && caldata[i+1] == 84) {
// found possible start within data
calcount = 68 - i;
memmove(caldata, caldata + i, calcount);
return;
}
}
// look for 117 in last byte
if (caldata[67] == 117) {
caldata[0] = 117;
calcount = 1;
} else {
calcount = 0;
}
}
}
raw readings: arbitrary sample
Raw:-368,-7588,4484,-18,-10,0,-896,1051,1150
Raw:-352,-7600,4472,-15,-9,2,-894,1043,1156
Raw:-356,-7596,4460,-17,-9,-3,-886,1046,1166
Raw:-352,-7600,4464,-9,-11,-2,-888,1041,1151
Raw:-216,-4876,7328,-22,-9,4,367,26,-71
Raw:-228,-4900,7312,-13,-9,0,360,14,-71
Raw:-220,-4892,7324,-11,-8,1,360,16,-79
Raw:-228,-4884,7332,-7,-7,0,365,26,-58
Raw:-204,-4896,7316,-10,-7,1,383,-1,-89
Raw:-228,-4888,7304,-16,-8,4,365,18,-81
Raw:-212,-4896,7300,-19,-8,3,370,21,-87
Raw:-224,-4888,7308,-11,-9,2,372,4,-49
Cal1:0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,50.000
Raw:-212,-4904,7316,-10,-10,3,373,-4,-63
Raw:-228,-4864,7312,-14,-7,4,382,21,-75
Raw:-236,-4884,7332,-13,-10,4,361,18,-79
Raw:-208,-4872,7320,-5,-8,4,361,21,-82
Raw:-212,-4880,7332,-19,-9,1,375,20,-72
Raw:-216,-4888,7312,-11,-9,2,364,32,-73
Raw:-224,-4876,7328,-14,-8,4,351,19,-64
Raw:-232,-4872,7292,-14,-8,-3,368,17,-83
Raw:-228,-4900,7320,-16,-10,1,383,13,-65
Raw:-204,-4872,7320,-9,-12,2,354,25,-72
Raw:-232,-4888,7336,-10,-9,5,358,25,-67
Raw:-216,-4880,7312,-15,-5,4,364,13,-70
Raw:-216,-4888,7328,-18,-9,2,373,10,-71
Raw:-220,-4896,7316,-18,-10,3,363,35,-73
Raw:-228,-4896,7304,-10,-7,5,374,8,-59
Raw:-228,-4892,7356,-9,-9,1,365,8,-68
Raw:-216,-4868,7336,-11,-7,3,343,24,-57
Raw:-228,-4884,7328,-13,-9,4,360,17,-79
Raw:-212,-4896,7316,-17,-9,1,365,17,-60
Raw:-208,-4896,7324,-14,-7,1,370,15,-84
Raw:-212,-4884,7316,-8,-11,0,371,22,-77
Raw:-220,-4888,7324,-11,-10,0,374,8,-80
#include <NXPMotionSense.h>
#include <Wire.h>
#include <EEPROM.h>
#include <util/crc16.h>
NXPMotionSense imu;
const int ledPin = 13;
int ledState = LOW;
int ledFastblinks = 0;
elapsedMillis ledMillis = 0;
int loopcount = 0;
void receiveCalibration();
void setup() {
Serial.begin(115200);
while (!Serial) ; // wait for serial port open
imu.begin();
pinMode(ledPin, OUTPUT);
}
void loop() {
int ax, ay, az;
int gx, gy, gz;
int mx, my, mz;
// get and print uncalibrated data
if (imu.available()) {
imu.readMotionSensor(ax, ay, az, gx, gy, gz, mx, my, mz);
Serial.print("Raw:");
Serial.print(ax);
Serial.print(',');
Serial.print(ay);
Serial.print(',');
Serial.print(az);
Serial.print(',');
Serial.print(gx);
Serial.print(',');
Serial.print(gy);
Serial.print(',');
Serial.print(gz);
Serial.print(',');
Serial.print(mx);
Serial.print(',');
Serial.print(my);
Serial.print(',');
Serial.print(mz);
Serial.println();
loopcount = loopcount + 1;
}
// check for incoming calibration
receiveCalibration();
// occasionally print calibration
if (loopcount == 50 || loopcount > 100) {
Serial.print("Cal1:");
float caloffsets[9], calmag;
imu.getCalibration(caloffsets, NULL, &calmag);
for (int i=0; i<9; i++) {
Serial.print(caloffsets, 3);
Serial.print(',');
}
Serial.println(calmag, 3);
loopcount = loopcount + 1;
}
if (loopcount >= 100) {
Serial.print("Cal2:");
float calsoftiron[9];
imu.getCalibration(NULL, calsoftiron, NULL);
for (int i=0; i<9; i++) {
Serial.print(calsoftiron, 4);
if (i < 8) Serial.print(',');
}
Serial.println();
loopcount = 0;
}
// blink LED, slow normally, fast when calibration written
if (ledMillis >= 1000) {
if (ledFastblinks > 0) {
ledFastblinks = ledFastblinks - 1;
ledMillis -= 125;
} else {
ledMillis -= 1000;
}
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
byte caldata[68]; // buffer to receive magnetic calibration data
byte calcount=0;
void receiveCalibration() {
uint16_t crc;
byte b, i;
if (Serial.available()) {
b = Serial.read();
if (calcount == 0 && b != 117) {
// first byte must be 117
return;
}
if (calcount == 1 && b != 84) {
// second byte must be 84
calcount = 0;
return;
}
// store this byte
caldata[calcount++] = b;
if (calcount < 68) {
// full calibration message is 68 bytes
return;
}
// verify the crc16 check
crc = 0xFFFF;
for (i=0; i < 68; i++) {
crc = _crc16_update(crc, caldata);
}
if (crc == 0) {
// data looks good, use it
imu.writeCalibration(caldata);
calcount = 0;
loopcount = 10000;
ledFastblinks = 16; // Toggle LED faster the next 16 times
return;
}
// look for the 117,84 in the data, before discarding
for (i=2; i < 67; i++) {
if (caldata == 117 && caldata[i+1] == 84) {
// found possible start within data
calcount = 68 - i;
memmove(caldata, caldata + i, calcount);
return;
}
}
// look for 117 in last byte
if (caldata[67] == 117) {
caldata[0] = 117;
calcount = 1;
} else {
calcount = 0;
}
}
}
raw readings: arbitrary sample
Raw:-368,-7588,4484,-18,-10,0,-896,1051,1150
Raw:-352,-7600,4472,-15,-9,2,-894,1043,1156
Raw:-356,-7596,4460,-17,-9,-3,-886,1046,1166
Raw:-352,-7600,4464,-9,-11,-2,-888,1041,1151
Raw:-216,-4876,7328,-22,-9,4,367,26,-71
Raw:-228,-4900,7312,-13,-9,0,360,14,-71
Raw:-220,-4892,7324,-11,-8,1,360,16,-79
Raw:-228,-4884,7332,-7,-7,0,365,26,-58
Raw:-204,-4896,7316,-10,-7,1,383,-1,-89
Raw:-228,-4888,7304,-16,-8,4,365,18,-81
Raw:-212,-4896,7300,-19,-8,3,370,21,-87
Raw:-224,-4888,7308,-11,-9,2,372,4,-49
Cal1:0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,50.000
Raw:-212,-4904,7316,-10,-10,3,373,-4,-63
Raw:-228,-4864,7312,-14,-7,4,382,21,-75
Raw:-236,-4884,7332,-13,-10,4,361,18,-79
Raw:-208,-4872,7320,-5,-8,4,361,21,-82
Raw:-212,-4880,7332,-19,-9,1,375,20,-72
Raw:-216,-4888,7312,-11,-9,2,364,32,-73
Raw:-224,-4876,7328,-14,-8,4,351,19,-64
Raw:-232,-4872,7292,-14,-8,-3,368,17,-83
Raw:-228,-4900,7320,-16,-10,1,383,13,-65
Raw:-204,-4872,7320,-9,-12,2,354,25,-72
Raw:-232,-4888,7336,-10,-9,5,358,25,-67
Raw:-216,-4880,7312,-15,-5,4,364,13,-70
Raw:-216,-4888,7328,-18,-9,2,373,10,-71
Raw:-220,-4896,7316,-18,-10,3,363,35,-73
Raw:-228,-4896,7304,-10,-7,5,374,8,-59
Raw:-228,-4892,7356,-9,-9,1,365,8,-68
Raw:-216,-4868,7336,-11,-7,3,343,24,-57
Raw:-228,-4884,7328,-13,-9,4,360,17,-79
Raw:-212,-4896,7316,-17,-9,1,365,17,-60
Raw:-208,-4896,7324,-14,-7,1,370,15,-84
Raw:-212,-4884,7316,-8,-11,0,371,22,-77
Raw:-220,-4888,7324,-11,-10,0,374,8,-80
Last edited: