Hi all,
I'm using a Leonardo to interface with my computer as a joystick, I've assigned a few buttons (buttons 1-12) which are working great I've also added in 3 rotary encoders (Buttons 13-18).
The desired functionality is when I turn the encoder clockwise or counterclockwise it registers the movement as 1 triggering of the button.
Example:
Turn encoder #1 clockwise 3 detentes should register 3 triggers of the 13 button. Likewise, turning it counterclockwise would register the 14 button.
The problem I am having is that the rotaries are just constantly triggering and showing all the rotary buttons as being triggered.
I've included my code below, it compiles fine, windows interprets it as an 18 buttonjoystick, like intended, the pushbuttons work fine as well.
//include joystick library
#include <Joystick.h>
//Map Button name alias to pins Syntax= define <Name\Pin>
#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
//Rotary definition
#define NUMROTARIES 3
#define ENABLE_PULLUPS
// Set Map Button names/pins to button numbers
const byte buttonPins[NUM_BUTTONS] = {B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12};
//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
//Testing Rotaries
struct rotariesdef {
byte pin1;
byte pin2;
int ccwchar;
int cwchar;
volatile unsigned char state;
};
rotariesdef rotaries[NUMROTARIES] {
{6,7,13,14,0},
{2,3,15,16,0},
{4,5,17,18,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
void setup() {
// Change pins to input and enable pullup resistors
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);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
// Initialize Joystick Library
Joystick.begin();
}
void loop() {
CheckAllEncoders();
// Read Button
bool buttonVals[NUM_BUTTONS];
for (int index =0; index < NUM_BUTTONS; index++){
buttonVals[index] = !digitalRead(buttonPins[index]);
}
for(int i = 0; i < NUM_BUTTONS; i++) {
Joystick.setButton(i, buttonVals[i]);
}
delay(50);
}
/* 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(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);
};
}
}
You can see in this image the buttons assigned to the rotary encoders are lit up, currently nothing is connected to the pins these are assigned to but they are still being triggered by something.
If anyone has any ideas please let me know I am tearing my hair out.
Thanks in advance