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) void readNvm(NonVolatileMemory &nvm)
{ {
nvm.calData.validMarker = 0;
for (size_t ii = 0; ii < sizeof(NonVolatileMemory); ii++) for (size_t ii = 0; ii < sizeof(NonVolatileMemory); ii++)
{ {
nvm.rawBytes[ii] = EEPROM.read(ii); nvm.rawBytes[ii] = EEPROM.read(ii);

View file

@ -23,16 +23,36 @@ struct JoystickAxisCalibration
bool valid() const; bool valid() const;
} __attribute__((packed)); } __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 struct JoystickCalibration
{ {
JoystickAxisCalibration x; JoystickAxisCalibration x;
JoystickAxisCalibration y; JoystickAxisCalibration y;
} __attribute__((packed)); } __attribute__((packed));
static constexpr uint32_t VALID_MARKER_DEFAULT = 0xcafecall;
union NonVolatileMemory union NonVolatileMemory
{ {
struct Calibration {
/// place hard-coded start marker at the beginning of the data
/// to indicate validity
uint32_t validMarker = VALID_MARKER_DEFAULT;
JoystickCalibration joystickCal; JoystickCalibration joystickCal;
uint8_t rawBytes[sizeof(JoystickCalibration)] = {}; 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 /// @brief Write the provided struct to EEPROM

View file

@ -11,9 +11,9 @@
AlignedJoy joystick_1(0, 1); /// X on A0, Y on A1 AlignedJoy joystick_1(0, 1); /// X on A0, Y on A1
ArduinoLEDMatrix ledMatrix; 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). * 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)) if (joy.axesCalibration(TIME_CAL_2))
{ {
Serial.println("Calibration succesfully!!"); Serial.println("Calibration succesfull!!");
} }
else else
{ {
Serial.println("Calibration failed!!"); Serial.println("Calibration failed!!");
return false;
} }
// Print all points calibrated // Print all points calibrated
@ -79,15 +80,14 @@ void runJoystickCalibrationRoutine(AlignedJoy &joy)
Serial.print(" | max -> "); Serial.print(" | max -> ");
Serial.println(joy.getCalibratedPoint(Y, MAX)); Serial.println(joy.getCalibratedPoint(Y, MAX));
// save values to NVM // save values to cal struct
JoystickCalibration cal = {};
cal.x.min = joy.getCalibratedPoint(X, MIN); cal.x.min = joy.getCalibratedPoint(X, MIN);
cal.x.mid = joy.getCalibratedPoint(X, MID); cal.x.mid = joy.getCalibratedPoint(X, MID);
cal.x.max = joy.getCalibratedPoint(X, MAX); cal.x.max = joy.getCalibratedPoint(X, MAX);
cal.y.min = joy.getCalibratedPoint(Y, MIN); cal.y.min = joy.getCalibratedPoint(Y, MIN);
cal.y.mid = joy.getCalibratedPoint(Y, MID); cal.y.mid = joy.getCalibratedPoint(Y, MID);
cal.y.max = joy.getCalibratedPoint(Y, MAX); cal.y.max = joy.getCalibratedPoint(Y, MAX);
writeCalibration(cal); return true;
} }
void setup() void setup()
@ -102,17 +102,32 @@ void setup()
} }
ledMatrix.play(true); ledMatrix.play(true);
// retrieve joystic calibration values or run calibration and save results // retrieve current calibration values
NonVolatileMemory nvm = {}; NonVolatileMemory nvm = {};
bool calibrationInvalid = true;
do {
readNvm(nvm); readNvm(nvm);
calibrationInvalid = !nvm.joystickCal.x.valid() || !nvm.joystickCal.y.valid();
if (calibrationInvalid) {
runJoystickCalibrationRoutine(joystick_1);
}
// 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); } 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() void loop()