From 5a8a1500eb613962ad45cfa25427961df9a3e63b Mon Sep 17 00:00:00 2001 From: tyler miller Date: Fri, 10 Jan 2025 13:21:27 -0500 Subject: [PATCH] reworking initial calibration and setting cal values from EEPROM --- lib/nvm/src/NvmEeprom.cpp | 1 + lib/nvm/src/NvmEeprom.hpp | 24 ++++++++++++++++++++-- src/main.cpp | 43 ++++++++++++++++++++++++++------------- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/lib/nvm/src/NvmEeprom.cpp b/lib/nvm/src/NvmEeprom.cpp index fccea2b..a769d1d 100644 --- a/lib/nvm/src/NvmEeprom.cpp +++ b/lib/nvm/src/NvmEeprom.cpp @@ -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); diff --git a/lib/nvm/src/NvmEeprom.hpp b/lib/nvm/src/NvmEeprom.hpp index 766f239..4a84cff 100644 --- a/lib/nvm/src/NvmEeprom.hpp +++ b/lib/nvm/src/NvmEeprom.hpp @@ -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 diff --git a/src/main.cpp b/src/main.cpp index 8ea892c..f6ff51f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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()