I want to ask you a question.
I connected it like this, but only some of it works.
I want to know why.
Is it because of insufficient voltage that only some of it works?
Or I wonder if this Arduino does not support 32 buttons at the same time in the language.
Please tell me what is wrong.
Can't 16 buttons work at the same time?
/********** 36 Buttons and 3 Rotary Encoders button box by BaldEagle gaming **********/
/*
*This code is for creating a button box with 36 buttons with 3 rotaries and 0 axis
*This code is for Arduino pro micro
*The table below is showing how the buttons are connected to the board (pin)
*A3, A2, A1, A0, 15 and 14 Are the Row Pins for the Keypad 16 and 10-6 are the Column Pins
*the buttons are connected to each others according to this table
* : A3 A2 A1 A0 15 14
* ....................................................
* 16 : 0 1 2 3 4 5 I
* 10 : 6 7 8 9 10 11
* 9 : 12 13 14 15 16 17
* 8 : 18 19 20 21 22 23
* 7 : 24 25 26 27 28 29
* 6 : 30 31 32 33 34 35
* Pin 0, 1, 2, 3, 4, and 5 plus the GND are used for rotaries
*/
//Including libraries and define variables and give a constant value name
#include <Keypad.h> //#include is used to include libraries from outside the code.
#include <Joystick.h>
#define enablePullUps //#define is used to give a name to a constant value.
//or to define a new variable
const byte numOfRotaries = 3; //creating variables to define number of rotary encoders
//Creating an array with pins that are used
// for more info: 21 = A3, 20 = A2, 19 = A1, 18 = A0 ....
byte colPins[] = {21,20,19,18,15,14};
byte rowPins[] = {16,10,9,8,7,6};
//define size of array
const int numOfColumns = sizeof(colPins)/sizeof(colPins[0]);
const int numOfRows = sizeof(rowPins)/sizeof(rowPins[0]);
// Creating a 2D array that contains the buttons and also symboling them
byte buttons[numOfRows][numOfColumns] = {
{0,1,2,3,4,5},
{6,7,8,9,10,11},
{12,13,14,15,16,17},
{18,19,20,21,22,23},
{24,25,26,27,28,29},
{30,31,32,33,34,35},
};
//Inislize new keypad class
Keypad ButtonBox = Keypad( makeKeymap(buttons),
rowPins, colPins, numOfRows, numOfColumns);
//create and define the joystick
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK,
42, 0, // 36 atsButtons, 3x2 rotary encoder (each rotary is count as 2 buttons
//(clockwise (turn right) and counterclockwise (turn left)), 0 hat switch,
false, false, false, // no X axis, Y axis, and/or Z axis
false, false, false, // no Rx, Ry, Rz
false, false, // no rudder and/or throttle
false, false, false); // no accelerator, break, and/or steering
//creating structure (A structure can contain variables, methods, static constructor, ...)
struct rotariesStruct {
byte pin1; //define pins and create 3 variabes
byte pin2;
int cClockWise;
int clockWise;
volatile unsigned char state;
};
rotariesStruct rotariesEncoders[numOfRotaries] {
//this will create 3 rotaries
{0,1,36,37,0}, //pin 0 and 1 are connected to button 36, 37 (rotary)
{2,3,38,39,0},
{4,5,40,41,0},
};
//rotary table
#define DIR_CCW 0x10 //DIR = Directory
#define DIR_CW 0x20 //ccw = counter clockwise CW = clockwise
#define R_START 0x0 //R_start = rotary start
#ifdef HALF_STEP
//use 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 rotaryTable[6][4] = { //[6][4] mean 6 rows and 4 columns
// 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 full step
#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 rotaryTable[7][4] = { //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() { //setup() is a method called when the program start, and create the variabes and
//pin mode......
Joystick.begin();
initializeRotaryEncoders();
}
void loop() { //loop() is a method that run for ever
CheckingButtons(); //this mean that these 2 methods will run for ever
CheckingRotaryEncoder();
}
//CheckingButtons() function will check the state of the buttons
void CheckingButtons() {
if (ButtonBox.getKeys()){
for (int i=0; i<LIST_MAX; i++) { //LIST_MAX is a variabe created in keypad.ccp and keypad.h
if ( ButtonBox.key[i].stateChanged ) { //this mean if the button has been pressed/hold or released
switch (ButtonBox.key[i].kstate) {
case PRESSED: //if the button is pressed and/or hold
case HOLD:
Joystick.setButton(ButtonBox.key[i].kchar, 1); //value will be set to 1 = ON in binary
break;
case RELEASED: //if the button is idle or released
case IDLE:
Joystick.setButton(ButtonBox.key[i].kchar, 0); //value will set to 0 = OFF in binary
break;
}
}
}
}
}
void initializeRotaryEncoders() { //create and initial rotary
for (int i=0;i<numOfRotaries;i++) {
pinMode(rotariesEncoders[i].pin1, INPUT); //set pins to input
pinMode(rotariesEncoders[i].pin2, INPUT);
#ifdef enablePullUps
digitalWrite(rotariesEncoders[i].pin1, HIGH); //set pins value to high
digitalWrite(rotariesEncoders[i].pin2, HIGH);
#endif
}
}
//Create and check pin state
unsigned char rotaryProcess(int i) {
unsigned char pinState = (digitalRead(rotariesEncoders[i].pin2) << 1)
| digitalRead(rotariesEncoders[i].pin1); //get the pins state
rotariesEncoders[i].state = rotaryTable[rotariesEncoders[i].state //determine a new state
& 0xf][pinState];
return (rotariesEncoders[i].state & 0x30); //return the created event
}
//check all rotaries encoder
void CheckingRotaryEncoder() {
for (int i=0;i<numOfRotaries;i++) {
unsigned char result = rotaryProcess(i);
if (result == DIR_CCW) { //if the rotary has been turned to left
Joystick.setButton(rotariesEncoders[i].cClockWise, 1); //value will be set to 1
delay(250); //waiting 250ms = 1/4 second before set the value to 0
Joystick.setButton(rotariesEncoders[i].cClockWise, 0);
}
if (result == DIR_CW) { //if the rotary is turned to the right
Joystick.setButton(rotariesEncoders[i].clockWise, 1);
delay(250);
Joystick.setButton(rotariesEncoders[i].clockWise, 0);
}
}
}