Skip to content
rotaryencoder.ino 4.12 KiB
Newer Older
//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();
    }
  }
}