//include the third party library to manage HID #include "HID-Project.h" //declare understandable var to recognise button in the code, the A pin and B pin const int rotaryEncoderA = 4; const int rotaryEncoderB = 3; const int rotaryEncoderButton = 2; //we also need to init other values int counter = 0; int lastCounter = 0; int aState; int aLastState; int lastButtonStatus[32]; void setup() { //declare the A and B pin as input pullup pinMode (rotaryEncoderA, INPUT_PULLUP); pinMode (rotaryEncoderB, INPUT_PULLUP); //initialise the A pin last state aLastState = digitalRead(rotaryEncoderA); //declare the button as an INPUT_PULLUP pinMode(rotaryEncoderButton, INPUT_PULLUP); //initialise the gamepad Gamepad.begin(); } //function that will be executed again and again and again... void loop() { //to keep the loop clean and understandable //rotary encoder management externalised to another function rotaryEncoder( rotaryEncoderA, rotaryEncoderB, 2 , 3); //Button management externalised to another function ButtonCheck(rotaryEncoderButton , 1 ); } //this function manage the rotary encoders //the parameters are // inputA => the pin number of the A side of the rotary // inputB => the pin number of the B side of the rotary // gamepadButtonUpNb => which gamepad number will be pressed when rotary going up // gamepadButtonDownNb => which gamepad number will be pressed when rotary going down void rotaryEncoder(int inputA, int inputB , int gamepadButtonUpNb , int gamepadButtonDownNb) { aState = digitalRead(inputA); // Reads the "current" state of the outputA // If the previous and the current state of the outputA are different, that means a Pulse has occured if (aState != aLastState) { // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise if (digitalRead(inputB) != aState) { counter ++; //my rotary encoder have a +2 value each step so button will be press only when even number if (counter % 2 == 0) { //since I don't want to hold the press // I just "press" the button, wait 300ms and release the button Gamepad.press(gamepadButtonUpNb); Gamepad.write(); delay(300); Gamepad.release(gamepadButtonUpNb); Gamepad.write(); } } else { // else, it means that the outputB state is the same as A that means the encoder is rotating counter clockwise counter --; //my rotary encoder have a +2 value each step so button will be press only when even number if (counter % 2 == 0) { //since I don't want to hold the press // I just "press" the button, wait 300ms and release the button Gamepad.press(gamepadButtonDownNb); Gamepad.write(); delay(300); Gamepad.release(gamepadButtonDownNb); Gamepad.write(); } } Serial.print("Position: "); Serial.println(counter); } aLastState = aState; // Updates the previous state of the outputA with the current state } // function that check the button state // the parameters are // inputNB => the pin nb of the button of the rotary encoder // gamepadButtonNb => which gamepad number will be pressed when rotary button is pressed void ButtonCheck(int inputNb, int gamepadButtonNb) { //we check and store the button status int ButtonVal = digitalRead(inputNb); // if the button state have changed, it means the user pressed or released the physical button if (ButtonVal != lastButtonStatus[inputNb]) { // if the status is LOW, it means the user pressed the physical push button // remember, the INPUT_PULLUP invert the value if (ButtonVal == LOW) { //don't forget to update the last status of the button lastButtonStatus[inputNb] = LOW; //and then we "press" the gamepad button Gamepad.press(gamepadButtonNb); Gamepad.write(); } else { // if the input is HIGH, it means the user released the physical push button //don't forget to update the last status of the button lastButtonStatus[inputNb] = HIGH; //and then we "release" the gamepad button Gamepad.release(gamepadButtonNb); Gamepad.write(); } } }