reworking initial calibration and setting cal values from EEPROM

This commit is contained in:
tyler miller 2025-01-10 13:21:27 -05:00
parent 3a514fd381
commit 5a8a1500eb
3 changed files with 52 additions and 16 deletions

View file

@ -26,6 +26,7 @@ void writeCalibration(const JoystickCalibration &cal) {
void readNvm(NonVolatileMemory &nvm)
{
nvm.calData.validMarker = 0;
for (size_t ii = 0; ii < sizeof(NonVolatileMemory); ii++)
{
nvm.rawBytes[ii] = EEPROM.read(ii);

View file

@ -23,16 +23,36 @@ struct JoystickAxisCalibration
bool valid() const;
} __attribute__((packed));
/// calibration of min/max for single axis analog signals with no mid point
/// ie: a potentiometer
struct LinearAnalogCalibration {
uint16_t min;
uint16_t max;
inline bool valid() const { return min < max; }
} __attribute__((packed));
struct JoystickCalibration
{
JoystickAxisCalibration x;
JoystickAxisCalibration y;
} __attribute__((packed));
static constexpr uint32_t VALID_MARKER_DEFAULT = 0xcafecall;
union NonVolatileMemory
{
JoystickCalibration joystickCal;
uint8_t rawBytes[sizeof(JoystickCalibration)] = {};
struct Calibration {
/// place hard-coded start marker at the beginning of the data
/// to indicate validity
uint32_t validMarker = VALID_MARKER_DEFAULT;
JoystickCalibration joystickCal;
LinearAnalogCalibration linearCal;
} __attribute__((packed)) calData;
uint8_t rawBytes[NonVolatileMemory::Calibration] = {};
inline bool valid() const { return calData.validMarker == VALID_MARKER_DEFAULT; }
};
/// @brief Write the provided struct to EEPROM

View file

@ -11,9 +11,9 @@
AlignedJoy joystick_1(0, 1); /// X on A0, Y on A1
ArduinoLEDMatrix ledMatrix;
void runJoystickCalibrationRoutine(AlignedJoy &joy)
/// Run calibration on the provided joystick. Save the results to the provided calibration
bool runJoystickCalibrationRoutine(AlignedJoy &joy, JoystickCalibration &cal)
{
// JOYSTICK CALIBRATION
/*
* Start the joystick calibration in the center position. Use this method only if the calibration of the axles is desired (axesCalibration).
*/
@ -50,11 +50,12 @@ void runJoystickCalibrationRoutine(AlignedJoy &joy)
*/
if (joy.axesCalibration(TIME_CAL_2))
{
Serial.println("Calibration succesfully!!");
Serial.println("Calibration succesfull!!");
}
else
{
Serial.println("Calibration failed!!");
return false;
}
// Print all points calibrated
@ -79,15 +80,14 @@ void runJoystickCalibrationRoutine(AlignedJoy &joy)
Serial.print(" | max -> ");
Serial.println(joy.getCalibratedPoint(Y, MAX));
// save values to NVM
JoystickCalibration cal = {};
// save values to cal struct
cal.x.min = joy.getCalibratedPoint(X, MIN);
cal.x.mid = joy.getCalibratedPoint(X, MID);
cal.x.max = joy.getCalibratedPoint(X, MAX);
cal.y.min = joy.getCalibratedPoint(Y, MIN);
cal.y.mid = joy.getCalibratedPoint(Y, MID);
cal.y.max = joy.getCalibratedPoint(Y, MAX);
writeCalibration(cal);
return true;
}
void setup()
@ -102,17 +102,32 @@ void setup()
}
ledMatrix.play(true);
// retrieve joystic calibration values or run calibration and save results
// retrieve current calibration values
NonVolatileMemory nvm = {};
bool calibrationInvalid = true;
do {
readNvm(nvm);
calibrationInvalid = !nvm.joystickCal.x.valid() || !nvm.joystickCal.y.valid();
if (calibrationInvalid) {
runJoystickCalibrationRoutine(joystick_1);
}
readNvm(nvm);
// run joystick calibration if needed
bool calibrationInvalid = nvm.valid();
do {
calibrationInvalid |= !nvm.joystickCal.x.valid() || !nvm.joystickCal.y.valid();
if (calibrationInvalid) {
calibrationInvalid |= !runJoystickCalibrationRoutine(joystick_1, nvm.calData.joystickCal);
}
} while (calibrationInvalid);
// ensure calibration has been applied
// TODO: API doesnt allow setting configured midpoint...
joystick_1.setCalibratedPoint(axis_t::X, point_t::MIN, nvm.calData.joystickCal.x.min);
joystick_1.setCalibratedPoint(axis_t::X, point_t::MID, nvm.calData.joystickCal.x.mid);
joystick_1.setCalibratedPoint(axis_t::X, point_t::MAX, nvm.calData.joystickCal.x.max);
joystick_1.setCalibratedPoint(axis_t::Y, point_t::MIN, nvm.calData.joystickCal.y.min);
joystick_1.setCalibratedPoint(axis_t::Y, point_t::MID, nvm.calData.joystickCal.y.mid);
joystick_1.setCalibratedPoint(axis_t::Y, point_t::MAX, nvm.calData.joystickCal.y.max);
// run analog lever calibration if needed
// write NVM in the event any values were updated
writeNvm(nvm);
}
void loop()