1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  3. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  4. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

DIY Arduino Buttonbox

Discussion in 'DIY peripherals' started by TOPMO3, Mar 28, 2016.

  1. Antonio botas

    Antonio botas New Member

    Joined:
    Aug 30, 2016
    Messages:
    11
    Occupation:
    Tig Welder
    Location:
    lisboa
    Balance:
    - 178Coins
    Ratings:
    +22 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, Arduino, Motion platform
    Hi all,i have done also a button box,a just give a touch ,just use some magnetic stripes to do the layout for the games !a sample in the photo! IMG_20180921_094356.jpg IMG_20180921_094740.jpg IMG_20180921_094804.jpg IMG_20180921_094525.jpg
    • Like Like x 2
  2. evolaco

    evolaco Member

    Joined:
    Sep 27, 2015
    Messages:
    260
    Location:
    Spain
    Balance:
    1,070Coins
    Ratings:
    +28 / 0 / -0
    My Motion Simulator:
    3DOF
    for 8 encoder and 20 buttons I would need two arduino? Can I put a USB hub to use a single cable? No choice?
  3. Antonio botas

    Antonio botas New Member

    Joined:
    Aug 30, 2016
    Messages:
    11
    Occupation:
    Tig Welder
    Location:
    lisboa
    Balance:
    - 178Coins
    Ratings:
    +22 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, Arduino, Motion platform
    EVOLACO just check if this work for your projet with 8 encoders! 7921781a6113e0d6fd96f465037ce1c4.jpg
    • Like Like x 2
  4. evolaco

    evolaco Member

    Joined:
    Sep 27, 2015
    Messages:
    260
    Location:
    Spain
    Balance:
    1,070Coins
    Ratings:
    +28 / 0 / -0
    My Motion Simulator:
    3DOF
    How many buttons and encoder can you use in total? Is there more information and the sketch?
    • Like Like x 1
  5. Antonio botas

    Antonio botas New Member

    Joined:
    Aug 30, 2016
    Messages:
    11
    Occupation:
    Tig Welder
    Location:
    lisboa
    Balance:
    - 178Coins
    Ratings:
    +22 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, Arduino, Motion platform
    i think you can put 96 butons and 8 encoderes( butons =coluns x lines)12x8=96 for more info check mmjoy2 software(it works plug and play)if you need more than 8 encoders you can connect also encoders to the matrix keyboard (colunsxlines=matrix)
    • Like Like x 2
    • Informative Informative x 1
  6. Henrik

    Henrik New Member Gold Contributor

    Joined:
    Aug 13, 2017
    Messages:
    18
    Location:
    Sverige
    Balance:
    104Coins
    Ratings:
    +15 / 0 / -0
    Hi Jon!
    I am very sorry for the late reply (i did not get an update mail, must have mest it up some how)

    I have connected the rotaries the same way as you, but i am using this code in the beginning.
    I hope this will help you, if you haven't solved it already.
    If you haven't and this wont help i will keep looking and compering code.



    rotariesdef rotaries[NUMROTARIES] {
    {0,1,26,27,0},
    {2,3,28,29,0},
    {4,5,30,31,0},
    {6,7,22,23,0},
    {8,9,24,25,0},

    • Like Like x 2
  7. HamptonRoader

    HamptonRoader New Member

    Joined:
    Oct 25, 2018
    Messages:
    1
    Balance:
    154Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    Arduino
    I just signed up to say thank you for this - I have learned a ton about arduino from this and other posts.

    Maybe my struggle will help some one else. I was having a hell of a time with my rotary encoder + push button with 5 pins. I did not need the VCC pin for mine, so I wired the 3 encoder pins as shown in the diagram in this thread (pin1, pin2, ground), and then the 1 button pin to any open pin on the arduino board. I coded the push buttons separate from the grid buttons since i was not sure how to include in the grid on a single wire.

    The big problem i was having, not sure if it's due to my cheap encoders or not, but when turning the encoder, occasionally the rotary push button would fire even though it was not being pressed. So after trying all types of garbage, I incorporated a delay after the rotary encoders are used so the push button is disabled for a short time, and this stopped all arbitrary push button firings.

    This is far from properly coded (lots of single variables where arrays should be used, rookie Arduino user, etc) but it may help someone stuck that is just trying to get a project working. I noted all my changes with comments so no one will mistake my butchery for the original authors sketch, potentially ruining his reputation lol!

    Code:
    //Simple buttonbox sketch
    //Supports up to 25 buttons and up to 4 encoders
    //version 0.2 by TOPMO3
    //
    //
    //Arduino IDE 1.6.6 (or above) !
    //
    //Joystick library from  Matthew Heironimus, https://github.com/MHeironimus/ArduinoJoystickLibrary
    //
    //Encoders code from Ben Buxton
    //More info: http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
    //
    //Thank you guys! :)
    //
    // Butchered hackjob additions by Nino Scholz (all the disableflag stuff and the rotarybutton additions)
    
    //Uncomment this for HALFSTEP encoder operation
    #define HALF_STEP
    
    #include <Keypad.h>
    #include <Joystick.h>
    
    #define NUMROTARIES 3
    #define ENABLE_PULLUPS
    #define NUMBUTTONS 5
    #define NUMROWS 1
    #define NUMCOLS 5
    
    // ** Butchered hackjob additions initialization
    #define ROTARYBUTTONDELAY 100 // time period after encoder activation that rotary push button is disabled to prevent misfire
    const int buttonPin1 = 9;     // the number of the pushbutton1 pin
    int buttonState1 = 0;         // variable for reading the pushbutton1 status
    const int buttonPin2 = 10;    // the number of the pushbutton2 pin
    int buttonState2 = 0;         // variable for reading the pushbutton2 status
    const int buttonPin3 = 16;    // the number of the pushbutton3 pin
    int buttonState3 = 0;         // variable for reading the pushbutton3 status
    int disableFlag = 0;          // flag to tell the rotarybutton not to fire, since the encoder was sometimes arbitrarily activating it.
    int disableCounter = 0;       // counter that resets at #define ROTARYBUTTONDELAY 100
    // END Butchered hackjob additions initialization
    
    // 1x5 normal button grid
    //define the symbols on the buttons of the keypads
    byte buttons[NUMROWS][NUMCOLS] = {
      {1,2,3,4,5},
    };;
    
    
    struct rotariesdef {
      byte pin1;
      byte pin2;
      int ccwchar;
      int cwchar;
      volatile unsigned char state;
    };
    
    // only 3 encoders on my box. [pin1,pin2,joyoutput1,joyoutput2,??)
    rotariesdef rotaries[NUMROTARIES] {
      {0,1,20,21,0},
      {2,3,23,24,0},
      {4,5,26,27,0}, 
    };
    
    #define DIR_CCW 0x10
    #define DIR_CW 0x20
    #define R_START 0x0
    
    #ifdef HALF_STEP
    // Use the half-step state table (emits a code at 00 and 11)
    #define R_CCW_BEGIN 0x1
    #define R_CW_BEGIN 0x2
    #define R_START_M 0x3
    #define R_CW_BEGIN_M 0x4
    #define R_CCW_BEGIN_M 0x5
    const unsigned char ttable[6][4] = {
      // R_START (00)
      {R_START_M,            R_CW_BEGIN,     R_CCW_BEGIN,  R_START},
      // R_CCW_BEGIN
      {R_START_M | DIR_CCW, R_START,        R_CCW_BEGIN,  R_START},
      // R_CW_BEGIN
      {R_START_M | DIR_CW,  R_CW_BEGIN,     R_START,      R_START},
      // R_START_M (11)
      {R_START_M,            R_CCW_BEGIN_M,  R_CW_BEGIN_M, R_START},
      // R_CW_BEGIN_M
      {R_START_M,            R_START_M,      R_CW_BEGIN_M, R_START | DIR_CW},
      // R_CCW_BEGIN_M
      {R_START_M,            R_CCW_BEGIN_M,  R_START_M,    R_START | DIR_CCW},
    };
    #else
    // Use the full-step state table (emits a code at 00 only)
    #define R_CW_FINAL 0x1
    #define R_CW_BEGIN 0x2
    #define R_CW_NEXT 0x3
    #define R_CCW_BEGIN 0x4
    #define R_CCW_FINAL 0x5
    #define R_CCW_NEXT 0x6
    
    const unsigned char ttable[7][4] = {
      // R_START
      {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
      // R_CW_FINAL
      {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
      // R_CW_BEGIN
      {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
      // R_CW_NEXT
      {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
      // R_CCW_BEGIN
      {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
      // R_CCW_FINAL
      {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
      // R_CCW_NEXT
      {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
    };
    #endif
    
    
    byte rowPins[NUMROWS] = {21}; //connect to the row pinouts of the keypad
    byte colPins[NUMCOLS] = {20,19,18,15,14}; //connect to the column pinouts of the keypad
    
    //initialize an instance of class NewKeypad
    Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);
    
    //initialize an Joystick with 34 buttons;
    Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
      JOYSTICK_TYPE_JOYSTICK, 34, 0,
      false, false, false, false, false, false,
      false, false, false, false, false);
    
    
    void setup() {
      Joystick.begin();
      rotary_init();
      rotaryButton_init();
    }
    
    /* Call this once in setup(). */
    void rotaryButton_init() {
     
       // initialize the pushbutton pin as an input:
       pinMode(buttonPin1, INPUT_PULLUP);       
       pinMode(buttonPin2, INPUT_PULLUP);       
       pinMode(buttonPin3, INPUT_PULLUP);       
     
      }
    
    
    void loop() {
    
      // ** butchered hack job addition
      disableCounter++; // increment the delay counter for rotarybutton inactive timeframe
      if (disableCounter > ROTARYBUTTONDELAY) { disableCounter = 0; disableFlag = 0; }; // if enough time has passed, allow rotary buttons to work again
      // END butchered hackjob addition
     
      CheckAllEncoders();
      CheckAllButtons();
    } 
    
    
    void CheckAllButtons(void) {
          if (buttbx.getKeys())
        {
           for (int i=0; i<LIST_MAX; i++)   // Scan the whole key list.
            {
               if ( buttbx.key[i].stateChanged )   // Only find keys that have changed state.
                {
                switch (buttbx.key[i].kstate) {  // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
                        case PRESSED:
                        case HOLD:
                                  Joystick.setButton(buttbx.key[i].kchar, 1);                             
                                  break;
                        case RELEASED:
                        case IDLE:
                                  Joystick.setButton(buttbx.key[i].kchar, 0);                             
                                  break;
                }
               }   
             }
         }
    }
    
    
    /* Call this once in setup(). */
    void rotary_init() {
      for (int i=0;i<NUMROTARIES;i++) {   
        pinMode(rotaries[i].pin1, INPUT);
        pinMode(rotaries[i].pin2, INPUT);
        #ifdef ENABLE_PULLUPS
          digitalWrite(rotaries[i].pin1, HIGH);
          digitalWrite(rotaries[i].pin2, HIGH);
        #endif
      }
    }
    
    
    /* Read input pins and process for events. Call this either from a
     * loop or an interrupt (eg pin change or timer).
     *
     * Returns 0 on no event, otherwise 0x80 or 0x40 depending on the direction.
     */
    unsigned char rotary_process(int _i) {
       unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
      rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
      return (rotaries[_i].state & 0x30);
    }
    
    void CheckAllEncoders(void) {
      for (int i=0;i<NUMROTARIES;i++) {
        unsigned char result = rotary_process(i);
        if (result == DIR_CCW) {
          Joystick.setButton(rotaries[i].ccwchar, 1); delay(100); Joystick.setButton(rotaries[i].ccwchar, 0);
           // Butchered hackjob addition
           disableFlag = 1; // disable the rotary pushbuttons to prevent misfires during encoder use
           disableCounter = 0; // reset the timer     
           // end Butchered hackjob addition
        };
        if (result == DIR_CW) {
          Joystick.setButton(rotaries[i].cwchar, 1); delay(100); Joystick.setButton(rotaries[i].cwchar, 0);
          // Butchered hackjob addition
          disableFlag = 1;  // disable the rotary pushbuttons to prevent misfires during encoder use
          disableCounter = 0;  // reset the timer         
          // Butchered hackjob addition
        };
      }
    
     // *** Butchered hackjob addition check the push buttons on encoders
     buttonState1 = digitalRead(buttonPin1);
     buttonState2 = digitalRead(buttonPin2);
     buttonState3 = digitalRead(buttonPin3);
    
     // check if the pushbutton is pressed. Should set up constants for 22,25,28 - they are the joystick output buttons
     // if it is, the buttonState is HIGH:
     if (buttonState1 == LOW && disableFlag == 0) {     
       // turn LED on:   
       Joystick.setButton(22, 1);   
       return;;
     }
     else {
       Joystick.setButton(22, 0);   
     }
    
     if (buttonState2 == LOW && disableFlag == 0) {     
       // turn LED on:   
       Joystick.setButton(25, 1);   
       return;;
     }
     else {
       Joystick.setButton(25, 0);   
     }
    
     if (buttonState3 == LOW && disableFlag == 0) {     
       // turn LED on:   
       Joystick.setButton(28, 1);   
       return;;
     }
     else {
       Joystick.setButton(28, 0);   
     }
    }
    // END Butchered hackjob addition check the push buttons on encoders
  8. Nico de Graaff

    Nico de Graaff New Member

    Joined:
    Nov 3, 2018
    Messages:
    2
    Balance:
    198Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    Arduino
    I don't know anything about the Arduino language (yet), but I've build this box and it's all working. The only thing is when I push a button repeatedly the output is different all the time. One time it's CTRL+E, another time ALT+E and ofcourse CTRL+ALT+E. Can I do something about it? BTW I use QiPress to check this. Thanks for your help. I'm use the keyboard script!
  9. JonBakhol

    JonBakhol Active Member

    Joined:
    Mar 16, 2018
    Messages:
    107
    Location:
    Netherlands harderwijk
    Balance:
    462Coins
    Ratings:
    +46 / 1 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    Hi @Henrik ,

    Just want to let you know that the encoders and all buttons are working fine.
    Thanks for your reply.

    Grts Jon
  10. Nico de Graaff

    Nico de Graaff New Member

    Joined:
    Nov 3, 2018
    Messages:
    2
    Balance:
    198Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    Arduino
    Hi. Only three decoders are working for the joystick version (2d). If I download the joystick library I see only joystick there, not joystick 2 & 3.
  11. KARTUXO

    KARTUXO New Member

    Joined:
    Jan 9, 2019
    Messages:
    2
    Balance:
    167Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    Arduino
    Hello everyone, do not program arduino, but thanks to these posts I have started an online course.
    I appreciate the work and the contribution of all, of which I have learned a lot
    but I find an error when compiling ... can someone tell me how to solve it ?? ... thanks to everyone.
    using google translator sorry!

    Attached Files:

  12. KARTUXO

    KARTUXO New Member

    Joined:
    Jan 9, 2019
    Messages:
    2
    Balance:
    167Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    Arduino
    sorry !! ... here the error capture

    upload_2019-1-9_18-54-51.png

    Attached Files:

  13. phildo012

    phildo012 New Member

    Joined:
    Oct 15, 2017
    Messages:
    2
    Location:
    New Zealand
    Balance:
    179Coins
    Ratings:
    +0 / 0 / -0
    Hi I am getting this error when trying to upload.

    C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Phil\Documents\Arduino\libraries -fqbn=arduino:avr:micro -vid-pid=0X2341_0X8037 -ide-version=10805 -build-path C:\Users\Phil\AppData\Local\Temp\arduino_build_644963 -warnings=none -build-cache C:\Users\Phil\AppData\Local\Temp\arduino_cache_740029 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\Phil\Documents\Arduino\buttsimpjoy_02d\buttsimpjoy_02d.ino
    C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Phil\Documents\Arduino\libraries -fqbn=arduino:avr:micro -vid-pid=0X2341_0X8037 -ide-version=10805 -build-path C:\Users\Phil\AppData\Local\Temp\arduino_build_644963 -warnings=none -build-cache C:\Users\Phil\AppData\Local\Temp\arduino_cache_740029 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\Phil\Documents\Arduino\buttsimpjoy_02d\buttsimpjoy_02d.ino
    Using board 'micro' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
    Using core 'arduino' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
    Build options changed, rebuilding all
    Detecting libraries used...
    "C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_MICRO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8037 '-DUSB_MANUFACTURER="Unknown"' '-DUSB_PRODUCT="Arduino Micro"' "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\micro" "C:\Users\Phil\AppData\Local\Temp\arduino_build_644963\sketch\buttsimpjoy_02d.ino.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_MICRO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8037 '-DUSB_MANUFACTURER="Unknown"' '-DUSB_PRODUCT="Arduino Micro"' "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\micro" "C:\Users\Phil\AppData\Local\Temp\arduino_build_644963\sketch\buttsimpjoy_02d.ino.cpp" -o "C:\Users\Phil\AppData\Local\Temp\arduino_build_644963\preproc\ctags_target_for_gcc_minus_e.cpp"
    C:\Users\Phil\Documents\Arduino\buttsimpjoy_02d\buttsimpjoy_02d.ino:21:20: fatal error: Keypad.h: No such file or directory

    #include <Keypad.h>

    ^

    compilation terminated.

    exit status 1
    Error compiling for board Arduino/Genuino Micro.
  14. phildo012

    phildo012 New Member

    Joined:
    Oct 15, 2017
    Messages:
    2
    Location:
    New Zealand
    Balance:
    179Coins
    Ratings:
    +0 / 0 / -0
    Sorry newbie here. but got it sorted
  15. Emilio Lopez

    Emilio Lopez New Member

    Joined:
    Feb 12, 2019
    Messages:
    1
    Balance:
    161Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    Arduino
    Hello
    I am testing the code for five rotary and I have a problem. Compiling correctly, I upload the program without failures, and testing the two arrays that have been published, the fifth rotary only manages to activate the button 25 in one direction. The other four rotary if they work correctly. I leave the code here in case someone could help me, thank you.

    Code:
    //BUTTON BOX
    //USE w ProMicro
    //Tested in WIN10 + Assetto Corsa
    //AMSTUDIO
    //20.8.17
    
    #include <Keypad.h>
    #include <Joystick.h>
    
    #define ENABLE_PULLUPS
    #define NUMROTARIES 5
    #define NUMBUTTONS 16
    #define NUMROWS 4
    #define NUMCOLS 4
    
    
    byte buttons[NUMROWS][NUMCOLS] = {
      {0,1,2,3},
      {4,5,6,7},
      {8,9,10,11},
      {12,13,14,15},
     
    };
    
    struct rotariesdef {
      byte pin1;
      byte pin2;
      int ccwchar;
      int cwchar;
      volatile unsigned char state;
    };
    
    rotariesdef rotaries[NUMROTARIES] {
      {0,1,16,17,0},
      {2,3,18,19,0},
      {4,5,20,21,0},
      {6,7,22,23,0},
      {8,9,24,25,0},
    };
    
    /*rotariesdef rotaries[NUMROTARIES] {
    {0,1,24,25,0},
    {2,3,28,29,0},
    {4,5,30,31,0},
    {6,7,22,23,0},
    {8,9,26,27,0},
    };*/
    
    #define DIR_CCW 0x10
    #define DIR_CW 0x20
    #define R_START 0x0
    
    #ifdef HALF_STEP
    #define R_CCW_BEGIN 0x1
    #define R_CW_BEGIN 0x2
    #define R_START_M 0x3
    #define R_CW_BEGIN_M 0x4
    #define R_CCW_BEGIN_M 0x5
    const unsigned char ttable[6][4] = {
      // R_START (00)
      {R_START_M,            R_CW_BEGIN,     R_CCW_BEGIN,  R_START},
      // R_CCW_BEGIN
      {R_START_M | DIR_CCW, R_START,        R_CCW_BEGIN,  R_START},
      // R_CW_BEGIN
      {R_START_M | DIR_CW,  R_CW_BEGIN,     R_START,      R_START},
      // R_START_M (11)
      {R_START_M,            R_CCW_BEGIN_M,  R_CW_BEGIN_M, R_START},
      // R_CW_BEGIN_M
      {R_START_M,            R_START_M,      R_CW_BEGIN_M, R_START | DIR_CW},
      // R_CCW_BEGIN_M
      {R_START_M,            R_CCW_BEGIN_M,  R_START_M,    R_START | DIR_CCW},
    };
    #else
    #define R_CW_FINAL 0x1
    #define R_CW_BEGIN 0x2
    #define R_CW_NEXT 0x3
    #define R_CCW_BEGIN 0x4
    #define R_CCW_FINAL 0x5
    #define R_CCW_NEXT 0x6
    
    const unsigned char ttable[7][4] = {
      // R_START
      {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
      // R_CW_FINAL
      {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
      // R_CW_BEGIN
      {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
      // R_CW_NEXT
      {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
      // R_CCW_BEGIN
      {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
      // R_CCW_FINAL
      {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
      // R_CCW_NEXT
      {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
    };
    #endif
    
    byte rowPins[NUMROWS] = {21,20,19,18};
    byte colPins[NUMCOLS] = {15,14,16,10};
    
    Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);
    
    Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
      JOYSTICK_TYPE_JOYSTICK, 25, 0,
      false, false, false, false, false, false,
      false, false, false, false, false);
    
    void setup() {
      Joystick.begin();
      rotary_init();}
    
    void loop() {
    
      CheckAllEncoders();
    
      CheckAllButtons();
    
    }
    
    void CheckAllButtons(void) {
          if (buttbx.getKeys())
        {
           for (int i=0; i<LIST_MAX; i++)   
            {
               if ( buttbx.key[i].stateChanged )   
                {
                switch (buttbx.key[i].kstate) {
                        case PRESSED:
                        case HOLD:
                                  Joystick.setButton(buttbx.key[i].kchar, 1);
                                  break;
                        case RELEASED:
                        case IDLE:
                                  Joystick.setButton(buttbx.key[i].kchar, 0);
                                  break;
                }
               }   
             }
         }
    }
    
    
    void rotary_init() {
      for (int i=0;i<NUMROTARIES;i++) {
        pinMode(rotaries[i].pin1, INPUT);
        pinMode(rotaries[i].pin2, INPUT);
        #ifdef ENABLE_PULLUPS
          digitalWrite(rotaries[i].pin1, HIGH);
          digitalWrite(rotaries[i].pin2, HIGH);
        #endif
      }
    }
    
    
    unsigned char rotary_process(int _i) {
       unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
      rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
      return (rotaries[_i].state & 0x30);
    }
    
    void CheckAllEncoders(void) {
      for (int i=0;i<NUMROTARIES;i++) {
        unsigned char result = rotary_process(i);
        if (result == DIR_CCW) {
          Joystick.setButton(rotaries[i].ccwchar, 1); delay(50); Joystick.setButton(rotaries[i].ccwchar, 0);
        };
        if (result == DIR_CW) {
          Joystick.setButton(rotaries[i].cwchar, 1); delay(50); Joystick.setButton(rotaries[i].cwchar, 0);
        };
      }
    }
  16. Snowracer

    Snowracer New Member

    Joined:
    Feb 16, 2019
    Messages:
    3
    Balance:
    23Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    DC motor, Arduino
    Hello and thank you topmo3 for making open source files! I have KY-040 rotary encoders(built in 10k resistors) and am using butsimjoy02d file. Simple momentary buttons work and 3 of 4 rotary encoders read cw/ccw. However I have two problems.
    1. The rotary encoders push buttons show a series of button pushes instead of one when using win 10 game controller settings. Ex 22,23,24,25,26 will highlight red instead of just one number when pressing the rotary button.
    2. The Pins 6 and 7 on the promicro do not work on my rotary encoder? I have tried the other buttsimjoy files and have the same problem.
    Thank you for any help in fixing these issues.
  17. Luis.Uet

    Luis.Uet New Member

    Joined:
    Apr 27, 2019
    Messages:
    2
    Balance:
    25Coins
    Ratings:
    +2 / 0 / -0
    My Motion Simulator:
    Arduino
    Hello guys,
    I built my own ButtonBox yesterday...
    I have got 4 toggle-switches with two way activation (on) and a springreturn to the middle (off).
    And 8 normal push-buttons.
    All this is connected to an normal Arduino Pro Micro...

    Now I want to know if I even wired it up correct?
    And which Arduino sketch I have to use?
    Because I didn't get it running on my own.:sos

    If I use the first sketch, I can upload it without any problems but the buttons won't work. (Some of them work sometimes?!)
    If I use the newer ones I will have different errors. (expected unqualified-id before '.' token or 'xyz' does not name a type)

    I have downloadet many librarys. (keypad, keyboard, joystick...)

    What do I have to do now?


    Cheers

    Luis

    Attached Files:

    • Like Like x 1
  18. Luis.Uet

    Luis.Uet New Member

    Joined:
    Apr 27, 2019
    Messages:
    2
    Balance:
    25Coins
    Ratings:
    +2 / 0 / -0
    My Motion Simulator:
    Arduino
    Hey Guys,
    I got it all sortet now...:thumbs

    But how do I set up the sketch for 8 buttons and 4 toggle switches?:think
    (They got 2 ways and return to off.)

    Cheers,
    Luis
    • Like Like x 1
  19. Danilo Santos

    Danilo Santos New Member

    Joined:
    Jul 26, 2019
    Messages:
    4
    Balance:
    21Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    Arduino
    Could someone help me? I'm making a button box can call 24 buttons. But how can I use the potentiometer in the same function as the encoders. I don't know how to connect the 3 pin arduino pro
    [​IMG]
  20. JonBakhol

    JonBakhol Active Member

    Joined:
    Mar 16, 2018
    Messages:
    107
    Location:
    Netherlands harderwijk
    Balance:
    462Coins
    Ratings:
    +46 / 1 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    Hi Danilo,

    I made an F1 steering wheel with buttons, encoders and potentiometer.
    I attached the Arduino code. Maybe it will help you.

    Ride on

    Attached Files:

    • Like Like x 1
    • Useful Useful x 1
    Last edited: Jul 26, 2019