#include <Joystick.h>
#include <Key.h>
#include <Keypad.h>
/*
These libraries will be used to emulate a joystick, and assigning keys to the button output
*/
/*
We enable the onboard resistors that pull the current down to the board
as you can see in the schema
*/
#define ENABLE_PULLUPS
#define NUMROTARIES 5
#define NUMBUTTONS 16
#define NUMROWS 4
#define NUMCOLS 4
/*
This variable will map our 2D matrix, and assign a number for each button
The values are just incrementing numbers
*/
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;
};
/*
Here we map each of the rotary encoders into an array
You will notice that 1 and 0 are reversed, that's because on this arduino board, tx and rx are reversed
{
pin1 (clk),
pin2 (dta),
button to press when turning backwards,
button to press when turning forwards
current state of button (0)
}
*/
rotariesdef rotaries[NUMROTARIES] {
{1,0,16,17,0},
{2,3,18,19,0},
{4,5,20,21,0},
{6,7,22,23,0},
{8,9,24,25,0}
};
/*
This is some next level shit, don't look at it for too long
And don't worry about it, it works.
*/
#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
/*
This one is important, here we defined the number of the ports we are using for the rows and cols
If you look at my schema, you will see that the rows (in red) and cols (in blue) match with the numbers below
*/
byte rowPins[NUMROWS] = {15,14,16,10};
byte colPins[NUMCOLS] = {21,20,19,18};
/*
The following code will loop all inputs and assign them to buttons that our fake joystick can output
The code below uses the above inputs, so you don't have to make any changes here.
*/
Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, 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() {
CheckAllEncoders();
CheckAllButtons();
}
void CheckAllButtons(void) {
if (buttbx.getKeys())
{
for (int i=0; i<LIST_MAX; i++)
{
if ( buttbx.key*.stateChanged ) *
- {*
_ switch (buttbx.key*.kstate) { _
_ case PRESSED:_
_ case HOLD:_
_ Joystick.setButton(buttbx.key.kchar, 1);
break;
case RELEASED:
case IDLE:
Joystick.setButton(buttbx.key.kchar, 0);
break;
}
}
}
}
}
void rotary_init() {
for (int i=0;i<NUMROTARIES;i++) {
pinMode(rotaries.pin1, INPUT);
pinMode(rotaries.pin2, INPUT);_
#ifdef ENABLE_PULLUPS*
_ digitalWrite(rotaries*.pin1, HIGH);
digitalWrite(rotaries.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_.ccwchar, 1); delay(50); Joystick.setButton(rotaries.ccwchar, 0);
};_
if (result == DIR_CW) {
Joystick.setButton(rotaries_.cwchar, 1); delay(50); Joystick.setButton(rotaries.cwchar, 0);
};
}
}*_