-
Notifications
You must be signed in to change notification settings - Fork 136
Open
Description
I asked AI to merge calibrate.ino and and heading.ino into one single skecth wchich at first start performs calibration and saves data in EEPROM, and from second start begins printing calibrated values.
Calibration lasts 10 seconds, you must rotate the sensor 360° about all its axes during this time.
Not tested yet.
#include <Wire.h>
#include <LSM303.h>
#include <EEPROM.h>
LSM303 compass;
LSM303::vector<int16_t> running_min = {32767, 32767, 32767}, running_max = {-32768, -32768, -32768};
char report[80];
// Structure to save calibration values in EEPROM
struct CalibrationData {
int16_t min_x;
int16_t min_y;
int16_t min_z;
int16_t max_x;
int16_t max_y;
int16_t max_z;
uint8_t calibrated; // Flag to verify if calibration has been performed
};
void setup() {
Serial.begin(9600);
Wire.begin();
compass.init();
compass.enableDefault();
// Read calibration data from EEPROM
CalibrationData calibData;
EEPROM.get(0, calibData);
// Check if calibration has already been performed
if (calibData.calibrated == 0xAA) {
// Use saved calibration values
compass.m_min = (LSM303::vector<int16_t>){
calibData.min_x,
calibData.min_y,
calibData.min_z
};
compass.m_max = (LSM303::vector<int16_t>){
calibData.max_x,
calibData.max_y,
calibData.max_z
};
Serial.println("Calibration loaded from EEPROM");
} else {
// Calibration mode
Serial.println("Starting calibration. Rotate the sensor in all directions.");
}
}
void loop() {
// Read calibration data from EEPROM
CalibrationData calibData;
EEPROM.get(0, calibData);
if (calibData.calibrated != 0xAA) {
// Calibration mode
compass.read();
running_min.x = min(running_min.x, compass.m.x);
running_min.y = min(running_min.y, compass.m.y);
running_min.z = min(running_min.z, compass.m.z);
running_max.x = max(running_max.x, compass.m.x);
running_max.y = max(running_max.y, compass.m.y);
running_max.z = max(running_max.z, compass.m.z);
snprintf(report, sizeof(report), "min: {%+6d, %+6d, %+6d} max: {%+6d, %+6d, %+6d}",
running_min.x, running_min.y, running_min.z,
running_max.x, running_max.y, running_max.z);
Serial.println(report);
// Wait a bit for calibration
delay(100);
// Check if we have collected sufficient data (optional)
if (millis() > 30000) { // 30 seconds of calibration
// Save calibration values to EEPROM
calibData.min_x = running_min.x;
calibData.min_y = running_min.y;
calibData.min_z = running_min.z;
calibData.max_x = running_max.x;
calibData.max_y = running_max.y;
calibData.max_z = running_max.z;
calibData.calibrated = 0xAA; // Mark as calibrated
EEPROM.put(0, calibData);
Serial.println("Calibration completed and saved!");
// Restart to switch to reading mode
delay(2000);
setup();
}
} else {
// Reading mode
compass.read();
float heading = compass.heading();
Serial.print("Heading: ");
Serial.println(heading);
delay(100);
}
}
Metadata
Metadata
Assignees
Labels
No labels