Program freezes after rotating encoder too many times

Hey everyone,

I wrote a small program to control buttons and encoders on a switch box. All the switches work fine and without issues, but whenever I rotate any encoder too many times the program freezes. I'm using both single and dual encoders with push buttons. Any help would be greatly appreciated.

Here is my code:

#include <Bounce.h>
#include <elapsedMillis.h>
#include <Rotary.h>
#include <usb_joystick.h>


Bounce button_12 = Bounce(12, 10);
Bounce button_13 = Bounce(13, 10);  // 10 = 10 ms debounce time
Bounce button_14 = Bounce(14, 10);  // which is appropriate for
Bounce button_15 = Bounce(15, 10);  // most mechanical pushbuttons
Bounce button_16 = Bounce(16, 10);
Bounce button_17 = Bounce(17, 10);
Bounce button_18 = Bounce(18, 10);
Bounce button_19 = Bounce(19, 10);
Bounce button_20 = Bounce(20, 10);
Bounce button_21 = Bounce(21, 10);
Bounce button_22 = Bounce(22, 10);
Bounce button_23 = Bounce(23, 10);
Bounce button_24 = Bounce(24, 10);
Bounce button_27 = Bounce(27, 10);
Bounce button_28 = Bounce(28, 10);
Bounce button_29 = Bounce(29, 10);
Bounce button_30 = Bounce(30, 10);
Bounce button_31 = Bounce(31, 10);
Bounce button_32 = Bounce(32, 10);
Bounce button_33 = Bounce(33, 10);
Bounce button_34 = Bounce(34, 10);
Bounce button_35 = Bounce(35, 10);
Bounce button_36 = Bounce(36, 10);
Bounce button_37 = Bounce(37, 10);
Bounce button_38 = Bounce(38, 10);
Bounce button_39 = Bounce(39, 10);
Bounce button_40 = Bounce(40, 10);
Bounce button_41 = Bounce(41, 10);
Bounce button_48 = Bounce(48, 10);
Bounce button_49 = Bounce(49, 10);
Bounce button_50 = Bounce(50, 10);
Bounce button_51 = Bounce(51, 10);
Bounce button_52 = Bounce(52, 10);
Bounce button_53 = Bounce(53, 10);
Bounce button_54 = Bounce(54, 10);

elapsedMillis timeElapsed;
unsigned int enc_interval = 150;  //interval for encoders

Rotary rotary1 = Rotary(0, 1);
Rotary rotary2 = Rotary(2, 3);
Rotary rotary3 = Rotary(4, 5);
Rotary rotary4 = Rotary(6, 7);
Rotary rotary5 = Rotary(8, 9);
Rotary rotary6 = Rotary(10, 11);

void setup() {

  attachInterrupt(digitalPinToInterrupt(0), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(1), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(2), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(4), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(5), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(6), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(7), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(8), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(9), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(10), rotate, CHANGE);
  attachInterrupt(digitalPinToInterrupt(11), rotate, CHANGE);

  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);
  pinMode(17, INPUT_PULLUP);
  pinMode(18, INPUT_PULLUP);
  pinMode(19, INPUT_PULLUP);
  pinMode(20, INPUT_PULLUP);
  pinMode(21, INPUT_PULLUP);
  pinMode(22, INPUT_PULLUP);
  pinMode(23, INPUT_PULLUP);
  pinMode(24, INPUT_PULLUP);
  pinMode(27, INPUT_PULLUP);
  pinMode(28, INPUT_PULLUP);
  pinMode(29, INPUT_PULLUP);
  pinMode(30, INPUT_PULLUP);
  pinMode(31, INPUT_PULLUP);
  pinMode(32, INPUT_PULLUP);
  pinMode(33, INPUT_PULLUP);
  pinMode(34, INPUT_PULLUP);
  pinMode(35, INPUT_PULLUP);
  pinMode(36, INPUT_PULLUP);
  pinMode(37, INPUT_PULLUP);
  pinMode(38, INPUT_PULLUP);
  pinMode(39, INPUT_PULLUP);
  pinMode(40, INPUT_PULLUP);
  pinMode(41, INPUT_PULLUP);
  pinMode(48, INPUT_PULLUP);
  pinMode(49, INPUT_PULLUP);
  pinMode(50, INPUT_PULLUP);
  pinMode(51, INPUT_PULLUP);
  pinMode(52, INPUT_PULLUP);
  pinMode(53, INPUT_PULLUP);
  pinMode(54, INPUT_PULLUP);
  
}

void loop() {

  // read 6 analog inputs and use them for the joystick axis
  //Joystick.Xrotate(analogRead(25));
  //Joystick.Yrotate(analogRead(26));

  if (timeElapsed > enc_interval) {
   Joystick.button(1,0);
   Joystick.button(2,0);
   Joystick.button(3,0);
   Joystick.button(4,0);
   Joystick.button(5,0);
   Joystick.button(6,0);
   Joystick.button(7,0);
   Joystick.button(8,0);
   Joystick.button(9,0);
   Joystick.button(10,0);
   Joystick.button(11,0);
   Joystick.button(12,0);
  }

  //UPDATE BUTTONS

  button_12.update();
  button_13.update();
  button_14.update();
  button_15.update();
  button_16.update();
  button_17.update();
  button_18.update();
  button_19.update();  
  button_20.update();
  button_21.update();
  button_22.update();
  button_23.update();
  button_24.update();
  button_27.update();
  button_28.update();
  button_29.update();
  button_30.update();
  button_31.update();
  button_32.update();
  button_33.update();
  button_34.update();
  button_35.update();
  button_36.update();
  button_37.update();
  button_38.update();
  button_39.update();
  button_40.update();
  button_41.update();
  button_48.update();
  button_49.update();
  button_50.update();
  button_51.update();
  button_52.update();
  button_53.update();
  button_54.update();

  // Check each button for "falling" edge.
  // Update the Joystick buttons only upon changes.
  // falling = high (not pressed - voltage from pullup resistor)
  //           to low (pressed - button connects pin to ground)
  if (button_12.fallingEdge()) {
    Joystick.button(13, 1);
  }
  if (button_13.fallingEdge()) {
    Joystick.button(14, 1);
  }
  if (button_14.fallingEdge()) {
    Joystick.button(15, 1);
  }
  if (button_15.fallingEdge()) {
    Joystick.button(16, 1);
  }
  if (button_16.fallingEdge()) {
    Joystick.button(17, 1);
  }
  if (button_17.fallingEdge()) {
    Joystick.button(18, 1);
  }
  if (button_18.fallingEdge()) {
    Joystick.button(19, 1);
  }
  if (button_19.fallingEdge()) {
    Joystick.button(20, 1);
  }
  if (button_20.fallingEdge()) {
    Joystick.button(21, 1);
  }
  if (button_21.fallingEdge()) {
    Joystick.button(22, 1);
  }
  if (button_22.fallingEdge()) {
    Joystick.button(23, 1);
  }
  if (button_23.fallingEdge()) {
    Joystick.button(24, 1);
  }
  if (button_24.fallingEdge()) {
    Joystick.button(25, 1);
  }
  if (button_27.fallingEdge()) {
    Joystick.button(28, 1);
  }
  if (button_28.fallingEdge()) {
    Joystick.button(29, 1);
  }
  if (button_29.fallingEdge()) {
    Joystick.button(30, 1);
  }
  if (button_30.fallingEdge()) {
    Joystick.button(31, 1);
  }
  if (button_31.fallingEdge()) {
    Joystick.button(32, 1);
  }
  if (button_32.fallingEdge()) {
    Joystick.button(33, 1);
  }
  if (button_33.fallingEdge()) {
    Joystick.button(34, 1);
  }
  if (button_34.fallingEdge()) {
    Joystick.button(35, 1);
  }
  if (button_35.fallingEdge()) {
    Joystick.button(36, 1);
  }
  if (button_36.fallingEdge()) {
    Joystick.button(37, 1);
  }
  if (button_37.fallingEdge()) {
    Joystick.button(38, 1);
  }
  if (button_38.fallingEdge()) {
    Joystick.button(39, 1);
  }
  if (button_39.fallingEdge()) {
    Joystick.button(40, 1);
  }
  if (button_40.fallingEdge()) {
    Joystick.button(41, 1);
  }
  if (button_41.fallingEdge()) {
    Joystick.button(42, 1);
  }
  if (button_48.fallingEdge()) {
    Joystick.button(49, 1);
  }
  if (button_49.fallingEdge()) {
    Joystick.button(50, 1);
  }
  if (button_50.fallingEdge()) {
    Joystick.button(51, 1);
  }
  if (button_51.fallingEdge()) {
    Joystick.button(52, 1);
  }
  if (button_52.fallingEdge()) {
    Joystick.button(53, 1);
  }
  if (button_53.fallingEdge()) {
    Joystick.button(54, 1);
  }
  if (button_54.fallingEdge()) {
    Joystick.button(55, 1);
  }  

  // Check each button for "rising" edge
  // Update the Joystick buttons only upon changes.
  // rising = low (pressed - button connects pin to ground)
  //          to high (not pressed - voltage from pullup resistor)

  if (button_12.risingEdge()) {
    Joystick.button(13, 0);
  }
  if (button_13.risingEdge()) {
    Joystick.button(14, 0);
  }
  if (button_14.risingEdge()) {
    Joystick.button(15, 0);
  }
  if (button_15.risingEdge()) {
    Joystick.button(16, 0);
  }
  if (button_16.risingEdge()) {
    Joystick.button(17, 0);
  }
  if (button_17.risingEdge()) {
    Joystick.button(18, 0);
  }
  if (button_18.risingEdge()) {
    Joystick.button(19, 0);
  }
  if (button_19.risingEdge()) {
    Joystick.button(20, 0);
  }
  if (button_20.risingEdge()) {
    Joystick.button(21, 0);
  }
  if (button_21.risingEdge()) {
    Joystick.button(22, 0);
  }
  if (button_22.risingEdge()) {
    Joystick.button(23, 0);
  }
  if (button_23.risingEdge()) {
    Joystick.button(24, 0);
  }
  if (button_24.risingEdge()) {
    Joystick.button(25, 0);
  }
  if (button_27.risingEdge()) {
    Joystick.button(28, 0);
  }
  if (button_28.risingEdge()) {
    Joystick.button(29, 0);
  }
  if (button_29.risingEdge()) {
    Joystick.button(30, 0);
  }
  if (button_30.risingEdge()) {
    Joystick.button(31, 0);
  }
  if (button_31.risingEdge()) {
    Joystick.button(32, 0);
  }
  if (button_32.risingEdge()) {
    Joystick.button(33, 0);
  }
  if (button_33.risingEdge()) {
    Joystick.button(34, 0);
  }
  if (button_34.risingEdge()) {
    Joystick.button(35, 0);
  }
  if (button_35.risingEdge()) {
    Joystick.button(36, 0);
  }
  if (button_36.risingEdge()) {
    Joystick.button(37, 0);
  }
  if (button_37.risingEdge()) {
    Joystick.button(38, 0);
  }
  if (button_38.risingEdge()) {
    Joystick.button(39, 0);
  }
  if (button_39.risingEdge()) {
    Joystick.button(40, 0);
  }
  if (button_40.risingEdge()) {
    Joystick.button(41, 0);
  }
  if (button_41.risingEdge()) {
    Joystick.button(42, 0);
  }
  if (button_48.risingEdge()) {
    Joystick.button(49, 0);
  }
  if (button_49.risingEdge()) {
    Joystick.button(50, 0);
  }
  if (button_50.risingEdge()) {
    Joystick.button(51, 0);
  }
  if (button_51.risingEdge()) {
    Joystick.button(52, 0);
  }
  if (button_52.risingEdge()) {
    Joystick.button(53, 0);
  }
  if (button_53.risingEdge()) {
    Joystick.button(54, 0);
  }
  if (button_54.risingEdge()) {
    Joystick.button(55, 0);
  }

}

void rotate() {
 
// HANDLE ENCODER 1

unsigned char result1 = rotary1.process();

  switch(result1){
    case DIR_CW:
    timeElapsed = 150;
    Joystick.button(1,1);
    Joystick.button(2,0);
    break;
    default:
      break;
  }
    switch(result1){        
    case DIR_CCW:
    timeElapsed = 150;
    Joystick.button(2,1);
    Joystick.button(1,0);
    break;
    default:
      break;
    
  }


/*unsigned char result1 = rotary1.process();
  if (result1 == DIR_CW) {
    timeElapsed = 0;
    Joystick.button(1,1);
    Joystick.button(2,0);
  } else if (result1 == DIR_CCW) {
    timeElapsed = 0;
    Joystick.button(2,1);
    Joystick.button(1,0);
  }*/

// HANDLE ENCODER 2 

  unsigned char result2 = rotary2.process();
  switch(result2) {
    case (DIR_CW):
    timeElapsed = 150;
    Joystick.button(3,1);
    Joystick.button(4,0);
    break;
    default:
      break;
  }
  switch(result2) {
    case DIR_CCW:
    timeElapsed = 150;
    Joystick.button(4,1);
    Joystick.button(3,0);
    break;
    default:
      break;
  } 

  /*unsigned char result2 = rotary2.process();
  if (result2 == DIR_CW) {
    timeElapsed = 0;
    Joystick.button(3,1);
    Joystick.button(4,0);
  } else if (result2 == DIR_CCW) {
    timeElapsed = 0;
    Joystick.button(4,1);
    Joystick.button(3,0);
  }*/
 
// HANDLE ENCODER 3

  unsigned char result3 = rotary3.process();
  switch(result3) {
    case (DIR_CW):
    timeElapsed = 150;
    Joystick.button(5,1);
    Joystick.button(6,0);
    break;
    default:
      break;
  }
  switch(result3){
    case DIR_CCW:
    timeElapsed = 150;
    Joystick.button(6,1);
    Joystick.button(5,0);
    break;
    default:
      break;
  } 


  /*unsigned char result3 = rotary3.process();
  if (result3 == DIR_CW) {
    timeElapsed = 0;
    Joystick.button(5,1);
    Joystick.button(6,0);
  } else if (result3 == DIR_CCW) {
    timeElapsed = 0;
    Joystick.button(6,1);
    Joystick.button(5,0);
  }*/   
 
// HANDLE ENCODER 4

  unsigned char result4 = rotary4.process();
  switch(result4) {
    case (DIR_CW):
    timeElapsed = 150;
    Joystick.button(7,1);
    Joystick.button(8,0);
    break;
    default:
      break;
  }
  switch(result4) {
    case DIR_CCW:
    timeElapsed = 150;
    Joystick.button(8,1);
    Joystick.button(7,0);
    break;
    default:
      break;
  } 

  /*unsigned char result4 = rotary4.process();
  if (result4 == DIR_CW) {
    timeElapsed = 0;
    Joystick.button(7,1);
    Joystick.button(8,0);
  } else if (result4 == DIR_CCW) {
    timeElapsed = 0;
    Joystick.button(8,1);
    Joystick.button(7,0);
  }*/    
 
// HANDLE ENCODER 5

  unsigned char result5 = rotary5.process();
  switch(result5) {
    case (DIR_CW):
    timeElapsed = 150;
    Joystick.button(9,1);
    Joystick.button(10,0);
    break;
    default:
      break;
  }
  switch(result5) {
    case DIR_CCW:
    timeElapsed = 150;
    Joystick.button(10,1);
    Joystick.button(9,0);
    break;
    default:
      break;
  } 

  /*unsigned char result5 = rotary5.process();
  if (result5 == DIR_CW) {
    timeElapsed = 0;
    Joystick.button(9,1);
    Joystick.button(10,0);
  } else if (result5 == DIR_CCW) {
    timeElapsed = 0;
    Joystick.button(10,1);
    Joystick.button(9,0);
  }  */  
 
// HANDLE ENCODER 6

  unsigned char result6 = rotary6.process();
  switch (result6) {
    case (DIR_CW):
    timeElapsed = 150;
    Joystick.button(11,1);
    Joystick.button(12,0);
    break;
    default:
      break;
  }
  switch(result6) {
    case DIR_CCW:
    timeElapsed = 150;
    Joystick.button(12,1);
    Joystick.button(11,0);
    break;
    default:
      break;
  } 

  /*unsigned char result6 = rotary6.process();
  if (result6 == DIR_CW) {
    timeElapsed = 0;
    Joystick.button(11,1);
    Joystick.button(12,0);
  } else if (result6 == DIR_CCW) {
    timeElapsed = 0;
    Joystick.button(12,1);
    Joystick.button(11,0);
  }  */
  
 
}

Don't rotate it too many times, you don't need to do that.

Bounce button_12 = Bounce(12, 10);
Bounce button_13 = Bounce(13, 10);  // 10 = 10 ms debounce time
Bounce button_14 = Bounce(14, 10);  // which is appropriate for
...
Bounce button_52 = Bounce(52, 10);
Bounce button_53 = Bounce(53, 10);
Bounce button_54 = Bounce(54, 10);

You seriously need to learn to use arrays!

  • Avoid using the TX and RX pins.

I'm not using an Arduino board. I'm using a Teensy 4.1. I should have mentioned that. I will combine the switch statements.

I am new to Arduino coding. I will put the buttons in an array. If I rotate the encoder, one-click every 1 sec or so it works for a while, but then it freezes.

I will try to find the wiring diagram.

Thank you!!

@kolaha Will your method work with a Teensy 4.1? I'm using pins [0-12]

Sell Teensy and buy 5x "Arduino Micro Pro"