Hey friends,
I’ve got 3 encoders hooked up to a Leonardo running interrupts to press a few buttons and some weird inconsistencies between them although they all run off the same code.
The problem:
Encoder#1 Connected to pins 0 & 1 assigned to buttons 13 & 14
- Sometimes will trigger buttons 13, 14, 15, 16 and 18 (But never 17). It should only ever trigger 13 or 14 depending on the direction of the rotation
Encoder#2 Connected to pins 2 and 3, assigned to buttons 15 & 16
- Works perfectly, literally no problems
Encoder#3 connected to pins 4 and 7, assigned to buttons 17 & 18
- Sometimes triggers the buttons, sometimes doesn’t, very intermittent in when it works.
The encoders being used are SR1230. Identical to the picture below
Here is the code, I’ve also attached it as an .ino file
#include <Joystick.h>
#define NUMROTARIES 3
#define NUM_BUTTONS 18
#define B1 8
#define B2 9
#define B3 10
#define B4 11
#define B5 12
#define B6 13
#define B7 18
#define B8 19
#define B9 20
#define B10 21
#define B11 22
#define B12 23
const byte buttonPins[12] = {B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12};
struct rotariesdef {
byte pin1;
byte pin2;
int ccwchar;
int cwchar;
volatile unsigned char state;
};
rotariesdef rotaries[NUMROTARIES] {
{0,1,12,13,0},
{2,3,14,15,0},
{4,7,16,17,0},
};
#define DIR_CCW 0x10
#define DIR_CW 0x20
#define R_START 0x0
#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
volatile 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},
};
//Setup joystick functions
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
NUM_BUTTONS, 0, // Button Count, Hat Switch Count
false, false, false, // X and Y, but no Z Axis
false, false, false, // No Rx, Ry, or Rz
false, false, // No rudder or throttle
false, false, false); // No accelerator, brake, or steering
void setup() {
Joystick.begin();
rotary_init();
}
void loop() {
delay(100);
Joystick.setButton(17, 0);
Joystick.setButton(16, 0);
Joystick.setButton(15, 0);
Joystick.setButton(14, 0);
Joystick.setButton(13, 0);
Joystick.setButton(12, 0);
CheckAllButtons();
}
void CheckEncoders(){
for (volatile int i=0;i<NUMROTARIES;i++) {
volatile unsigned char result = rotary_process(i);
if (result == DIR_CCW) {
Joystick.setButton(rotaries[i].ccwchar, 1);
}
if (result == DIR_CW) {
Joystick.setButton(rotaries[i].cwchar, 1);
}
}
}
void CheckAllButtons(void) {
bool buttonVals[NUM_BUTTONS];
for (int index =0; index < NUM_BUTTONS; index++){
buttonVals[index] = !digitalRead(buttonPins[index]);
} //This
for(int i = 0; i < NUM_BUTTONS; i++) {
Joystick.setButton(i, buttonVals[i]);
}
}
void rotary_init() {
for (int i=0;i<NUMROTARIES;i++) {
pinMode(rotaries[i].pin1, INPUT_PULLUP);
pinMode(rotaries[i].pin2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(0), CheckEncoders, CHANGE);
attachInterrupt(digitalPinToInterrupt(1), CheckEncoders, CHANGE);
attachInterrupt(digitalPinToInterrupt(2), CheckEncoders, CHANGE);
attachInterrupt(digitalPinToInterrupt(3), CheckEncoders, CHANGE);
attachInterrupt(digitalPinToInterrupt(7), CheckEncoders, CHANGE);
digitalWrite(rotaries[i].pin1, HIGH);
digitalWrite(rotaries[i].pin2, HIGH);
}
pinMode(B1, INPUT_PULLUP);
pinMode(B2, INPUT_PULLUP);
pinMode(B3, INPUT_PULLUP);
pinMode(B4, INPUT_PULLUP);
pinMode(B5, INPUT_PULLUP);
pinMode(B6, INPUT_PULLUP);
pinMode(B7, INPUT_PULLUP);
pinMode(B8, INPUT_PULLUP);
pinMode(B9, INPUT_PULLUP);
pinMode(B10, INPUT_PULLUP);
pinMode(B11, INPUT_PULLUP);
pinMode(B12, INPUT_PULLUP);
}
volatile unsigned char rotary_process(volatile int _i) {
volatile 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);
}
I’ve been poring over this for hours if you can fix this I’ll PayPal you $20 straight up. Please noblemen/women of the Arduino forums I beg you for you help! If you need any more information please let me know.
Button_box_V10.3.ino (3.76 KB)