/*
button box 32 buttons with 2 rotaries and 0 axis for Arduino pro micro
*/
#include <Joystick.h>
#define enablePullUps
const byte numOfRotaries = 2;
//Creating an arrays with pins that are used
// for more info: 21 = A3, 20 = A2, 19 = A1, 18 = A0 ....
byte rowPins[] = {21, 20, 19, 18};
byte colPins[] = {16, 10, 9, 14, 15};
byte button[] = {4, 5};
struct rotariesStruct {
byte pin1;
byte pin2;
byte cClockWise;
byte clockWise;
byte state;
} Encs[numOfRotaries] {
{0, 1, 28, 29, 0}, //pin 0 and 1 are connected to joystick button 36, 37
{2, 3, 30, 31, 0}
};
//define size of array
const int numOfColumns = sizeof(colPins) / sizeof(colPins[0]);
const int numOfRows = sizeof(rowPins) / sizeof(rowPins[0]);
//create and define the joystick
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK,
32, 0, // not all applications supporting more as 32 buttons
false, false, false, // X, Y, Z axes
false, false, false, // Rx, Ry, Rz
false, false, // rudder, throttle
false, false, false); // accelerator, break, steering
const byte RT[6][4] = {
{0x03, 0x02, 0x01, 0x00}, // 0x0 (00)
{0x13, 0x00, 0x01, 0x00}, // 0x1
{0x23, 0x02, 0x00, 0x00}, // 0x2
{0x03, 0x05, 0x04, 0x00}, // 0x3
{0x03, 0x03, 0x04, 0x20}, // 0x4
{0x03, 0x05, 0x03, 0x10}, // 0x5
};
void setup() {
Joystick.begin();
initializeRotaryEncoders();
for (byte r = 0; r < numOfRows; r++) {
pinMode(rowPins[r], INPUT_PULLUP);
}
for (byte r = 0; r < 2; r++) {
pinMode(button[r], INPUT_PULLUP);
}
}
void loop() {
CheckButtons();
CheckRotaryEncoder();
}
void CheckButtons() {
for (byte c = 0; c < numOfColumns; c++) {
pinMode(colPins[c], OUTPUT);
digitalWrite(colPins[c], LOW); // Begin column pulse output.
for (byte r = 0; r < numOfRows; r++)Joystick.setButton(2+r + c * numOfColumns, !digitalRead(rowPins[r]));
pinMode(colPins[c], INPUT_PULLUP);
}
Joystick.setButton(0, !digitalRead(button[0]));
Joystick.setButton(1, !digitalRead(button[1]));
}
void initializeRotaryEncoders() { //create and initial rotary
for (int i = 0; i < numOfRotaries; i++) {
pinMode(Encs[i].pin1, INPUT); //set pins to input
pinMode(Encs[i].pin2, INPUT);
#ifdef enablePullUps
digitalWrite(Encs[i].pin1, HIGH); //set pins value to high
digitalWrite(Encs[i].pin2, HIGH);
#endif
}
}
byte rotaryProcess(byte i) {
byte pinState = (digitalRead(Encs[i].pin2) << 1) | digitalRead(Encs[i].pin1);
Encs[i].state = RT[Encs[i].state & 0xf][pinState];
return (Encs[i].state & 0x30);
}
void CheckRotaryEncoder() {
for (byte i = 0; i < numOfRotaries; i++) {
byte result = rotaryProcess(i);
//if the rotary has been turned to left
if (result == 0x10) {
Joystick.setButton(Encs[i].cClockWise, 1);
delay(20);
Joystick.setButton(Encs[i].cClockWise, 0);
} else
//if the rotary is turned to the right
if (result == 0x20) {
Joystick.setButton(Encs[i].clockWise, 1);
delay(20);
Joystick.setButton(Encs[i].clockWise, 0);
}
}
}