|
#include <Joystick.h> |
|
#include <Keypad.h> |
|
|
|
#define ENABLE_PULLUPS |
|
#define NUMROTARIES 4 // Number of rotary encoders |
|
#define NUMBUTTONS 18 // Number of buttons |
|
#define NUMROWS 6 // Number of rows in matrix |
|
#define NUMCOLS 3 // Number of columns in matrix |
|
|
|
byte row_pins[NUMROWS] = {6, 7, 8, 9, 10, 16}; |
|
byte col_pins[NUMCOLS] = {18, 19, 20}; |
|
|
|
byte buttons[NUMROWS][NUMCOLS] = {}; |
|
|
|
struct rotariesdef { |
|
byte pin1; |
|
byte pin2; |
|
int ccwchar; |
|
int cwchar; |
|
volatile unsigned char state; |
|
}; |
|
|
|
rotariesdef rotaries[NUMROTARIES] {}; |
|
|
|
// Counter-clockwise direction |
|
#define DIR_CCW 0x10 |
|
// Clockwise direction |
|
#define DIR_CW 0x20 |
|
// Rotary start |
|
#define R_START 0x0 |
|
|
|
#ifdef HALF_STEP |
|
// Rotary counter-clockwise begin |
|
#define R_CCW_BEGIN 0x1 |
|
// Rotary clockwise begin |
|
#define R_CW_BEGIN 0x2 |
|
// Rotary start...? |
|
#define R_START_M 0x3 |
|
// Rotary clockwise begin...? |
|
#define R_CW_BEGIN_M 0x4 |
|
// Rotary counter-clockwise begin...? |
|
#define R_CCW_BEGIN_M 0x5 |
|
|
|
const unsigned char ttable[6][4] = {}; |
|
|
|
Keypad button_box = Keypad( |
|
makeKeymap(buttons), |
|
row_pins, |
|
col_pins, |
|
NUMROWS, |
|
NUMCOLS |
|
); |
|
|
|
Joystick_ Joystick( |
|
JOYSTICK_DEFAULT_REPORT_ID, |
|
JOYSTICK_TYPE_JOYSTICK, |
|
32, |
|
0, |
|
false, |
|
false, |
|
false, |
|
false, |
|
false, |
|
false, |
|
false, |
|
false, |
|
false, |
|
false, |
|
false |
|
); |
|
|
|
void setup() { |
|
Joystick.begin(); |
|
rotary_init(); |
|
} |
|
|
|
void loop() { |
|
check_all_encoders(); |
|
check_all_buttons(); |
|
} |
|
|
|
void rotary_init(void) { |
|
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 |
|
} |
|
} |
|
|
|
void check_all_buttons(void) { |
|
if (button_box.getKeys()) { |
|
for (int i=0; i<LIST_MAX; i++) { |
|
if (button_box.key[i].stateChanged) { |
|
switch (button_box.key[i].kstate) { |
|
case PRESSED: |
|
case HOLD: |
|
Serial.print("Pressed"); |
|
Joystick.setButton(button_box.key[i].kchar, 1); |
|
break; |
|
case RELEASED: |
|
case IDLE: |
|
Serial.print("Released"); |
|
Joystick.setButton(button_box.key[i].kchar, 0); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Process the rotary state to establish what direction it's been turned |
|
unsigned char rotary_process(int r) { |
|
unsigned char pinstate = (digitalRead(rotaries[r].pin2) << 1) | digitalRead(rotaries[r].pin1); |
|
rotaries[r].state = ttable[rotaries[r].state & 0xf][pinstate]; |
|
return (rotaries[r].state & 0x30); |
|
} |
|
|
|
// Process the rotary position, and update the joystick |
|
void check_all_encoders(void) { |
|
for (int i=0; i<NUMROTARIES; i++) { |
|
unsigned char result = rotary_process(i); |
|
|
|
// Process a counter-clockwise rotation |
|
if (result == DIR_CCW) { |
|
Joystick.setButton(rotaries[i].ccwchar, 1); |
|
delay(50); |
|
Joystick.setButton(rotaries[i].ccwchar, 0); |
|
} |
|
|
|
// Process a clockwise rotation |
|
if (result == DIR_CW) { |
|
Joystick.setButton(rotaries[i].cwchar, 1); |
|
delay(50); |
|
Joystick.setButton(rotaries[i].cwchar, 0); |
|
} |
|
} |
|
} |