├── CircuitDiagram.png ├── library.properties ├── keywords.txt ├── src ├── YInverterJoystick.cpp ├── XInverterJoystick.cpp ├── XYReplacerJoystick.cpp ├── DelegateJoystick.h ├── DelegateJoystick.cpp ├── YInverterJoystick.h ├── XInverterJoystick.h ├── AxisJoystick.cpp ├── XYReplacerJoystick.h ├── Joystick.h └── AxisJoystick.h ├── LICENSE ├── examples ├── ReplaceXY │ └── ReplaceXY.ino ├── ReplaceAndInvert │ └── ReplaceAndInvert.ino ├── InvertAxis │ └── InvertAxis.ino ├── SingleReading │ └── SingleReading.ino ├── MultipleReading │ └── MultipleReading.ino ├── SerialJoystick │ └── SerialJoystick.ino ├── CalibrateJoystick │ └── CalibrateJoystick.ino └── STM32 │ └── STM32.ino └── README.md /CircuitDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suoapvs/AxisJoystick/HEAD/CircuitDiagram.png -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=AxisJoystick 2 | version=2.2.3 3 | author=Yurii Salimov 4 | maintainer=Yurii Salimov 5 | sentence=The Library implements a set of methods for working with an axis joystick controller. 6 | paragraph=Dual axis XY joystick module reading. 7 | category=Signal Input/Output 8 | url=https://github.com/YuriiSalimov/AxisJoystick 9 | architectures=* 10 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ######################################## 2 | # Syntax Coloring Map For AxisJoystick # 3 | ######################################## 4 | 5 | ######################################## 6 | # Data types (KEYWORD1) # 7 | ######################################## 8 | 9 | Joystick KEYWORD1 10 | AxisJoystick KEYWORD1 11 | DelegateJoystick KEYWORD1 12 | XYReplacer KEYWORD1 13 | XInverter KEYWORD1 14 | YInverter KEYWORD1 15 | Move KEYWORD1 16 | 17 | ######################################## 18 | # Methods and Functions (KEYWORD2) # 19 | ######################################## 20 | 21 | singleRead KEYWORD2 22 | multipleRead KEYWORD2 23 | isPress KEYWORD2 24 | isUp KEYWORD2 25 | isDown KEYWORD2 26 | isRight KEYWORD2 27 | isLeft KEYWORD2 28 | xAxis KEYWORD2 29 | yAxis KEYWORD2 30 | readVRx KEYWORD2 31 | readVRy KEYWORD2 32 | readSW KEYWORD2 33 | calibrate KEYWORD2 34 | -------------------------------------------------------------------------------- /src/YInverterJoystick.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Created by Yurii Salimov, December, 2018. 3 | Released into the public domain. 4 | */ 5 | #include "YInverterJoystick.h" 6 | 7 | YInverterJoystick::YInverterJoystick(Joystick* origin) 8 | : DelegateJoystick(origin) { 9 | } 10 | 11 | boolean YInverterJoystick::isUp() { 12 | return DelegateJoystick::isDown(); 13 | } 14 | 15 | boolean YInverterJoystick::isDown() { 16 | return DelegateJoystick::isUp(); 17 | } 18 | 19 | Joystick::Move YInverterJoystick::singleRead() { 20 | return invert(DelegateJoystick::singleRead()); 21 | } 22 | 23 | Joystick::Move YInverterJoystick::multipleRead() { 24 | return invert(DelegateJoystick::multipleRead()); 25 | } 26 | 27 | inline Joystick::Move YInverterJoystick::invert(const Joystick::Move move) { 28 | switch (move) { 29 | case Move::UP: 30 | return Move::DOWN; 31 | case Move::DOWN: 32 | return Move::UP; 33 | default: 34 | return move; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/XInverterJoystick.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Created by Yurii Salimov, December, 2018. 3 | Released into the public domain. 4 | */ 5 | #include "XInverterJoystick.h" 6 | 7 | XInverterJoystick::XInverterJoystick(Joystick* origin) 8 | : DelegateJoystick(origin) { 9 | } 10 | 11 | boolean XInverterJoystick::isRight() { 12 | return DelegateJoystick::isLeft(); 13 | } 14 | 15 | boolean XInverterJoystick::isLeft() { 16 | return DelegateJoystick::isRight(); 17 | } 18 | 19 | Joystick::Move XInverterJoystick::singleRead() { 20 | return invert(DelegateJoystick::singleRead()); 21 | } 22 | 23 | Joystick::Move XInverterJoystick::multipleRead() { 24 | return invert(DelegateJoystick::multipleRead()); 25 | } 26 | 27 | inline Joystick::Move XInverterJoystick::invert(const Joystick::Move move) { 28 | switch (move) { 29 | case Move::LEFT: 30 | return Move::RIGHT; 31 | case Move::RIGHT: 32 | return Move::LEFT; 33 | default: 34 | return move; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018-2019 Yurii Salimov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/XYReplacerJoystick.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Created by Yurii Salimov, December, 2018. 3 | Released into the public domain. 4 | */ 5 | #include "XYReplacerJoystick.h" 6 | 7 | XYReplacerJoystick::XYReplacerJoystick(Joystick* origin) 8 | : DelegateJoystick(origin) { 9 | } 10 | 11 | boolean XYReplacerJoystick::isUp() { 12 | return DelegateJoystick::isRight(); 13 | } 14 | 15 | boolean XYReplacerJoystick::isDown() { 16 | return DelegateJoystick::isLeft(); 17 | } 18 | 19 | boolean XYReplacerJoystick::isRight() { 20 | return DelegateJoystick::isUp(); 21 | } 22 | 23 | boolean XYReplacerJoystick::isLeft() { 24 | return DelegateJoystick::isDown(); 25 | } 26 | 27 | int XYReplacerJoystick::xAxis() { 28 | return DelegateJoystick::yAxis(); 29 | } 30 | 31 | int XYReplacerJoystick::yAxis() { 32 | return DelegateJoystick::xAxis(); 33 | } 34 | 35 | Joystick::Move XYReplacerJoystick::singleRead() { 36 | return replace(DelegateJoystick::singleRead()); 37 | } 38 | 39 | Joystick::Move XYReplacerJoystick::multipleRead() { 40 | return replace(DelegateJoystick::multipleRead()); 41 | } 42 | 43 | inline Joystick::Move XYReplacerJoystick::replace(const Joystick::Move move) { 44 | switch (move) { 45 | case Move::UP: 46 | return Move::RIGHT; 47 | case Move::DOWN: 48 | return Move::LEFT; 49 | case Move::RIGHT: 50 | return Move::UP; 51 | case Move::LEFT: 52 | return Move::DOWN; 53 | default: 54 | return move; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/DelegateJoystick.h: -------------------------------------------------------------------------------- 1 | /** 2 | DelegateJoystick.h - abstract class-wrapper implements methods of 3 | the Joystick.h interface, delegating call methods to the input joystick. 4 | 5 | v.2.0: 6 | - created. 7 | 8 | v.2.0.1 9 | - added destructor. 10 | 11 | v.2.1.0 12 | - added calibration methods for joystick axes. 13 | 14 | https://github.com/YuriiSalimov/AxisJoystick 15 | 16 | Created by Yurii Salimov, December, 2018. 17 | Released into the public domain. 18 | */ 19 | #ifndef DELEGATE_JOYSTICK_H 20 | #define DELEGATE_JOYSTICK_H 21 | 22 | #include "Joystick.h" 23 | 24 | class DelegateJoystick : public Joystick { 25 | 26 | private: 27 | Joystick* origin; 28 | 29 | protected: 30 | /** 31 | Constructor 32 | 33 | @param origin - the origin joystick (not NULL) 34 | */ 35 | DelegateJoystick(Joystick* origin); 36 | 37 | public: 38 | /** 39 | Destructor. 40 | On deleting deletes the original joystick. 41 | */ 42 | ~DelegateJoystick(); 43 | 44 | virtual Move singleRead() override; 45 | 46 | virtual Move multipleRead() override; 47 | 48 | virtual boolean isPress() override; 49 | 50 | virtual boolean isUp() override; 51 | 52 | virtual boolean isDown() override; 53 | 54 | virtual boolean isRight() override; 55 | 56 | virtual boolean isLeft() override; 57 | 58 | virtual int xAxis() override; 59 | 60 | virtual int yAxis() override; 61 | 62 | int readVRx() override; 63 | 64 | int readVRy() override; 65 | 66 | int readSW() override; 67 | 68 | void calibrate(int low, int high) override; 69 | 70 | void calibrate(int adcMin, int adcMax, int deviation) override; 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /examples/ReplaceXY/ReplaceXY.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Replace X- and Y-axis of Joystick 3 | 4 | Reads a press of the joystick and displays information 5 | in the default Serial. 6 | 7 | https://github.com/YuriiSalimov/AxisJoystick 8 | 9 | Created by Yurii Salimov, December, 2018. 10 | Released into the public domain. 11 | */ 12 | #include 13 | #include 14 | #include 15 | 16 | #define SW_PIN 5 17 | #define VRX_PIN A1 18 | #define VRY_PIN A2 19 | 20 | Joystick* original; 21 | Joystick* xyReplacer; 22 | 23 | // the setup function runs once when you press reset or power the board 24 | void setup() { 25 | Serial.begin(9600); 26 | 27 | original = new AxisJoystick(SW_PIN, VRX_PIN, VRY_PIN); 28 | xyReplacer = new XYReplacerJoystick(original); 29 | } 30 | 31 | // the loop function runs over and over again forever 32 | void loop() { 33 | Serial.print("original: " + moveTitle(original->multipleRead())); 34 | Serial.println(" | replace XY: " + moveTitle(xyReplacer->multipleRead())); 35 | 36 | delay(500); // optionally, only to delay the output of information in the example 37 | } 38 | 39 | /** 40 | Return title of the input joystick move. 41 | */ 42 | String moveTitle(const Joystick::Move move) { 43 | switch (move) { 44 | case Joystick::Move::NOT: 45 | return "NOT"; 46 | case Joystick::Move::PRESS: 47 | return "PRESS"; 48 | case Joystick::Move::UP: 49 | return "UP"; 50 | case Joystick::Move::DOWN: 51 | return "DOWN"; 52 | case Joystick::Move::RIGHT: 53 | return "RIGHT"; 54 | case Joystick::Move::LEFT: 55 | return "LEFT"; 56 | default: 57 | return "???"; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/DelegateJoystick.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Created by Yurii Salimov, December, 2018. 3 | Released into the public domain. 4 | */ 5 | #include "DelegateJoystick.h" 6 | 7 | DelegateJoystick::DelegateJoystick(Joystick* origin) { 8 | this->origin = origin; 9 | } 10 | 11 | DelegateJoystick::~DelegateJoystick() { 12 | delete this->origin; 13 | } 14 | 15 | Joystick::Move DelegateJoystick::singleRead() { 16 | return this->origin->singleRead(); 17 | } 18 | 19 | Joystick::Move DelegateJoystick::multipleRead() { 20 | return this->origin->multipleRead(); 21 | } 22 | 23 | boolean DelegateJoystick::isPress() { 24 | return this->origin->isPress(); 25 | } 26 | 27 | boolean DelegateJoystick::isUp() { 28 | return this->origin->isUp(); 29 | } 30 | 31 | boolean DelegateJoystick::isDown() { 32 | return this->origin->isDown(); 33 | } 34 | 35 | boolean DelegateJoystick::isRight() { 36 | return this->origin->isRight(); 37 | } 38 | 39 | boolean DelegateJoystick::isLeft() { 40 | return this->origin->isLeft(); 41 | } 42 | 43 | int DelegateJoystick::xAxis() { 44 | return this->origin->xAxis(); 45 | } 46 | 47 | int DelegateJoystick::yAxis() { 48 | return this->origin->yAxis(); 49 | } 50 | 51 | int DelegateJoystick::readVRx() { 52 | return this->origin->readVRx(); 53 | } 54 | 55 | int DelegateJoystick::readVRy() { 56 | return this->origin->readVRy(); 57 | } 58 | 59 | int DelegateJoystick::readSW() { 60 | return this->origin->readSW(); 61 | } 62 | 63 | void DelegateJoystick::calibrate(const int low, const int high) { 64 | this->origin->calibrate(low, high); 65 | } 66 | 67 | void DelegateJoystick::calibrate( 68 | const int adcMin, const int adcMax, const int deviation 69 | ) { 70 | this->origin->calibrate(adcMin, adcMax, deviation); 71 | } 72 | -------------------------------------------------------------------------------- /examples/ReplaceAndInvert/ReplaceAndInvert.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Replace and Invert X- and Y-axes of Joystick 3 | 4 | Reads a press of the joystick and displays information 5 | in the default Serial. 6 | 7 | https://github.com/YuriiSalimov/AxisJoystick 8 | 9 | Created by Yurii Salimov, December, 2018. 10 | Released into the public domain. 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define SW_PIN 5 19 | #define VRX_PIN A1 20 | #define VRY_PIN A2 21 | 22 | Joystick* original; 23 | Joystick* modified; 24 | 25 | // the setup function runs once when you press reset or power the board 26 | void setup() { 27 | Serial.begin(9600); 28 | 29 | original = new AxisJoystick(SW_PIN, VRX_PIN, VRY_PIN); 30 | modified = new XYReplacerJoystick( 31 | new XInverterJoystick( 32 | new YInverterJoystick(original) 33 | ) 34 | ); 35 | } 36 | 37 | // the loop function runs over and over again forever 38 | void loop() { 39 | Serial.print("original: " + moveTitle(original->multipleRead())); 40 | Serial.println(" | modified: " + moveTitle(modified->multipleRead())); 41 | 42 | delay(500); // optionally, only to delay the output of information in the example 43 | } 44 | 45 | /** 46 | Return title of the input joystick move. 47 | */ 48 | String moveTitle(const Joystick::Move move) { 49 | switch (move) { 50 | case Joystick::Move::NOT: 51 | return "NOT"; 52 | case Joystick::Move::PRESS: 53 | return "PRESS"; 54 | case Joystick::Move::UP: 55 | return "UP"; 56 | case Joystick::Move::DOWN: 57 | return "DOWN"; 58 | case Joystick::Move::RIGHT: 59 | return "RIGHT"; 60 | case Joystick::Move::LEFT: 61 | return "LEFT"; 62 | default: 63 | return "???"; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /examples/InvertAxis/InvertAxis.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Invert X- and Y-axes of Joystick 3 | 4 | Reads a press of the joystick and displays information 5 | in the default Serial. 6 | 7 | https://github.com/YuriiSalimov/AxisJoystick 8 | 9 | Created by Yurii Salimov, December, 2018. 10 | Released into the public domain. 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define SW_PIN 5 18 | #define VRX_PIN A1 19 | #define VRY_PIN A2 20 | 21 | Joystick* original; 22 | Joystick* xInverter; 23 | Joystick* yInverter; 24 | 25 | // the setup function runs once when you press reset or power the board 26 | void setup() { 27 | Serial.begin(9600); 28 | 29 | original = new AxisJoystick(SW_PIN, VRX_PIN, VRY_PIN); 30 | xInverter = new XInverterJoystick(original); 31 | yInverter = new YInverterJoystick(original); 32 | } 33 | 34 | // the loop function runs over and over again forever 35 | void loop() { 36 | Serial.print("original: " + moveTitle(original->multipleRead())); 37 | Serial.print(" | invert X: " + moveTitle(xInverter->multipleRead())); 38 | Serial.println(" | invert Y: " + moveTitle(yInverter->multipleRead())); 39 | 40 | delay(500); // optionally, only to delay the output of information in the example 41 | } 42 | 43 | /** 44 | Return title of the input joystick move. 45 | */ 46 | String moveTitle(const Joystick::Move move) { 47 | switch (move) { 48 | case Joystick::Move::NOT: 49 | return "NOT"; 50 | case Joystick::Move::PRESS: 51 | return "PRESS"; 52 | case Joystick::Move::UP: 53 | return "UP"; 54 | case Joystick::Move::DOWN: 55 | return "DOWN"; 56 | case Joystick::Move::RIGHT: 57 | return "RIGHT"; 58 | case Joystick::Move::LEFT: 59 | return "LEFT"; 60 | default: 61 | return "???"; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /examples/SingleReading/SingleReading.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Axis Joystick, Single Reading 3 | 4 | Reads a press of the joystick and displays information 5 | in the default Serial. 6 | 7 | Single reading of the joystick controller. 8 | If the joystick is clamped, the next 9 | value of pressing - NOT. 10 | Return value of pressing the remote control: 11 | Move::PRESS - button is pressed; 12 | Move::UP - X axis is pressed up; 13 | Move::DOWN - X axis is pressed down; 14 | Move::RIGTH - Y axis is pressed right; 15 | Move::LEFT - Y axis is pressed left; 16 | Move::NOT - not pressed. 17 | 18 | https://github.com/YuriiSalimov/AxisJoystick 19 | 20 | Created by Yurii Salimov, February, 2018. 21 | Released into the public domain. 22 | */ 23 | #include 24 | #include 25 | 26 | #define SW_PIN 5 27 | #define VRX_PIN A1 28 | #define VRY_PIN A2 29 | 30 | Joystick* joystick; 31 | 32 | // the setup function runs once when you press reset or power the board 33 | void setup() { 34 | Serial.begin(9600); 35 | 36 | joystick = new AxisJoystick(SW_PIN, VRX_PIN, VRY_PIN); 37 | } 38 | 39 | // the loop function runs over and over again forever 40 | void loop() { 41 | Serial.print("Joystick, Single Reading: "); 42 | Serial.println(moveTitle(joystick->singleRead())); 43 | 44 | delay(500); // optionally, only to delay the output of information in the example 45 | } 46 | 47 | /** 48 | Return title of the input joystick move. 49 | */ 50 | String moveTitle(const Joystick::Move move) { 51 | switch (move) { 52 | case Joystick::Move::NOT: 53 | return "NOT"; 54 | case Joystick::Move::PRESS: 55 | return "PRESS"; 56 | case Joystick::Move::UP: 57 | return "UP"; 58 | case Joystick::Move::DOWN: 59 | return "DOWN"; 60 | case Joystick::Move::RIGHT: 61 | return "RIGHT"; 62 | case Joystick::Move::LEFT: 63 | return "LEFT"; 64 | default: 65 | return "???"; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /examples/MultipleReading/MultipleReading.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Axis Joystick, Multiple Reading 3 | 4 | Reads a press of the joystick and displays information 5 | in the default Serial. 6 | 7 | Multiple reading of the joystick controller. 8 | If the joystick is clamped, 9 | returns a pressed button value. 10 | 11 | Return value of pressing the remote control: 12 | Move::PRESS - button is pressed; 13 | Move::UP - X axis is pressed up; 14 | Move::DOWN - X axis is pressed down; 15 | Move::RIGTH - Y axis is pressed right; 16 | Move::LEFT - Y axis is pressed left; 17 | Move::NOT - not pressed. 18 | 19 | https://github.com/YuriiSalimov/AxisJoystick 20 | 21 | Created by Yurii Salimov, February, 2018. 22 | Released into the public domain. 23 | */ 24 | #include 25 | #include 26 | 27 | #define SW_PIN 5 28 | #define VRX_PIN A1 29 | #define VRY_PIN A2 30 | 31 | Joystick* joystick; 32 | 33 | // the setup function runs once when you press reset or power the board 34 | void setup() { 35 | Serial.begin(9600); 36 | 37 | joystick = new AxisJoystick(SW_PIN, VRX_PIN, VRY_PIN); 38 | } 39 | 40 | // the loop function runs over and over again forever 41 | void loop() { 42 | Serial.print("Joystick, Multiple Reading: "); 43 | Serial.println(moveTitle(joystick->multipleRead())); 44 | 45 | delay(500); // optionally, only to delay the output of information in the example 46 | } 47 | 48 | /** 49 | Return title of the input joystick move. 50 | */ 51 | String moveTitle(const Joystick::Move move) { 52 | switch (move) { 53 | case Joystick::Move::NOT: 54 | return "NOT"; 55 | case Joystick::Move::PRESS: 56 | return "PRESS"; 57 | case Joystick::Move::UP: 58 | return "UP"; 59 | case Joystick::Move::DOWN: 60 | return "DOWN"; 61 | case Joystick::Move::RIGHT: 62 | return "RIGHT"; 63 | case Joystick::Move::LEFT: 64 | return "LEFT"; 65 | default: 66 | return "???"; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /examples/SerialJoystick/SerialJoystick.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Axis Joystick 3 | 4 | Reads a press of the joystick and displays information 5 | in the default Serial. 6 | 7 | https://github.com/YuriiSalimov/AxisJoystick 8 | 9 | Created by Yurii Salimov, February, 2018. 10 | Released into the public domain. 11 | */ 12 | #include 13 | #include 14 | 15 | #define SW_PIN 5 16 | #define VRX_PIN A1 17 | #define VRY_PIN A2 18 | 19 | Joystick* joystic; 20 | 21 | // the setup function runs once when you press reset or power the board 22 | void setup() { 23 | Serial.begin(9600); 24 | 25 | joystic = new AxisJoystick(SW_PIN, VRX_PIN, VRY_PIN); 26 | } 27 | 28 | // the loop function runs over and over again forever 29 | void loop() { 30 | Serial.print("| SingleRead: " + moveTitle(joystic->singleRead())); 31 | Serial.print(" | MultipleRead: " + moveTitle(joystic->multipleRead())); 32 | Serial.print(" | Press: " + String(joystic->isPress())); 33 | Serial.print(" | Up: " + String(joystic->isUp())); 34 | Serial.print(" | Down: " + String(joystic->isDown())); 35 | Serial.print(" | Right: " + String(joystic->isRight())); 36 | Serial.print(" | Left: " + String(joystic->isLeft())); 37 | Serial.print(" | VRx: " + String(joystic->readVRx())); 38 | Serial.print(" | VRy: " + String(joystic->readVRy())); 39 | Serial.println(" | SW: " + String(joystic->readSW()) + " |"); 40 | 41 | delay(500); // optionally, only to delay the output of information in the example 42 | } 43 | 44 | /** 45 | Return title of the input joystick move. 46 | */ 47 | String moveTitle(const Joystick::Move move) { 48 | switch (move) { 49 | case Joystick::Move::NOT: 50 | return "NOT"; 51 | case Joystick::Move::PRESS: 52 | return "PRESS"; 53 | case Joystick::Move::UP: 54 | return "UP"; 55 | case Joystick::Move::DOWN: 56 | return "DOWN"; 57 | case Joystick::Move::RIGHT: 58 | return "RIGHT"; 59 | case Joystick::Move::LEFT: 60 | return "LEFT"; 61 | default: 62 | return "???"; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/YInverterJoystick.h: -------------------------------------------------------------------------------- 1 | /** 2 | YInverter - class-wrapper implements methods of the Joystick.h 3 | interface, inverting Y-axis signal of the origin joystick. 4 | 5 | v.2.0: 6 | - created. 7 | 8 | v.2.1.1 9 | - optimized replace() method. 10 | 11 | v.2.2.0 12 | - renamed from YInverter. 13 | 14 | https://github.com/YuriiSalimov/AxisJoystick 15 | 16 | Created by Yurii Salimov, December, 2018. 17 | Released into the public domain. 18 | */ 19 | #ifndef Y_INVERTER_JOYSTICK_H 20 | #define Y_INVERTER_JOYSTICK_H 21 | 22 | #include "DelegateJoystick.h" 23 | 24 | class YInverterJoystick final : public DelegateJoystick { 25 | 26 | public: 27 | /** 28 | Constructor 29 | 30 | @param origin - the origin joystick (not NULL) 31 | */ 32 | YInverterJoystick(Joystick* origin); 33 | 34 | /** 35 | Single reading of the joystick controller. 36 | Inverts the input joystick Y-axis move. 37 | 38 | @return value of pressing the joystick (never NULL): 39 | Move::UP - Y-axis is pressed down; 40 | Move::DOWN - Y-axis is pressed up; 41 | else the input move. 42 | */ 43 | Move singleRead() override; 44 | 45 | /** 46 | Multiple reading of the joystick controller. 47 | Inverts the input joystick Y-axis move. 48 | 49 | @return value of pressing the joystick (never NULL): 50 | Move::UP - Y-axis is pressed down; 51 | Move::DOWN - Y-axis is pressed up; 52 | else the input move. 53 | */ 54 | Move multipleRead() override; 55 | 56 | /** 57 | Checks if the joystick is pressed up (Y-axis). 58 | 59 | @return true - joystick is really pressed down, 60 | false - joystick is not pressed. 61 | */ 62 | boolean isUp() override; 63 | 64 | /** 65 | Checks if the joystick is pressed down (Y-axis). 66 | 67 | @return true - joystick is really pressed up, 68 | false - joystick is not pressed. 69 | */ 70 | boolean isDown() override; 71 | 72 | private: 73 | /** 74 | Inverts the input joystick Y-axis move. 75 | 76 | @param move - the origin move to invert (not NULL) 77 | @return value of pressing the joystick (never NULL): 78 | Move::UP - Y-axis is pressed down; 79 | Move::DOWN - Y-axis is pressed up; 80 | else the input move. 81 | */ 82 | inline Move invert(Move move); 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/XInverterJoystick.h: -------------------------------------------------------------------------------- 1 | /** 2 | XInverter - class-wrapper implements methods of the Joystick.h 3 | interface, inverting X-axis signal of the origin joystick. 4 | 5 | v.2.0: 6 | - created. 7 | 8 | v.2.1.1 9 | - optimized invert() method. 10 | 11 | v.2.2.0 12 | - renamed from XInverter. 13 | 14 | https://github.com/YuriiSalimov/AxisJoystick 15 | 16 | Created by Yurii Salimov, December, 2018. 17 | Released into the public domain. 18 | */ 19 | #ifndef X_INVERTER_JOYSTICK_H 20 | #define X_INVERTER_JOYSTICK_H 21 | 22 | #include "DelegateJoystick.h" 23 | 24 | class XInverterJoystick final : public DelegateJoystick { 25 | 26 | public: 27 | /** 28 | Constructor 29 | 30 | @param origin - the origin joystick (not NULL) 31 | */ 32 | XInverterJoystick(Joystick* origin); 33 | 34 | /** 35 | Single reading of the joystick controller. 36 | Inverts the input joystick X-axis move. 37 | 38 | @return value of pressing the joystick (never NULL): 39 | Move::RIGHT - X-axis is pressed left; 40 | Move::LEFT - X-axis is pressed right; 41 | else the origin move. 42 | */ 43 | Move singleRead() override; 44 | 45 | /** 46 | Multiple reading of the joystick controller. 47 | Inverts the input joystick X-axis move. 48 | 49 | @return value of pressing the joystick (never NULL): 50 | Move::RIGHT - X-axis is pressed left; 51 | Move::LEFT - X-axis is pressed right; 52 | else the origin move. 53 | */ 54 | Move multipleRead() override; 55 | 56 | /** 57 | Checks if the joystick is pressed right (X-axis). 58 | 59 | @return true - joystick is really pressed left, 60 | false - joystick is not pressed. 61 | */ 62 | boolean isRight() override; 63 | 64 | /** 65 | Checks if the joystick is pressed left (X-axis). 66 | 67 | @return true - joystick is really pressed right, 68 | false - joystick is not pressed. 69 | */ 70 | boolean isLeft() override; 71 | 72 | private: 73 | /** 74 | Inverts the input joystick X-axis move. 75 | 76 | @param move - the origin move to invert (not NULL) 77 | @return value of pressing the joystick (never NULL): 78 | Move::RIGHT - X-axis is pressed left; 79 | Move::LEFT - X-axis is pressed right; 80 | else the input move. 81 | */ 82 | inline Move invert(Move move); 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/AxisJoystick.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Created by Yurii Salimov, February, 2018. 3 | Released into the public domain. 4 | */ 5 | #include "AxisJoystick.h" 6 | 7 | AxisJoystick::AxisJoystick( 8 | const int SW_pin, 9 | const int VRx_pin, 10 | const int VRy_pin 11 | ) { 12 | pinMode(this->SW_pin = SW_pin, INPUT_PULLUP); 13 | pinMode(this->VRx_pin = VRx_pin, INPUT); 14 | pinMode(this->VRy_pin = VRy_pin, INPUT); 15 | } 16 | 17 | Joystick::Move AxisJoystick::singleRead() { 18 | const Move currentMove = multipleRead(); 19 | return (currentMove != this->previousMove) ? 20 | (this->previousMove = currentMove) : 21 | Move::NOT; 22 | } 23 | 24 | Joystick::Move AxisJoystick::multipleRead() { 25 | if (isPress()) { 26 | return Move::PRESS; 27 | } else if (isUp()) { 28 | return Move::UP; 29 | } else if (isDown()) { 30 | return Move::DOWN; 31 | } else if (isRight()) { 32 | return Move::RIGHT; 33 | } else if (isLeft()) { 34 | return Move::LEFT; 35 | } 36 | return Move::NOT; 37 | } 38 | 39 | boolean AxisJoystick::isPress() { 40 | return readSW() == BUTTON_PRESS_SIGNAL; 41 | } 42 | 43 | boolean AxisJoystick::isUp() { 44 | return isHigh(readVRy()); 45 | } 46 | 47 | boolean AxisJoystick::isDown() { 48 | return isLow(readVRy()); 49 | } 50 | 51 | boolean AxisJoystick::isRight() { 52 | return isHigh(readVRx()); 53 | } 54 | 55 | boolean AxisJoystick::isLeft() { 56 | return isLow(readVRx()); 57 | } 58 | 59 | int AxisJoystick::readVRx() { 60 | return analogRead(this->VRx_pin); 61 | } 62 | 63 | int AxisJoystick::readVRy() { 64 | return analogRead(this->VRy_pin); 65 | } 66 | 67 | int AxisJoystick::readSW() { 68 | return digitalRead(this->SW_pin); 69 | } 70 | 71 | int AxisJoystick::xAxis() { 72 | return readVRx(); 73 | } 74 | 75 | int AxisJoystick::yAxis() { 76 | return readVRy(); 77 | } 78 | 79 | void AxisJoystick::calibrate(const int low, const int high) { 80 | this->min = low; 81 | this->max = high; 82 | } 83 | 84 | void AxisJoystick::calibrate( 85 | const int adcMin, const int adcMax, const int deviation 86 | ) { 87 | calibrate( 88 | adcMin + deviation, 89 | adcMax - deviation 90 | ); 91 | } 92 | 93 | inline boolean AxisJoystick::isLow(const int value) { 94 | return (value <= this->min); 95 | } 96 | 97 | inline boolean AxisJoystick::isHigh(const int value) { 98 | return (value >= this->max); 99 | } 100 | -------------------------------------------------------------------------------- /examples/CalibrateJoystick/CalibrateJoystick.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Joystick axes calibration 3 | 4 | Reads a press of the calibrated joystick and displays information 5 | in the default Serial. 6 | 7 | To calibrate, call the calibrate() method: 8 | 9 | void calibrate(LOW, HIGH); 10 | or 11 | void calibrate(ADC_MIN, ADC_MAX, DEVIATION); 12 | 13 | Where: 14 | LOW - the lower bound of the values range (default, 100); 15 | HIGH - the upper bound of the values range (default, 923); 16 | ADC_MIN - min value of the board ADC (default for Arduino, 0); 17 | ADC_MAX - max value of the board ADC (default for Arduino, 1023); 18 | DEVIATION - deviation from the value’s axis range (default, 100). 19 | 20 | https://github.com/YuriiSalimov/AxisJoystick 21 | 22 | Created by Yurii Salimov, May, 2019. 23 | Released into the public domain. 24 | */ 25 | #include 26 | #include 27 | 28 | #define SW_PIN 5 29 | #define VRX_PIN A1 30 | #define VRY_PIN A2 31 | #define ARDUINO_ADC_MIN 0 32 | #define ARDUINO_ADC_MAX 1023 33 | #define AXES_DEVIATION 100 34 | 35 | Joystick* joystic; 36 | 37 | // the setup function runs once when you press reset or power the board 38 | void setup() { 39 | Serial.begin(9600); 40 | 41 | joystic = new AxisJoystick(SW_PIN, VRX_PIN, VRY_PIN); 42 | joystic->calibrate(ARDUINO_ADC_MIN, ARDUINO_ADC_MAX, AXES_DEVIATION); 43 | /* 44 | or 45 | joystic->calibrate( 46 | ARDUINO_ADC_MIN + AXES_DEVIATION, 47 | ARDUINO_ADC_MAX - AXES_DEVIATION 48 | ); 49 | */ 50 | } 51 | 52 | // the loop function runs over and over again forever 53 | void loop() { 54 | Serial.print("| SingleRead: " + moveTitle(joystic->singleRead())); 55 | Serial.print(" | MultipleRead: " + moveTitle(joystic->multipleRead())); 56 | Serial.print(" | Press: " + String(joystic->isPress())); 57 | Serial.print(" | Up: " + String(joystic->isUp())); 58 | Serial.print(" | Down: " + String(joystic->isDown())); 59 | Serial.print(" | Right: " + String(joystic->isRight())); 60 | Serial.print(" | Left: " + String(joystic->isLeft())); 61 | Serial.print(" | VRx: " + String(joystic->readVRx())); 62 | Serial.print(" | VRy: " + String(joystic->readVRy())); 63 | Serial.println(" | SW: " + String(joystic->readSW()) + " |"); 64 | 65 | delay(500); // optionally, only to delay the output of information in the example 66 | } 67 | 68 | /** 69 | Return title of the input joystick move. 70 | */ 71 | String moveTitle(const Joystick::Move move) { 72 | switch (move) { 73 | case Joystick::Move::NOT: 74 | return "NOT"; 75 | case Joystick::Move::PRESS: 76 | return "PRESS"; 77 | case Joystick::Move::UP: 78 | return "UP"; 79 | case Joystick::Move::DOWN: 80 | return "DOWN"; 81 | case Joystick::Move::RIGHT: 82 | return "RIGHT"; 83 | case Joystick::Move::LEFT: 84 | return "LEFT"; 85 | default: 86 | return "???"; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /examples/STM32/STM32.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Axis Joystick for STM32 3 | 4 | Reads a press of the joystick and displays information 5 | in the default Serial. 6 | 7 | The Arduino Uno or any other Arduino board that uses Atmega328 as 8 | the Microcontroller has ADC resolution of 10 bits. Hence the values on each 9 | analog channel can vary from 0 to 1023. 10 | The STM32 board has ADC resolution of 12 bits. Hence the values on each analog 11 | channel can vary from 0 to 4095. 12 | 13 | If you use the STM32 board, you must calibrate your joystick, 14 | since the analogRead(*) function return 0..4095 15 | versus 0..1023 for Arduino. 16 | 17 | --------------------------- 18 | | analogRead() | 19 | --------------------------- 20 | | Arduion | STM32 | 21 | |-------------------------| 22 | | 0...1023 | 0...4095 | 23 | --------------------------- 24 | 25 | To calibrate, call the calibrate() method: 26 | 27 | void calibrate(LOW, HIGH); 28 | or 29 | void calibrate(ADC_MIN, ADC_MAX, DEVIATION); 30 | 31 | Where: 32 | LOW - the lower bound of the values range (default, 100); 33 | HIGH - the upper bound of the values range (default, 923); 34 | ADC_MIN - min value of the board ADC (default for Arduino, 0); 35 | ADC_MAX - max value of the board ADC (default for Arduino, 1023); 36 | DEVIATION - deviation from the value’s axis range (default, 100). 37 | 38 | https://github.com/YuriiSalimov/AxisJoystick 39 | 40 | Created by Yurii Salimov, May, 2019. 41 | Released into the public domain. 42 | */ 43 | #include 44 | #include 45 | 46 | #define SW_PIN PA5 47 | #define VRX_PIN PA6 48 | #define VRY_PIN PA7 49 | #define STM32_ADC_MIN 0 50 | #define STM32_ADC_MAX 4095 51 | #define AXES_DEVIATION 100 52 | 53 | Joystick* joystic; 54 | 55 | // the setup function runs once when you press reset or power the board 56 | void setup() { 57 | Serial.begin(9600); 58 | 59 | joystic = new AxisJoystick(SW_PIN, VRX_PIN, VRY_PIN); 60 | joystic->calibrate(STM32_ADC_MIN, STM32_ADC_MAX, AXES_DEVIATION); 61 | /* 62 | or 63 | joystic->calibrate( 64 | STM32_ADC_MIN + AXES_DEVIATION, 65 | STM32_ADC_MAX - AXES_DEVIATION 66 | ); 67 | */ 68 | } 69 | 70 | // the loop function runs over and over again forever 71 | void loop() { 72 | Serial.print("SingleRead: " + moveTitle(joystic->singleRead())); 73 | Serial.println(" | MultipleRead: " + moveTitle(joystic->multipleRead())); 74 | 75 | delay(500); // optionally, only to delay the output of information in the example 76 | } 77 | 78 | /** 79 | Return title of the input joystick move. 80 | */ 81 | String moveTitle(const Joystick::Move move) { 82 | switch (move) { 83 | case Joystick::Move::NOT: 84 | return "NOT"; 85 | case Joystick::Move::PRESS: 86 | return "PRESS"; 87 | case Joystick::Move::UP: 88 | return "UP"; 89 | case Joystick::Move::DOWN: 90 | return "DOWN"; 91 | case Joystick::Move::RIGHT: 92 | return "RIGHT"; 93 | case Joystick::Move::LEFT: 94 | return "LEFT"; 95 | default: 96 | return "???"; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/XYReplacerJoystick.h: -------------------------------------------------------------------------------- 1 | /** 2 | XYReplacer - class-wrapper implements methods of the Joystick.h 3 | interface, replacing X- and Y-axes signal of the origin joystick. 4 | 5 | v.2.0: 6 | - created. 7 | 8 | v.2.1.1 9 | - optimized replace() method. 10 | 11 | v.2.2.0 12 | - renamed from XYReplacer. 13 | 14 | https://github.com/YuriiSalimov/AxisJoystick 15 | 16 | Created by Yurii Salimov, December, 2018. 17 | Released into the public domain. 18 | */ 19 | #ifndef XY_REPLACER_JOYSTICK_H 20 | #define XY_REPLACER_JOYSTICK_H 21 | 22 | #include "DelegateJoystick.h" 23 | 24 | class XYReplacerJoystick final : public DelegateJoystick { 25 | 26 | public: 27 | /** 28 | Constructor 29 | 30 | @param origin - the origin joystick (not NULL) 31 | */ 32 | XYReplacerJoystick(Joystick* origin); 33 | 34 | /** 35 | Single reading of the joystick controller. 36 | Replaces X- and Y-axis moves. 37 | 38 | @return value of pressing the joystick (never NULL): 39 | Move::UP - X-axis is pressed right; 40 | Move::DOWN - X-axis is pressed left; 41 | Move::LEFT - Y-axis is pressed down; 42 | Move::RIGHt - Y-axis is pressed up; 43 | else the input move. 44 | */ 45 | Move singleRead() override; 46 | 47 | /** 48 | Multiple reading of the joystick controller. 49 | Replaces X- and Y-axes moves. 50 | 51 | @return value of pressing the joystick (never NULL): 52 | Move::UP - X-axis is pressed right; 53 | Move::DOWN - X-axis is pressed left; 54 | Move::LEFT - Y-axis is pressed down; 55 | Move::RIGHt - Y-axis is pressed up; 56 | else the input move. 57 | */ 58 | Move multipleRead() override; 59 | 60 | /** 61 | Checks if the joystick is pressed up (Y-axis). 62 | 63 | @return true - joystick is really pressed right (X-axis), 64 | false - joystick is not pressed. 65 | */ 66 | boolean isUp() override; 67 | 68 | /** 69 | Checks if the joystick is pressed down (Y-axis). 70 | 71 | @return true - joystick is really pressed left (X-axis), 72 | false - joystick is not pressed. 73 | */ 74 | boolean isDown() override; 75 | 76 | /** 77 | Checks if the joystick is pressed right (X-axis). 78 | 79 | @return true - joystick is really pressed up (Y-axis), 80 | false - joystick is not pressed. 81 | */ 82 | boolean isRight() override; 83 | 84 | /** 85 | Checks if the joystick is pressed left (X-axis). 86 | 87 | @return true - joystick is really pressed down (Y-axis), 88 | false - joystick is not pressed. 89 | */ 90 | boolean isLeft() override; 91 | 92 | /** 93 | Reads the joystick X-axis coordinate 94 | (really Y-axis coordinate). 95 | 96 | @return X-axis (really Y-axis) coordinate 97 | */ 98 | int xAxis() override; 99 | 100 | /** 101 | Returns the joystick Y-axis coordinate 102 | (really X-axis coordinate). 103 | 104 | @return Y-axis (really X-axis) coordinate 105 | */ 106 | int yAxis() override; 107 | 108 | private: 109 | /** 110 | Replaces the input move from X- to Y-axis 111 | and from Y- to X-axis. 112 | 113 | @param move - the origin move to invert (not NULL) 114 | @return value of pressing the joystick (never NULL): 115 | Move::UP - X-axis is pressed right; 116 | Move::DOWN - X-axis is pressed left; 117 | Move::LEFT - Y-axis is pressed down; 118 | Move::RIGHt - Y-axis is pressed up; 119 | else the input move. 120 | */ 121 | inline Move replace(Move move); 122 | }; 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /src/Joystick.h: -------------------------------------------------------------------------------- 1 | /** 2 | Joystick - interface describes a set of methods 3 | for working with a joystick controller. 4 | 5 | v.2.1.0 6 | - added calibration methods for joystick axes 7 | 8 | v.2.2.1 9 | - updated methods for Joystick calibration 10 | 11 | v.2.2.3 12 | - added virtual destructor 13 | 14 | https://github.com/YuriiSalimov/AxisJoystick 15 | 16 | Created by Yurii Salimov, December, 2018. 17 | Released into the public domain. 18 | */ 19 | #ifndef JOYSTICK_H 20 | #define JOYSTICK_H 21 | 22 | #if defined(ARDUINO) && (ARDUINO >= 100) 23 | #include 24 | #else 25 | #include 26 | #endif 27 | 28 | class Joystick { 29 | 30 | public: 31 | /** 32 | Enums of a possible pressings 33 | of the joystick controller: 34 | PRESS - button is pressed; 35 | UP - X axis is pressed UP; 36 | DOWN - X axis is pressed DOWN; 37 | RIGTH - Y axis is pressed RIGHT; 38 | LEFT - Y axis is pressed LEFT; 39 | NOT - not pressed. 40 | */ 41 | enum Move { 42 | PRESS, UP, DOWN, RIGHT, LEFT, NOT 43 | }; 44 | 45 | /** 46 | Destructor 47 | Deletes Joystick instance. 48 | */ 49 | virtual ~Joystick() {}; 50 | 51 | /** 52 | Single reading of the joystick controller. 53 | If the joystick is clamped, the next 54 | value of pressing - NOT. 55 | 56 | @return value of pressing the joystick. 57 | */ 58 | virtual Move singleRead() = 0; 59 | 60 | /** 61 | Multiple reading of the joystick controller. 62 | If the joystick is clamped, 63 | returns a pressed button value. 64 | 65 | @return value of pressing the joystick: 66 | Move::PRESS - button is pressed; 67 | Move::UP - Y-axis is pressed up; 68 | Move::DOWN - Y-axis is pressed down; 69 | Move::RIGTH - X-axis is pressed right; 70 | Move::LEFT - X-axis is pressed left; 71 | Move::NOT - not pressed. 72 | */ 73 | virtual Move multipleRead() = 0; 74 | 75 | /** 76 | Checks if the joystick button is pressed. 77 | 78 | @return true - button is pressed, 79 | false - button is not pressed. 80 | */ 81 | virtual boolean isPress() = 0; 82 | 83 | /** 84 | Checks if the joystick is pressed up (Y-axis). 85 | 86 | @return true - joystick is pressed up, 87 | false - joystick is not pressed. 88 | */ 89 | virtual boolean isUp() = 0; 90 | 91 | /** 92 | Checks if the joystick is pressed down (Y-axis). 93 | 94 | @return true - joystick is pressed down, 95 | false - joystick is not pressed. 96 | */ 97 | virtual boolean isDown() = 0; 98 | 99 | /** 100 | Checks if the joystick is pressed right (X-axis). 101 | 102 | @return true - joystick is pressed right, 103 | false - joystick is not pressed. 104 | */ 105 | virtual boolean isRight() = 0; 106 | 107 | /** 108 | Checks if the joystick is pressed left (X-axis). 109 | 110 | @return true - joystick is pressed left, 111 | false - joystick is not pressed. 112 | */ 113 | virtual boolean isLeft() = 0; 114 | 115 | /** 116 | Reads the joystick X-axis coordinate. 117 | 118 | @return X-axis coordinate. 119 | */ 120 | virtual int xAxis() = 0; 121 | 122 | /** 123 | Reads the joystick Y-axis coordinate. 124 | 125 | @return Y-axis coordinate. 126 | */ 127 | virtual int yAxis() = 0; 128 | 129 | /** 130 | Reads the VRx pin value. 131 | 132 | @return VRx value. 133 | */ 134 | virtual int readVRx() = 0; 135 | 136 | /** 137 | Reads the VRy pin value. 138 | 139 | @return VRy value. 140 | */ 141 | virtual int readVRy() = 0; 142 | 143 | /** 144 | Reads the SW pin value. 145 | 146 | @return SW value. 147 | */ 148 | virtual int readSW() = 0; 149 | 150 | /** 151 | Joystick axes calibration. 152 | 153 | @param low - the lower bound of the values range; 154 | @param high - the upper bound of the values range; 155 | */ 156 | virtual void calibrate(int low, int high) = 0; 157 | 158 | /** 159 | Joystick axes calibration. 160 | 161 | @param adcMin - min value of the board ADC; 162 | @param adcMax - max value of the board ADC; 163 | @param deviation - deviation from the value’s axis range, 164 | when the axis is considered activated: 165 | axis value <= (low + deviation) 166 | or 167 | axis value >= (high - deviation). 168 | */ 169 | virtual void calibrate(int adcMin, int adcMax, int deviation) = 0; 170 | }; 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /src/AxisJoystick.h: -------------------------------------------------------------------------------- 1 | /** 2 | AxisJoystick - class implements methods of the Joystick.h 3 | interface for working with an analog joystick controller. 4 | 5 | v.1.0.3: 6 | - optimized call of the init() method. 7 | 8 | v.2.0: 9 | - added implementation of the Joystick interface; 10 | - replaced X and Y axes. 11 | 12 | v.2.1.0 13 | - added calibration methods for joystick axes. 14 | 15 | v.2.1.1 16 | - optimized singleRead() method. 17 | 18 | v.2.2.1 19 | - optimized methods for Joystick calibration. 20 | 21 | v.2.2.2 22 | Replaced "define" constants with "static const". 23 | 24 | https://github.com/YuriiSalimov/AxisJoystick 25 | 26 | Created by Yurii Salimov, February, 2018. 27 | Released into the public domain. 28 | */ 29 | #ifndef AXIS_JOYSTICK_H 30 | #define AXIS_JOYSTICK_H 31 | 32 | #include "Joystick.h" 33 | 34 | class AxisJoystick final : public Joystick { 35 | 36 | private: 37 | /** 38 | The value at which the joystick axis 39 | is considered to be on. 40 | */ 41 | static const int AXIS_DEVIATION = 100; 42 | // Min value of Arduino ADC. 43 | static const int ADC_MIN = 0; 44 | // Max value of Arduino ADC. 45 | static const int ADC_MAX = 1023; 46 | // Signal when the joystick button is pressed. 47 | static const int BUTTON_PRESS_SIGNAL = LOW; 48 | 49 | int SW_pin; 50 | int VRx_pin; 51 | int VRy_pin; 52 | int min = ADC_MIN + AXIS_DEVIATION; 53 | int max = ADC_MAX - AXIS_DEVIATION; 54 | 55 | /** 56 | The value for the temporary storage 57 | of the previous pressing of the joystick 58 | controller. 59 | */ 60 | Move previousMove = Move::NOT; 61 | 62 | public: 63 | /** 64 | Constructor 65 | 66 | @param SW_pin - a digital port pin of a button. 67 | @param VRx_pin - a analog port pin of X-axis. 68 | @param VRy_pin - a analog port pin of Y-axis. 69 | */ 70 | AxisJoystick(int SW_pin, int VRx_pin, int VRy_pin); 71 | 72 | /** 73 | Single reading of the joystick controller. 74 | If the joystick is clamped, the next 75 | value of pressing - NOT. 76 | 77 | @return value of pressing the joystick (never NULL) 78 | */ 79 | Move singleRead() override; 80 | 81 | /** 82 | Multiple reading of the joystick controller. 83 | If the joystick is clamped, 84 | returns a pressed button value. 85 | 86 | @return value of pressing the joystick (never NULL): 87 | Move::PRESS - button is pressed; 88 | Move::UP - Y-axis is pressed up; 89 | Move::DOWN - Y-axis is pressed down; 90 | Move::RIGTH - X-axis is pressed right; 91 | Move::LEFT - X-axis is pressed left; 92 | Move::NOT - not pressed. 93 | */ 94 | Move multipleRead() override; 95 | 96 | /** 97 | Checks if the joystick button is pressed. 98 | 99 | @return true - button is pressed, 100 | false - button is not pressed. 101 | */ 102 | boolean isPress() override; 103 | 104 | /** 105 | Checks if the joystick is pressed up (Y-axis). 106 | 107 | @return true - joystick is pressed up, 108 | false - joystick is not pressed. 109 | */ 110 | boolean isUp() override; 111 | 112 | /** 113 | Checks if the joystick is pressed down (Y-axis). 114 | 115 | @return true - joystick is pressed down, 116 | false - joystick is not pressed. 117 | */ 118 | boolean isDown() override; 119 | 120 | /** 121 | Checks if the joystick is pressed right (X-axis). 122 | 123 | @return true - joystick is pressed right, 124 | false - joystick is not pressed. 125 | */ 126 | boolean isRight() override; 127 | 128 | /** 129 | Checks if the joystick is pressed left (X-axis). 130 | 131 | @return true - joystick is pressed left, 132 | false - joystick is not pressed. 133 | */ 134 | boolean isLeft() override; 135 | 136 | /** 137 | Reads the joystick X-axis coordinate. 138 | 139 | @return X-axis coordinate. 140 | */ 141 | int xAxis() override; 142 | 143 | /** 144 | Reads the joystick Y-axis coordinate. 145 | 146 | @return Y-axis coordinate. 147 | */ 148 | int yAxis() override; 149 | 150 | /** 151 | Reads the VRx pin value. 152 | 153 | @return VRx value. 154 | */ 155 | int readVRx() override; 156 | 157 | /** 158 | Reads the VRy pin value. 159 | 160 | @return VRy value. 161 | */ 162 | int readVRy() override; 163 | 164 | /** 165 | Reads the SW pin value. 166 | 167 | @return SW value. 168 | */ 169 | int readSW() override; 170 | 171 | /** 172 | Joystick axes calibration. 173 | 174 | @param low - the lower bound of the values range (default, 100); 175 | @param high - the upper bound of the values range (default, 923); 176 | */ 177 | void calibrate(int low, int high) override; 178 | 179 | /** 180 | Joystick axes calibration. 181 | 182 | @param adcMin - min value of the board ADC (default for Arduino, 0); 183 | @param adcMax - max value of the board ADC (default for Arduino, 1023); 184 | @param deviation - deviation from the value’s axis range (default, 100), 185 | when the axis is considered activated: 186 | axis value <= (low + deviation) 187 | or 188 | axis value >= (high - deviation). 189 | */ 190 | void calibrate(int adcMin, int adcMax, int deviation) override; 191 | 192 | private: 193 | inline boolean isLow(int value); 194 | 195 | inline boolean isHigh(int value); 196 | }; 197 | 198 | #endif 199 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Axis Joystick Library 2 | 3 | For Arduino ant STM32 boards. 4 | 5 | The Library implements a set of methods for working with an axis 6 | joystick controller. 7 | Dual axis XY joystick module reading. 8 | 9 | The Analog Joystick is similar to two potentiometers connected together, 10 | one for the vertical movement (Y-axis) and other for the horizontal 11 | movement (X-axis). The joystick also comes with a button. 12 | 13 | The Arduino Uno or any other Arduino board that uses Atmega328 as 14 | the Microcontroller has ADC resolution of 10 bits. Hence the values on each 15 | analog channel can vary from 0 to 1023. 16 | The STM32 board has ADC resolution of 12 bits. Hence the values on each analog 17 | channel can vary from 0 to 4095. 18 | 19 | The home position for the stick is at (x,y:511,511, for Arduino). 20 | If the stick is moved on X axis from one end to the other, the X values will 21 | change from 0 to 1023 and similar thing happens when moved along the Y axis. 22 | On the same lines you can read position of the 23 | stick anywhere in upper half hemisphere from combination of these values. 24 | 25 | ## Installation 26 | 27 | 1. [Download](https://github.com/YuriiSalimov/AxisJoystick/releases) the Latest release from gitHub. 28 | 2. Unzip and modify the Folder name to "AxisJoystick" (Remove the '-version') 29 | 3. Paste the modified folder on your Library folder 30 | (On your `libraries` folder inside Sketchbooks or Arduino software). 31 | 4. Restart the Arduino IDE. 32 | 33 | ## Circuit Diagram 34 | 35 | ![Circuit Diagram](CircuitDiagram.png) 36 | 37 | ## Methods 38 | 39 | ```cpp 40 | /** 41 | SW - a digital port number of a button. 42 | VRx - a analog port number of X-axis. 43 | VRy - a analog port number of Y-axis. 44 | */ 45 | AxisJoystick joystick(SW, VRx, VRy); 46 | 47 | /** 48 | Enums of a possible pressings 49 | of the joystick controller: 50 | PRESS - button is pressed; 51 | UP - Y-axis is pressed up; 52 | DOWN - Y-axis is pressed down; 53 | RIGTH - X-axis is pressed right; 54 | LEFT - X-axis is pressed left; 55 | NOT - otherwise. 56 | */ 57 | enum Move { 58 | PRESS, UP, DOWN, RIGHT, LEFT, NOT 59 | }; 60 | 61 | /** 62 | Single reading of the joystick controller. 63 | If the joystick is clamped, the next 64 | value of pressing - NOT. 65 | Return value of pressing the joystick: 66 | Move::PRESS - button is pressed; 67 | Move::UP - Y-axis is pressed up; 68 | Move::DOWN - Y-axis is pressed down; 69 | Move::RIGTH - X-axis is pressed right; 70 | Move::LEFT - X-axis is pressed left; 71 | Move::NOT - otherwise. 72 | */ 73 | joystick.singleRead(); 74 | 75 | /** 76 | Multiple reading of the joystick controller. 77 | If the joystick is clamped, 78 | returns a pressed button value. 79 | Return value of pressing the joystick: 80 | Move::PRESS - button is pressed; 81 | Move::UP - Y-axis is pressed up; 82 | Move::DOWN - Y-axis is pressed down; 83 | Move::RIGTH - X-axis is pressed right; 84 | Move::LEFT - X-axis is pressed left; 85 | Move::NOT - otherwise. 86 | */ 87 | joystick.multipleRead(); 88 | 89 | /** 90 | Checks if the joystick button is pressed. 91 | Return true - button is pressed, 92 | false - button is not pressed. 93 | */ 94 | joystick.isPress(); 95 | 96 | /** 97 | Checks if the joystick is pressed up (Y-axis). 98 | Return true - joystick is pressed up, 99 | false - joystick is not pressed. 100 | */ 101 | joystick.isUp(); 102 | 103 | /** 104 | Checks if the joystick is pressed down (Y-axis). 105 | Return true - joystick is pressed down, 106 | false - joystick is not pressed. 107 | */ 108 | joystick.isDown(); 109 | 110 | /** 111 | Checks if the joystick is pressed right (X-axis). 112 | Return true - joystick is pressed right, 113 | false - joystick is not pressed. 114 | */ 115 | joystick.isRight(); 116 | 117 | /** 118 | Checks if the joystick is pressed left (X-axis). 119 | Return true - joystick is pressed left, 120 | false - joystick is not pressed. 121 | */ 122 | joystick.isLeft(); 123 | 124 | // Returns the joystick X axis coordinate (VRx). 125 | joystick.xAxis(); 126 | 127 | // Returns the joystick Y axis coordinate (VRy). 128 | joystick.yAxis(); 129 | 130 | /** 131 | Joystick axes calibration. 132 | LOW - the lower bound of the values range (default, 0); 133 | HIGH - the upper bound of the values range (default, 1023); 134 | */ 135 | joystick.calibrate(LOW, HIGH); 136 | 137 | /** 138 | Joystick axes calibration. 139 | LOW - the lower bound of the values range (default, 0); 140 | HIGH - the upper bound of the values range (default, 1023); 141 | DEVIATION - deviation from the value’s axis range (default, 100), 142 | when the axis is considered activated: 143 | axis value <= (LOW + DEVIATION) 144 | or 145 | axis value >= (HIGH - DEVIATION). 146 | */ 147 | joystick.calibrate(LOW, HIGH, DEVIATION); 148 | ``` 149 | 150 | ### Examples 151 | 152 | [Single reading...](/examples/SingleReading/SingleReading.ino) 153 | 154 | [Multiple reading...](/examples/MultipleReading/MultipleReading.ino) 155 | 156 | [How to calibrate axes...](/examples/CalibrateJoystick/CalibrateJoystick.ino) 157 | 158 | [How to invert axis...](/examples/InvertAxis/InvertAxis.ino) 159 | 160 | [How to replace axes...](/examples/ReplaceXY/ReplaceXY.ino) 161 | 162 | [STM32...](/examples/STM32/STM32.ino) 163 | 164 | [All examples](/examples)... 165 | 166 | Created by Yurii Salimov. 167 | --------------------------------------------------------------------------------