diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..1eedbc0 --- /dev/null +++ b/.clang-format @@ -0,0 +1,10 @@ +BasedOnStyle: Chromium +IndentWidth: 4 +Language: Cpp +ColumnLimit: 100 +UseTab: Never +BreakBeforeBraces: Custom +FixNamespaceComments: true +ShortNamespaceLines: 0 +BraceWrapping: + BeforeElse: true diff --git a/lib/joystick/src/AlignedJoy.cpp b/lib/joystick/src/AlignedJoy.cpp index dacbda7..da06e62 100644 --- a/lib/joystick/src/AlignedJoy.cpp +++ b/lib/joystick/src/AlignedJoy.cpp @@ -1,5 +1,5 @@ /********************************************************************************************************** - + @file AlignedJoy.cpp @brief Joystick calibrated class @author Marco Palladino @@ -10,16 +10,16 @@ @details AlignedJoy is a class written in C++ for Arduino to interface classic analog joysticks. - Reading the analog values of a joystick with Arduino is very simple, so what is the purpose of this class? - Through the methods of the class you can calibrate one or more joysticks, read and memorize the calibration points. - For dynamic applications, calibrated points can be stored in eeprom. Or once the calibration points are obtained, - they can be set in constant mode. See description of methods. - The strength of the class is that having the calibration parameters is able to align the values of the axes - of the respective joysticks. It’s very useful when you want to manage something with a certain precision and - when you have a joystick with misaligned axis values. + Reading the analog values of a joystick with Arduino is very simple, so what is the purpose of +this class? Through the methods of the class you can calibrate one or more joysticks, read and +memorize the calibration points. For dynamic applications, calibrated points can be stored in +eeprom. Or once the calibration points are obtained, they can be set in constant mode. See +description of methods. The strength of the class is that having the calibration parameters is able +to align the values of the axes of the respective joysticks. It’s very useful when you want to +manage something with a certain precision and when you have a joystick with misaligned axis values. # LICENSE # - + MIT License Copyright (c) 2020 Marco Palladino @@ -45,232 +45,203 @@ #include "AlignedJoy.h" -AlignedJoy::AlignedJoy(uint8_t xPin, uint8_t yPin) -{ - this->xPin = xPin; - this->yPin = yPin; - this->joystickCentered = false; - this->joystickFullCalibrated = false; - - pinMode(this->xPin,INPUT); - pinMode(this->yPin,INPUT); +AlignedJoy::AlignedJoy(uint8_t xPin, uint8_t yPin) { + this->xPin = xPin; + this->yPin = yPin; + this->joystickCentered = false; + this->joystickFullCalibrated = false; + + pinMode(this->xPin, INPUT); + pinMode(this->yPin, INPUT); }; -void AlignedJoy::axesAlign(void) -{ - // Imposed the smallest value between the two calibrated minima. - this->alignMin = min(this->xAxisCalibMinimum, this->yAxisCalibMinimum); - // Imposed the largest value between the two calibrated maxima. - this->alignMax = max(this->xAxisCalibMaximum, this->yAxisCalibMaximum); +void AlignedJoy::axesAlign(void) { + // Imposed the smallest value between the two calibrated minima. + this->alignMin = min(this->xAxisCalibMinimum, this->yAxisCalibMinimum); + // Imposed the largest value between the two calibrated maxima. + this->alignMax = max(this->xAxisCalibMaximum, this->yAxisCalibMaximum); } -void AlignedJoy::middleCalibration(uint16_t timeOfCal) -{ - // New istance of the timer - calibrationTimer TIME_CAL_1; - - // Repeat for the required time - while(TIME_CAL_1 < timeOfCal) - { - // Assigns the value to each loop. - this->xAxisCalibCenter = analogRead(this->xPin); - this->yAxisCalibCenter = analogRead(this->yPin); - } - // set flag true - this->joystickCentered = true; -} - -bool AlignedJoy::axesCalibration(uint16_t timeOfCal) -{ - if(joystickCentered) - { - // New values for comparison - static uint16_t last_X_min = this->xAxisCalibCenter; - static uint16_t last_X_max = this->xAxisCalibCenter; - static uint16_t last_Y_min = this->yAxisCalibCenter; - static uint16_t last_Y_max = this->yAxisCalibCenter; - +void AlignedJoy::middleCalibration(uint16_t timeOfCal) { // New istance of the timer - calibrationTimer TIME_CAL_2; + calibrationTimer TIME_CAL_1; // Repeat for the required time - while(TIME_CAL_2 < timeOfCal) - { - // Read analog value - uint16_t x = analogRead(this->xPin); - uint16_t y = analogRead(this->yPin); - - // Logic acquisition. Assigns the lowest or highest values to each loop. - if(x < this->xAxisCalibCenter && x < last_X_min) - { - last_X_min = this->xAxisCalibMinimum = x; - } - if(x > this->xAxisCalibCenter && x > last_X_max) - { - last_X_max = this->xAxisCalibMaximum = x; - } - if(y < this->yAxisCalibCenter && y < last_Y_min) - { - last_Y_min = this->yAxisCalibMinimum = y; - } - if(y > this->yAxisCalibCenter && y > last_Y_max) - { - last_Y_max = this->yAxisCalibMaximum = y; - } + while (TIME_CAL_1 < timeOfCal) { + // Assigns the value to each loop. + this->xAxisCalibCenter = analogRead(this->xPin); + this->yAxisCalibCenter = analogRead(this->yPin); } - - // verify that there is the minimum excursion between the minimum and the maximum of each axis. - if((this->xAxisCalibMaximum - this->xAxisCalibMinimum) >= AXIS_TRAVEL && - (this->yAxisCalibMaximum - this->yAxisCalibMinimum) >= AXIS_TRAVEL) - { - // set flag true - this->joystickFullCalibrated = true; - - // align axes - axesAlign(); - - return true; - } - else - { - return false; - } - } - else - { - return false; - } + // set flag true + this->joystickCentered = true; } -void AlignedJoy::setCalibratedPoint(axis_t axis, point_t point, uint16_t pointValue) -{ - switch(point) - { - case MIN: - switch(axis) - { - case X: - this->xAxisCalibMinimum = pointValue; - break; - case Y: - this->yAxisCalibMinimum = pointValue; - break; - } - break; +bool AlignedJoy::axesCalibration(uint16_t timeOfCal) { + if (joystickCentered) { + // New values for comparison + static uint16_t last_X_min = this->xAxisCalibCenter; + static uint16_t last_X_max = this->xAxisCalibCenter; + static uint16_t last_Y_min = this->yAxisCalibCenter; + static uint16_t last_Y_max = this->yAxisCalibCenter; - case MID: - switch(axis) - { - case X: - this->xAxisCalibCenter = pointValue; - break; - case Y: - this->yAxisCalibCenter = pointValue; - break; - } - break; + // New istance of the timer + calibrationTimer TIME_CAL_2; - case MAX: - switch(axis) - { - case X: - this->xAxisCalibMaximum = pointValue; - break; - case Y: - this->yAxisCalibMaximum = pointValue; - break; + // Repeat for the required time + while (TIME_CAL_2 < timeOfCal) { + // Read analog value + uint16_t x = analogRead(this->xPin); + uint16_t y = analogRead(this->yPin); + + // Logic acquisition. Assigns the lowest or highest values to each loop. + if (x < this->xAxisCalibCenter && x < last_X_min) { + last_X_min = this->xAxisCalibMinimum = x; + } + if (x > this->xAxisCalibCenter && x > last_X_max) { + last_X_max = this->xAxisCalibMaximum = x; + } + if (y < this->yAxisCalibCenter && y < last_Y_min) { + last_Y_min = this->yAxisCalibMinimum = y; + } + if (y > this->yAxisCalibCenter && y > last_Y_max) { + last_Y_max = this->yAxisCalibMaximum = y; + } + } + + // verify that there is the minimum excursion between the minimum and the maximum of each + // axis. + if ((this->xAxisCalibMaximum - this->xAxisCalibMinimum) >= AXIS_TRAVEL && + (this->yAxisCalibMaximum - this->yAxisCalibMinimum) >= AXIS_TRAVEL) { + // set flag true + this->joystickFullCalibrated = true; + + // align axes + axesAlign(); + + return true; + } + else { + return false; } - break; } - // verify that there is the minimum excursion between the minimum and the maximum of each axis. - if((this->xAxisCalibMaximum - this->xAxisCalibMinimum) >= AXIS_TRAVEL && - (this->yAxisCalibMaximum - this->yAxisCalibMinimum) >= AXIS_TRAVEL) - { + else { + return false; + } +} + +void AlignedJoy::setCalibratedPoint(axis_t axis, point_t point, uint16_t pointValue) { + switch (point) { + case MIN: + switch (axis) { + case X: + this->xAxisCalibMinimum = pointValue; + break; + case Y: + this->yAxisCalibMinimum = pointValue; + break; + } + break; + + case MID: + switch (axis) { + case X: + this->xAxisCalibCenter = pointValue; + break; + case Y: + this->yAxisCalibCenter = pointValue; + break; + } + break; + + case MAX: + switch (axis) { + case X: + this->xAxisCalibMaximum = pointValue; + break; + case Y: + this->yAxisCalibMaximum = pointValue; + break; + } + break; + } + // verify that there is the minimum excursion between the minimum and the maximum of each axis. + if ((this->xAxisCalibMaximum - this->xAxisCalibMinimum) >= AXIS_TRAVEL && + (this->yAxisCalibMaximum - this->yAxisCalibMinimum) >= AXIS_TRAVEL) { // set flag true this->joystickFullCalibrated = true; // align axes axesAlign(); - } -} - -uint16_t AlignedJoy::getCalibratedPoint(axis_t axis, point_t point) -{ - uint16_t pointValue; - - switch(point) - { - case MIN: - switch(axis) - { - case X: - pointValue = this->xAxisCalibMinimum; - break; - case Y: - pointValue = this->yAxisCalibMinimum; - break; - } - break; - - case MID: - switch(axis) - { - case X: - pointValue = this->xAxisCalibCenter; - break; - case Y: - pointValue = this->yAxisCalibCenter; - break; - } - break; - - case MAX: - switch(axis) - { - case X: - pointValue = this->xAxisCalibMaximum; - break; - case Y: - pointValue = this->yAxisCalibMaximum; - break; - } - break; } - return pointValue; } -uint16_t AlignedJoy::read(axis_t axis) -{ - uint16_t axisValue; +uint16_t AlignedJoy::getCalibratedPoint(axis_t axis, point_t point) { + uint16_t pointValue; - switch(axis) - { - case X: - if(joystickFullCalibrated) - { - axisValue = map(analogRead(this->xPin), this->xAxisCalibMinimum, this->xAxisCalibMaximum, this->alignMin, this->alignMax); - } - else - { - axisValue = analogRead(this->xPin); - } - break; + switch (point) { + case MIN: + switch (axis) { + case X: + pointValue = this->xAxisCalibMinimum; + break; + case Y: + pointValue = this->yAxisCalibMinimum; + break; + } + break; - case Y: - if(joystickFullCalibrated) - { - axisValue = map(analogRead(this->yPin), this->yAxisCalibMinimum, this->yAxisCalibMaximum, this->alignMin, this->alignMax); - } - else - { - axisValue = analogRead(this->yPin); - } - break; + case MID: + switch (axis) { + case X: + pointValue = this->xAxisCalibCenter; + break; + case Y: + pointValue = this->yAxisCalibCenter; + break; + } + break; + + case MAX: + switch (axis) { + case X: + pointValue = this->xAxisCalibMaximum; + break; + case Y: + pointValue = this->yAxisCalibMaximum; + break; + } + break; } - return axisValue; + return pointValue; } -uint16_t AlignedJoy::read(axis_t axis, int32_t out_min, int32_t out_max) -{ - return map(read(axis), this->alignMin, this->alignMax, out_min, out_max); +uint16_t AlignedJoy::read(axis_t axis) { + uint16_t axisValue; + + switch (axis) { + case X: + if (joystickFullCalibrated) { + axisValue = map(analogRead(this->xPin), this->xAxisCalibMinimum, + this->xAxisCalibMaximum, this->alignMin, this->alignMax); + } + else { + axisValue = analogRead(this->xPin); + } + break; + + case Y: + if (joystickFullCalibrated) { + axisValue = map(analogRead(this->yPin), this->yAxisCalibMinimum, + this->yAxisCalibMaximum, this->alignMin, this->alignMax); + } + else { + axisValue = analogRead(this->yPin); + } + break; + } + return axisValue; +} + +uint16_t AlignedJoy::read(axis_t axis, int32_t out_min, int32_t out_max) { + return map(read(axis), this->alignMin, this->alignMax, out_min, out_max); } diff --git a/lib/joystick/src/AlignedJoy.h b/lib/joystick/src/AlignedJoy.h index 7082539..5c35730 100644 --- a/lib/joystick/src/AlignedJoy.h +++ b/lib/joystick/src/AlignedJoy.h @@ -1,5 +1,5 @@ /********************************************************************************************************** - + @file AlignedJoy.h @brief Joystick calibrated class @author Marco Palladino @@ -10,16 +10,16 @@ @details AlignedJoy is a class written in C++ for Arduino to interface classic analog joysticks. - Reading the analog values of a joystick with Arduino is very simple, so what is the purpose of this class? - Through the methods of the class you can calibrate one or more joysticks, read and memorize the calibration points. - For dynamic applications, calibrated points can be stored in eeprom. Or once the calibration points are obtained, - they can be set in constant mode. See description of methods. - The strength of the class is that having the calibration parameters is able to align the values of the axes - of the respective joysticks. It’s very useful when you want to manage something with a certain precision and - when you have a joystick with misaligned axis values. + Reading the analog values of a joystick with Arduino is very simple, so what is the purpose of +this class? Through the methods of the class you can calibrate one or more joysticks, read and +memorize the calibration points. For dynamic applications, calibrated points can be stored in +eeprom. Or once the calibration points are obtained, they can be set in constant mode. See +description of methods. The strength of the class is that having the calibration parameters is able +to align the values of the axes of the respective joysticks. It’s very useful when you want to +manage something with a certain precision and when you have a joystick with misaligned axis values. # LICENSE # - + MIT License Copyright (c) 2020 Marco Palladino @@ -61,127 +61,131 @@ AXIS_TRAVEL CONSTANT #define AXIS_TRAVEL 550 /// @brief axes flags -typedef enum axis:uint8_t {X=0, Y} axis_t; +typedef enum axis : uint8_t { X = 0, Y } axis_t; /// @brief calibration point flags -typedef enum point:uint8_t{ - /// minimum point - MIN=0, - /// middle point - MID, - /// maximum point - MAX - } point_t; +typedef enum point : uint8_t { + /// minimum point + MIN = 0, + /// middle point + MID, + /// maximum point + MAX +} point_t; -class AlignedJoy -{ - public: - - /** - @brief Class onstructor. Create a new object of the joystick and set the axes (X/Y) pin to input mode - @param xPin (x analog port pin of the device) - @param yPin (y analog port pin of the device) - */ - AlignedJoy(uint8_t xPin, uint8_t yPin); - /// Class destructor - ~AlignedJoy(){}; +class AlignedJoy { + public: + /** + @brief Class onstructor. Create a new object of the joystick and set the axes (X/Y) pin to input + mode + @param xPin (x analog port pin of the device) + @param yPin (y analog port pin of the device) + */ + AlignedJoy(uint8_t xPin, uint8_t yPin); + /// Class destructor + ~AlignedJoy() {}; - /** - @brief Start calibration of the joystick in center position. - @details - Use this method only if the calibration of the axles is desired. - Calibration is divided into two steps to allow defining the desired functionality - (messages, delays, etc.) between the two phases. - @param timeOfCal is the calibration time in milliseconds. - @return true o false. - */ - void middleCalibration(uint16_t timeOfCal); + /** + @brief Start calibration of the joystick in center position. + @details + Use this method only if the calibration of the axles is desired. + Calibration is divided into two steps to allow defining the desired functionality + (messages, delays, etc.) between the two phases. + @param timeOfCal is the calibration time in milliseconds. + @return true o false. + */ + void middleCalibration(uint16_t timeOfCal); - /** - @brief Calibration of the axes at the extreme points (min end max for each axis). - @details - It is recommended to rotate the joystick in a circular way along its perimeter (maximum radius - for each axis) throughout the calibration time. - @param timeOfCal is the calibration time in milliseconds. - @return true o false. - */ - bool axesCalibration(uint16_t timeOfCal); + /** + @brief Calibration of the axes at the extreme points (min end max for each axis). + @details + It is recommended to rotate the joystick in a circular way along its perimeter (maximum radius + for each axis) throughout the calibration time. + @param timeOfCal is the calibration time in milliseconds. + @return true o false. + */ + bool axesCalibration(uint16_t timeOfCal); - /** - @brief Method that allows you to set the minimum and maximum calibration points for each axis. - @details - Useful to set the values read by eeprom. Allows you to set the values individually, - useful for making changes in run time. - @warning - All calibration points (min and maximum) for each axis (x and y) must be defined to - obtain a scale reading of the two axes. - Only the extreme calibration points can be set, the center point is defined only for calibration purposes. - @param axis X or Y axle enumerator flag. - @param point MIN, MID or MAX enumertor flag of the calibration point. - @param value point value to set. For example to set value (876) of the X MAX - @code - objectname.setCalibratedPoint(X, MAX, 876); - @endcode - */ - void setCalibratedPoint(axis_t axis, point_t point, uint16_t value); + /** + @brief Method that allows you to set the minimum and maximum calibration points for each axis. + @details + Useful to set the values read by eeprom. Allows you to set the values individually, + useful for making changes in run time. + @warning + All calibration points (min and maximum) for each axis (x and y) must be defined to + obtain a scale reading of the two axes. + Only the extreme calibration points can be set, the center point is defined only for + calibration purposes. + @param axis X or Y axle enumerator flag. + @param point MIN, MID or MAX enumertor flag of the calibration point. + @param value point value to set. For example to set value (876) of the X MAX + @code + objectname.setCalibratedPoint(X, MAX, 876); + @endcode + */ + void setCalibratedPoint(axis_t axis, point_t point, uint16_t value); - /** - @brief This method returns the value of the required axis and point. - @details - It can be used to compare the saved values with the new ones, to read the values saved in - the eeprom with the "setCalibratedPoint" function or for debug. - @see https://github.com/PalladinoMarco/AlignedJoystick/wiki wiki documentation for more details. - @param axis X or Y axle enumerator flag. - @param point MIN, MID or MAX enumertor flag of the calibration point. - @return calibrated point of the axis request. For example to get the calibrated point of Y MIN - @code - objectname.getCalibratedPoint(Y, MIN); - @endcode - */ - uint16_t getCalibratedPoint(axis_t axis, point_t point); + /** + @brief This method returns the value of the required axis and point. + @details + It can be used to compare the saved values with the new ones, to read the values saved in + the eeprom with the "setCalibratedPoint" function or for debug. + @see https://github.com/PalladinoMarco/AlignedJoystick/wiki wiki documentation for more + details. + @param axis X or Y axle enumerator flag. + @param point MIN, MID or MAX enumertor flag of the calibration point. + @return calibrated point of the axis request. For example to get the calibrated point of Y MIN + @code + objectname.getCalibratedPoint(Y, MIN); + @endcode + */ + uint16_t getCalibratedPoint(axis_t axis, point_t point); - /** - @brief This method returns the required axis value. If calibrated, returns the aligned axis values. - @param axis X or Y axle enumerator flag. - @return analog read of the axis request. For example to read Y axis @code objectname.read(Y); @endcode - */ - uint16_t read(axis_t axis); + /** + @brief This method returns the required axis value. If calibrated, returns the aligned axis + values. + @param axis X or Y axle enumerator flag. + @return analog read of the axis request. For example to read Y axis @code objectname.read(Y); + @endcode + */ + uint16_t read(axis_t axis); - /** - @brief This method returns the required joystick axis values in the set range (map functions) - @details - If you want to get a mapping by keeping the scale of calibrated values do not use the arduino map - unction (already included in the method) but use the optional parameters "out_min" and "out_max" - of the read method. - For arduino map @see https://www.arduino.cc/reference/en/language/functions/math/map/ - @param axis X or Y axle enumerator flag. - @param out_min minimum range output value. - @param out_max maximum range output value. - @return analog read of the relative axis in map mode, for example to control a servo motor, do this: - @code - objectname.read(X, 1000, 2000); - objectname.read(Y, 1000, 2000); - @endcode - */ - uint16_t read(axis_t axis, int32_t out_min, int32_t out_max); - - private: - /* - sets a single minimum and maximum value, equal for each axis of the joystick to scale them. - */ - void axesAlign(); - uint8_t xPin; - uint8_t yPin; - uint16_t alignMin; - uint16_t alignMax; - uint16_t xAxisCalibCenter; - uint16_t xAxisCalibMinimum; - uint16_t xAxisCalibMaximum; - uint16_t yAxisCalibCenter; - uint16_t yAxisCalibMinimum; - uint16_t yAxisCalibMaximum; - bool joystickCentered; - bool joystickFullCalibrated; + /** + @brief This method returns the required joystick axis values in the set range (map functions) + @details + If you want to get a mapping by keeping the scale of calibrated values do not use the arduino + map unction (already included in the method) but use the optional parameters "out_min" and + "out_max" of the read method. For arduino map @see + https://www.arduino.cc/reference/en/language/functions/math/map/ + @param axis X or Y axle enumerator flag. + @param out_min minimum range output value. + @param out_max maximum range output value. + @return analog read of the relative axis in map mode, for example to control a servo motor, do + this: + @code + objectname.read(X, 1000, 2000); + objectname.read(Y, 1000, 2000); + @endcode + */ + uint16_t read(axis_t axis, int32_t out_min, int32_t out_max); + + private: + /* + sets a single minimum and maximum value, equal for each axis of the joystick to scale them. + */ + void axesAlign(); + uint8_t xPin; + uint8_t yPin; + uint16_t alignMin; + uint16_t alignMax; + uint16_t xAxisCalibCenter; + uint16_t xAxisCalibMinimum; + uint16_t xAxisCalibMaximum; + uint16_t yAxisCalibCenter; + uint16_t yAxisCalibMinimum; + uint16_t yAxisCalibMaximum; + bool joystickCentered; + bool joystickFullCalibrated; }; // class from elapsed-Millis @@ -190,17 +194,17 @@ class AlignedJoy /* Elapsed time types - for easy-to-use measurements of elapsed time * http://www.pjrc.com/teensy/ * Copyright (c) 2011 PJRC.COM, LLC - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -209,25 +213,69 @@ class AlignedJoy * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -class calibrationTimer -{ -private: - unsigned long ms; -public: - calibrationTimer(void) { ms = millis(); } - calibrationTimer(unsigned long val) { ms = millis() - val; } - calibrationTimer(const calibrationTimer &orig) { ms = orig.ms; } - operator unsigned long () const { return millis() - ms; } - calibrationTimer & operator = (const calibrationTimer &rhs) { ms = rhs.ms; return *this; } - calibrationTimer & operator = (unsigned long val) { ms = millis() - val; return *this; } - calibrationTimer & operator -= (unsigned long val) { ms += val ; return *this; } - calibrationTimer & operator += (unsigned long val) { ms -= val ; return *this; } - calibrationTimer operator - (int val) const { calibrationTimer r(*this); r.ms += val; return r; } - calibrationTimer operator - (unsigned int val) const { calibrationTimer r(*this); r.ms += val; return r; } - calibrationTimer operator - (long val) const { calibrationTimer r(*this); r.ms += val; return r; } - calibrationTimer operator - (unsigned long val) const { calibrationTimer r(*this); r.ms += val; return r; } - calibrationTimer operator + (int val) const { calibrationTimer r(*this); r.ms -= val; return r; } - calibrationTimer operator + (unsigned int val) const { calibrationTimer r(*this); r.ms -= val; return r; } - calibrationTimer operator + (long val) const { calibrationTimer r(*this); r.ms -= val; return r; } - calibrationTimer operator + (unsigned long val) const { calibrationTimer r(*this); r.ms -= val; return r; } +class calibrationTimer { + private: + unsigned long ms; + + public: + calibrationTimer(void) { ms = millis(); } + calibrationTimer(unsigned long val) { ms = millis() - val; } + calibrationTimer(const calibrationTimer& orig) { ms = orig.ms; } + operator unsigned long() const { return millis() - ms; } + calibrationTimer& operator=(const calibrationTimer& rhs) { + ms = rhs.ms; + return *this; + } + calibrationTimer& operator=(unsigned long val) { + ms = millis() - val; + return *this; + } + calibrationTimer& operator-=(unsigned long val) { + ms += val; + return *this; + } + calibrationTimer& operator+=(unsigned long val) { + ms -= val; + return *this; + } + calibrationTimer operator-(int val) const { + calibrationTimer r(*this); + r.ms += val; + return r; + } + calibrationTimer operator-(unsigned int val) const { + calibrationTimer r(*this); + r.ms += val; + return r; + } + calibrationTimer operator-(long val) const { + calibrationTimer r(*this); + r.ms += val; + return r; + } + calibrationTimer operator-(unsigned long val) const { + calibrationTimer r(*this); + r.ms += val; + return r; + } + calibrationTimer operator+(int val) const { + calibrationTimer r(*this); + r.ms -= val; + return r; + } + calibrationTimer operator+(unsigned int val) const { + calibrationTimer r(*this); + r.ms -= val; + return r; + } + calibrationTimer operator+(long val) const { + calibrationTimer r(*this); + r.ms -= val; + return r; + } + calibrationTimer operator+(unsigned long val) const { + calibrationTimer r(*this); + r.ms -= val; + return r; + } }; diff --git a/lib/nvm/src/NvmEeprom.cpp b/lib/nvm/src/NvmEeprom.cpp index a769d1d..ad31459 100644 --- a/lib/nvm/src/NvmEeprom.cpp +++ b/lib/nvm/src/NvmEeprom.cpp @@ -10,25 +10,21 @@ bool JoystickAxisCalibration::valid() const { return min < mid < max; } -void writeNvm(const NonVolatileMemory &nvm) -{ - for (size_t ii = 0; ii < sizeof(NonVolatileMemory); ii++) - { +void writeNvm(const NonVolatileMemory& nvm) { + for (size_t ii = 0; ii < sizeof(NonVolatileMemory); ii++) { EEPROM.write(ii, nvm.rawBytes[ii]); } } -void writeCalibration(const JoystickCalibration &cal) { +void writeCalibration(const JoystickCalibration& cal) { NonVolatileMemory nvm = {}; - nvm.joystickCal = cal; + nvm.calData.joystickCal = cal; writeNvm(nvm); } -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); } } diff --git a/lib/nvm/src/NvmEeprom.hpp b/lib/nvm/src/NvmEeprom.hpp index 4a84cff..c7844fa 100644 --- a/lib/nvm/src/NvmEeprom.hpp +++ b/lib/nvm/src/NvmEeprom.hpp @@ -9,8 +9,7 @@ #define __NVMEEPROM_H__ #include -struct JoystickAxisCalibration -{ +struct JoystickAxisCalibration { /// Minimum value axis could be uint16_t min; /// average center point of axis @@ -23,7 +22,6 @@ 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 { @@ -32,33 +30,31 @@ struct LinearAnalogCalibration { inline bool valid() const { return min < max; } } __attribute__((packed)); -struct JoystickCalibration -{ +struct JoystickCalibration { JoystickAxisCalibration x; JoystickAxisCalibration y; } __attribute__((packed)); static constexpr uint32_t VALID_MARKER_DEFAULT = 0xcafecall; -union NonVolatileMemory -{ +union NonVolatileMemory { + /// place hard-coded start marker at the beginning of the data + /// to indicate validity + uint32_t validMarker = VALID_MARKER_DEFAULT; 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] = {}; + uint8_t rawBytes[sizeof(NonVolatileMemory::Calibration)] = {}; inline bool valid() const { return calData.validMarker == VALID_MARKER_DEFAULT; } }; /// @brief Write the provided struct to EEPROM -void writeNvm(const NonVolatileMemory &nvm); -void writeCalibration(const JoystickCalibration&cal); +void writeNvm(const NonVolatileMemory& nvm); +void writeCalibration(const JoystickCalibration& cal); -void readNvm(NonVolatileMemory &nvm); +void readNvm(NonVolatileMemory& nvm); #endif /* __NVMEEPROM_H__ */ diff --git a/src/main.cpp b/src/main.cpp index f6ff51f..42a70e3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,32 +1,35 @@ -#include #include -#include "NvmEeprom.hpp" +#include #include "Arduino_LED_Matrix.h" +#include "NvmEeprom.hpp" // joystick calibration #define TIME_CAL_1 2000 #define TIME_CAL_2 3000 // 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; /// 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) { /* - * 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). */ // CALIBRATION 1 - Serial.print("Center Joystick Calibration \n\nLeave the joystick in the centre position during the calibration\ntime which is set to "); + Serial.print( + "Center Joystick Calibration \n\nLeave the joystick in the centre position during the " + "calibration\ntime which is set to "); Serial.print(TIME_CAL_1); Serial.println(" milliseconds."); delay(5000); Serial.println("Calibration started!"); delay(500); /* - * for calibrate the joystick center point use "centerCalibration" method; objectname.centerCalibration(uint16_t timeOfCal). - * "timeOfCal" is the calibration time in milliseconds + * for calibrate the joystick center point use "centerCalibration" method; + * objectname.centerCalibration(uint16_t timeOfCal). "timeOfCal" is the calibration time in + * milliseconds */ joy.middleCalibration(TIME_CAL_1); Serial.println("Joystick Centered!"); @@ -38,34 +41,36 @@ bool runJoystickCalibrationRoutine(AlignedJoy &joy, JoystickCalibration &cal) * It is recommended to rotate the joystick in a circular way along its circumference throughout * the calibration time. */ - Serial.print("Start axes Calibration \n\nRotate the joystick in a circular way along its circumference\nthroughout the calibration time ("); + Serial.print( + "Start axes Calibration \n\nRotate the joystick in a circular way along its " + "circumference\nthroughout the calibration time ("); Serial.print(TIME_CAL_2); Serial.println(" milliseconds)."); delay(5000); Serial.println("Calibration started!"); delay(500); /* - * for calibrate the joystick axes points use "axesCalibration" method (bool type); objectname.axesCalibration(uint16_t timeOfCal). - * "timeOfCal" is the calibration time in milliseconds. + * for calibrate the joystick axes points use "axesCalibration" method (bool type); + * objectname.axesCalibration(uint16_t timeOfCal). "timeOfCal" is the calibration time in + * milliseconds. */ - if (joy.axesCalibration(TIME_CAL_2)) - { - Serial.println("Calibration succesfull!!"); + if (joy.axesCalibration(TIME_CAL_2)) { + Serial.println("Calibration succesfull!"); } - else - { - Serial.println("Calibration failed!!"); + else { + Serial.println("Calibration failed!"); return false; } // Print all points calibrated /* - * You can use these values to save them to eeprom memory. In this way you will avoid requiring the joystick calibration at each boot time. - * To set the parameters read by eeprom you have to use the "setCalibratedPoint" method. - * If your project does not require the re-calibration of the joystick then you can make a sketch like this only to display the calibrated - * values to set them in the final project using the "setCalibratedPoint" method. - * To get the calibrated point values use getCalibratedPoint(axis_t axis, point_t point). - * The parameters: the labels of the "axis_t" shall be X and Y; the labels of "point_t" is MIN, MID and MAX. + * You can use these values to save them to eeprom memory. In this way you will avoid requiring + * the joystick calibration at each boot time. To set the parameters read by eeprom you have to + * use the "setCalibratedPoint" method. If your project does not require the re-calibration of + * the joystick then you can make a sketch like this only to display the calibrated values to + * set them in the final project using the "setCalibratedPoint" method. To get the calibrated + * point values use getCalibratedPoint(axis_t axis, point_t point). The parameters: the labels + * of the "axis_t" shall be X and Y; the labels of "point_t" is MIN, MID and MAX. */ Serial.print("X min -> "); Serial.print(joy.getCalibratedPoint(X, MIN)); @@ -90,15 +95,12 @@ bool runJoystickCalibrationRoutine(AlignedJoy &joy, JoystickCalibration &cal) return true; } -void setup() -{ - +void setup() { // SERIAL INITIALIZE Serial.begin(115200); ledMatrix.loadSequence(LEDMATRIX_ANIMATION_STARTUP); ledMatrix.begin(); - while (!Serial) - { + while (!Serial) { } ledMatrix.play(true); @@ -109,9 +111,11 @@ void setup() // run joystick calibration if needed bool calibrationInvalid = nvm.valid(); do { - calibrationInvalid |= !nvm.joystickCal.x.valid() || !nvm.joystickCal.y.valid(); + calibrationInvalid |= + !nvm.calData.joystickCal.x.valid() || !nvm.calData.joystickCal.y.valid(); if (calibrationInvalid) { - calibrationInvalid |= !runJoystickCalibrationRoutine(joystick_1, nvm.calData.joystickCal); + calibrationInvalid |= + !runJoystickCalibrationRoutine(joystick_1, nvm.calData.joystickCal); } } while (calibrationInvalid); // ensure calibration has been applied @@ -125,14 +129,11 @@ void setup() // run analog lever calibration if needed - // write NVM in the event any values were updated writeNvm(nvm); } -void loop() -{ - +void loop() { // print joystick axes value Serial.print("joystick_1 X -> "); Serial.print(joystick_1.read(X));