add calibration routine for analog lever

This commit is contained in:
tyler miller 2025-01-14 15:27:59 -05:00
parent 4b0959ecaa
commit baf657a5f4
4 changed files with 84 additions and 2 deletions

View file

@ -43,7 +43,7 @@ union NonVolatileMemory {
struct Calibration { struct Calibration {
uint32_t validMarker = VALID_MARKER_DEFAULT; uint32_t validMarker = VALID_MARKER_DEFAULT;
JoystickCalibration joystickCal; JoystickCalibration joystickCal;
LinearAnalogCalibration linearCal; LinearAnalogCalibration lever0;
} __attribute__((packed)) calData; } __attribute__((packed)) calData;
uint8_t rawBytes[sizeof(NonVolatileMemory::Calibration)] = {}; uint8_t rawBytes[sizeof(NonVolatileMemory::Calibration)] = {};

View file

@ -0,0 +1,24 @@
/** \File SingleAxis.cpp
* \copyright (c) 2025 len0rd
* \date 2025-01-14
*/
#include "SingleAxis.hpp"
LinearSingleAxis::LinearSingleAxis(uint8_t analogPin)
: m_pin{analogPin},
m_cal{
.min = 0,
.max = 1 << 10,
} {}
uint16_t LinearSingleAxis::readRaw() {
return analogRead(m_pin);
}
uint8_t LinearSingleAxis::readPercent() {
return map(readRaw(), m_cal.min, m_cal.max, 0, 100);
}
void LinearSingleAxis::applyCalibration(const LinearAnalogCalibration& cal) {
m_cal = cal;
}

View file

@ -0,0 +1,31 @@
/** \File SingleAxis.hpp
* \copyright (c) 2025 len0rd
* \date 2025-01-14
*
* Simple utility class for reading a 'single axis' analog device. ie: a potentiometer
*/
#ifndef __SINGLEAXIS_H__
#define __SINGLEAXIS_H__
#include "Arduino.h"
#include "NvmEeprom.hpp"
class LinearSingleAxis {
public:
LinearSingleAxis(uint8_t analogPin);
uint16_t readRaw();
/// read as a percentage between calbirated min/max
/// Return a value 0-100
uint8_t readPercent();
/// Apply the provided calibration and use on subsequent @ref readPercent calls
void applyCalibration(const LinearAnalogCalibration& cal);
private:
uint8_t m_pin;
LinearAnalogCalibration m_cal;
};
#endif /* __SINGLEAXIS_H__ */

View file

@ -2,6 +2,7 @@
#include <Arduino.h> #include <Arduino.h>
#include "Arduino_LED_Matrix.h" #include "Arduino_LED_Matrix.h"
#include "NvmEeprom.hpp" #include "NvmEeprom.hpp"
#include "SingleAxis.hpp"
// joystick calibration // joystick calibration
#define TIME_CAL_1 2000 #define TIME_CAL_1 2000
@ -10,6 +11,7 @@
// static objects // static objects
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;
LinearSingleAxis lever0(2);
/// Run calibration on the provided joystick. Save the results to the provided calibration /// Run calibration on the provided joystick. Save the results to the provided calibration
bool runJoystickCalibrationRoutine(AlignedJoy& joy, JoystickCalibration& cal) { bool runJoystickCalibrationRoutine(AlignedJoy& joy, JoystickCalibration& cal) {
@ -95,6 +97,22 @@ bool runJoystickCalibrationRoutine(AlignedJoy& joy, JoystickCalibration& cal) {
return true; return true;
} }
bool runLeverCalibration(LinearSingleAxis& lever, LinearAnalogCalibration& cal) {
Serial.println(" Calibrate lever minimum. Move lever to the min position");
delay(2000);
Serial.println(" Capturing min now!");
cal.min = lever.readRaw();
delay(500);
Serial.println(" Calibrate lever maximum. Move lever to the max position");
delay(2000);
Serial.println(" Capturing max now!");
cal.max = lever.readRaw();
Serial.println(" Calibration succesfull!");
return true;
}
void setup() { void setup() {
// SERIAL INITIALIZE // SERIAL INITIALIZE
Serial.begin(115200); Serial.begin(115200);
@ -109,7 +127,7 @@ void setup() {
readNvm(nvm); readNvm(nvm);
// run joystick calibration if needed // run joystick calibration if needed
bool calibrationInvalid = nvm.valid(); bool calibrationInvalid = !nvm.valid();
do { do {
calibrationInvalid |= calibrationInvalid |=
!nvm.calData.joystickCal.x.valid() || !nvm.calData.joystickCal.y.valid(); !nvm.calData.joystickCal.x.valid() || !nvm.calData.joystickCal.y.valid();
@ -129,6 +147,15 @@ void setup() {
joystick_1.setCalibratedPoint(axis_t::Y, point_t::MAX, nvm.calData.joystickCal.y.max); joystick_1.setCalibratedPoint(axis_t::Y, point_t::MAX, nvm.calData.joystickCal.y.max);
// run analog lever calibration if needed // run analog lever calibration if needed
calibrationInvalid = !nvm.valid();
do {
calibrationInvalid |= !nvm.calData.lever0.valid();
if (calibrationInvalid) {
Serial.println("Lever0 calibration required\n===========================");
calibrationInvalid |= runLeverCalibration(lever0, nvm.calData.lever0);
}
} while (calibrationInvalid);
lever0.applyCalibration(nvm.calData.lever0);
// write NVM in the event any values were updated // write NVM in the event any values were updated
writeNvm(nvm); writeNvm(nvm);