// include the joystick and keyboard library #include #include // Create the Joystick object Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK, 32, 0, true, true, false, false, false, false, false, false, false, false, false); //declare the pin number for each button, switch, encoder... //declare understandable var to recognise button in the code, const int SwitchButton1 = 2; const int SwitchButton2 = 3; const int SwitchButton3 = 53; const int SwitchButton4 = 51; const int SwitchButton5 = 50; const int NCButton = 7; const int Button1 = 8; const int Button2 = 9; const int Button3 = 10; const int Button4 = 11; const int Button5 = 12; const int Button6 = 13; const int Button7 = 14; const int Button8 = 15; const int Button9 = 16; const int Button10 = 17; const int threeWay1A = 18; const int threeWay1B = 19; const int threeWay2A = 20; const int threeWay2B = 21; const int threeWay3A = 24; const int threeWay3B = 25; const int rotaryEncoder1A = 31; const int rotaryEncoder1B = 32; const int rotaryEncoder1Button = 26; const int rotaryEncoder2A = 33; const int rotaryEncoder2B = 34; const int rotaryEncoder2Button = 27; const int rotaryEncoder3A = 35; const int rotaryEncoder3B = 36; const int rotaryEncoder3Button = 28; const int rotaryEncoder4A = 37; const int rotaryEncoder4B = 38; const int rotaryEncoder4Button = 29; const int rotaryEncoder5A = 39; const int rotaryEncoder5B = 40; const int rotaryEncoder5Button = 30; const int joystickX = A0; const int joystickY = A1; const int joystickButton = 49; char ctrlKey = KEY_LEFT_CTRL; //array to store the last status of the button //TODO: improve the "32" and only declare the required ammount int lastButtonStatus[32]; //variable needed for the rotary encoders int counter[5]; bool aState[5] ; bool aLastState[5] ; long unsigned aTime[5] ; //funtion that will be run only once to init the arduino void setup() { //initialise the pin mode of the buttons, switches, rotary encoders pinMode(SwitchButton1, INPUT); pinMode(SwitchButton2, INPUT); pinMode(SwitchButton3, INPUT); pinMode(SwitchButton4, INPUT); pinMode(SwitchButton5, INPUT); pinMode(NCButton, INPUT_PULLUP); pinMode(Button1, INPUT_PULLUP); pinMode(Button2, INPUT_PULLUP); pinMode(Button3, INPUT_PULLUP); pinMode(Button4, INPUT_PULLUP); pinMode(Button5, INPUT_PULLUP); pinMode(Button6, INPUT_PULLUP); pinMode(Button7, INPUT_PULLUP); pinMode(Button8, INPUT_PULLUP); pinMode(Button9, INPUT_PULLUP); pinMode(Button10, INPUT_PULLUP); pinMode(threeWay1A, INPUT); pinMode(threeWay1B, INPUT); pinMode(threeWay2A, INPUT); pinMode(threeWay2B, INPUT); pinMode(threeWay3A, INPUT); pinMode(threeWay3B, INPUT); pinMode(rotaryEncoder1A, INPUT_PULLUP); pinMode(rotaryEncoder1B, INPUT_PULLUP); pinMode(rotaryEncoder1Button, INPUT_PULLUP); aLastState[0] = digitalRead(rotaryEncoder1A); aTime[0] = millis(); counter[0] = 0; pinMode(rotaryEncoder2A, INPUT_PULLUP); pinMode(rotaryEncoder2B, INPUT_PULLUP); pinMode(rotaryEncoder2Button, INPUT_PULLUP); aLastState[1] = digitalRead(rotaryEncoder2A); aTime[1] = millis(); counter[1] = 0; pinMode(rotaryEncoder3A, INPUT_PULLUP); pinMode(rotaryEncoder3B, INPUT_PULLUP); pinMode(rotaryEncoder3Button, INPUT_PULLUP); aLastState[2] = digitalRead(rotaryEncoder3A); aTime[2] = millis(); counter[2] = 0; pinMode(rotaryEncoder4A, INPUT_PULLUP); pinMode(rotaryEncoder4B, INPUT_PULLUP); pinMode(rotaryEncoder4Button, INPUT_PULLUP); aLastState[3] = digitalRead(rotaryEncoder4A); aTime[3] = millis(); counter[3] = 0; pinMode(rotaryEncoder5A, INPUT_PULLUP); pinMode(rotaryEncoder5B, INPUT_PULLUP); pinMode(rotaryEncoder5Button, INPUT_PULLUP); aLastState[5] = digitalRead(rotaryEncoder5A); aTime[5] = millis(); counter[5] = 0; pinMode(joystickX, INPUT_PULLUP); pinMode(joystickY, INPUT_PULLUP); pinMode(joystickButton, INPUT_PULLUP); for (int i = 0 ; i < 31 ; i++) { lastButtonStatus[i] = HIGH; } Joystick.begin(); } //function that will be executed again and again and again... void loop() { //call the function for each type of input switchCheck(SwitchButton1, 'a'); switchCheck(SwitchButton2, 'z'); switchCheck(SwitchButton3, 'e'); switchCheck(SwitchButton4, 'r'); switchCheck(SwitchButton5, 't'); ButtonCheckNC(NCButton, 'y'); ButtonCheck(Button1, 'u'); ButtonCheck(Button2, 'i'); ButtonCheck(Button3, 'o'); ButtonCheck(Button4, 'p'); ButtonCheck(Button5, 'q'); ButtonCheck(Button6, 's'); ButtonCheck(Button7, 'd'); ButtonCheck(Button8, 'f'); ButtonCheck(Button9, 'g'); ButtonCheck(Button10, 'h'); ButtonCheck(threeWay1A, 'j'); ButtonCheck(threeWay1B, 'k'); ButtonCheck(threeWay2A, 'l'); ButtonCheck(threeWay2B, 'm'); ButtonCheck(threeWay3A, 'w'); ButtonCheck(threeWay3B, 'x'); ButtonCheck(rotaryEncoder1Button, 'c'); ButtonCheck(rotaryEncoder2Button, 'v'); ButtonCheck(rotaryEncoder3Button, 'b'); ButtonCheck(rotaryEncoder4Button, 'n'); ButtonCheck(rotaryEncoder5Button, ','); rotaryEncoderChar(rotaryEncoder1A, rotaryEncoder1B , '1' , '2'); rotaryEncoderChar(rotaryEncoder2A, rotaryEncoder2B , '3' , '4'); rotaryEncoderChar(rotaryEncoder3A, rotaryEncoder3B , '5' , '6'); rotaryEncoderChar(rotaryEncoder4A, rotaryEncoder4B , '7' , '8'); rotaryEncoderChar(rotaryEncoder5A, rotaryEncoder5B , '9' , '-'); ButtonCheck(joystickButton, '*'); /* analogJoyAxisCheck(joystickX , joystickY); */ } //this function manage the analog joystick //the parameters are // joyX => the pin number of the X axis of the analog joystick // joyY => the pin number of the Y axis of the analog joystick void analogJoyAxisCheck(int joyX , int joyY) { //initialise variable that will be needed int xMap, yMap, xValue, yValue; //initialise the range on 16bit Joystick.setXAxisRange(-32765, 32766); Joystick.setYAxisRange(-32765, 32766); //read the input value of the analog joystick x and y axis xValue = analogRead(joyX); yValue = analogRead(joyY); // after playing with the joystick and sending // value in the serial bus Serial.println(xValue); and Serial.println(yValue); // it appears that center of joystick is x:517 and y:531 // max/top y: 1023 min/bottom y :0 // max/right x: 1023 min/left x :0 //we map the scale to transform value from 0 to 1023 into something from -32765 to 32766 xMap = map(xValue, 0, 1023, -32765, 32766); yMap = map(yValue, 0, 1023, -32765, 32766); //once we have the matching coordinates, we can send it to the gamepad Joystick.setXAxis(xMap); Joystick.setYAxis(yMap); } //external function to manage switch //it takes 2 parameters //inputNb => the pin number on which the switch is plug //gamepadButtonNb => the button number of the gamepad void switchCheck(int inputNb, char gamepadButtonNb) { //read the digital input of the switch int ButtonVal = digitalRead(inputNb); //if the status is not the same as last time //it means that the user switches "off" or "on" if (ButtonVal != lastButtonStatus[inputNb]) { //don't forget to update the last status lastButtonStatus[inputNb] = ButtonVal; Keyboard.press(gamepadButtonNb); delay(300); // Keyboard.release(ctrlKey); Keyboard.release(gamepadButtonNb); } } // function that check the button state // the parameters are // inputNB => the pin nb of the button // gamepadButtonNb => which gamepad number will be pressed when rotary button is pressed void ButtonCheck(int inputNb, char gamepadButtonNb) { int ButtonVal = digitalRead(inputNb); if (ButtonVal != lastButtonStatus[inputNb]) { if (ButtonVal == LOW) { Keyboard.press(gamepadButtonNb); } else { Keyboard.release(gamepadButtonNb); } lastButtonStatus[inputNb] = ButtonVal; } } //TODO: factorise with the regular ButtonCheck function // basically the same function but the if else test is inverted due to the // naturaly closed status void ButtonCheckNC(int inputNb, char gamepadButtonNb) { int ButtonVal = digitalRead(inputNb); if (ButtonVal != lastButtonStatus[inputNb]) { if (ButtonVal == HIGH) { Keyboard.press(gamepadButtonNb); } else { Keyboard.release(gamepadButtonNb); } lastButtonStatus[inputNb] = ButtonVal; } } //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 rotaryEncoderChar(int inputA, int inputB , char gamepadButtonUpNb , char gamepadButtonDownNb) { aState[inputA] = 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[inputA] != aLastState[inputA] ) { //check time to avoid inconsistency if ( abs(millis() - aTime[inputA]) > 100 ) { // If the outputB state is different to the aLastState (itself different from aState), that means the encoder is rotating counter clockwise if (digitalRead(inputB) != aLastState[inputA]) { counter[inputA]--; //since I don't want to hold the press // I just "press" the button, wait 300ms and release the button //Keyboard.press(ctrlKey); Keyboard.press(gamepadButtonDownNb); delay(100); //Keyboard.release(ctrlKey); Keyboard.release(gamepadButtonDownNb); // Serial.print("bouton -"); } else { // else, it means that the outputB state is the same as aLastState that means the encoder is rotating clockwise //since I don't want to hold the press // I just "press" the button, wait 300ms and release the button //Keyboard.press(ctrlKey); Keyboard.press(gamepadButtonUpNb); delay(100); //Keyboard.release(ctrlKey); Keyboard.release(gamepadButtonUpNb); counter[inputA]++; } // save the time for next check aTime[inputA] = millis(); } // save the current state (that will be the next "last" state) aLastState[inputA] = aState[inputA] ; } }