ArduinoJoystickLibrary
ArduinoJoystickLibrary copied to clipboard
Buttons activate itself
Description of Issue
I'm making a control box for car simulation, and there is a big step motor. As long as the step motor is not activated, everything works fine. Every time I start the step motor, the button starts to trigger by itself. My guess is that the EMI cause this, however, I do not see a way to prevent this. Some says the pull_up resistor:
pinMode(2,INPUT_PULLUP);
Will solve this problem. However, I cannot find a way to activate the pull up resistor. Can you give me some help about this?
Technical Details
- Arduino Board (e.g. Arduino Leonardo): Arduino Pro Micro
- Host OS (e.g. Windows 10): Win10
- Arduino IDE Version (e.g. 1.8.3): 1.8.13
Sketch File that Reproduces Issue
Sketch file goes here (if applicable)
Wiring Details
wiring is like common button matrix wiring.
15 x x x x x A0 x x x x x A1 x x x x x A2 x x x x x A3 x x x x x 8 9 10 14 16
Additional context
The code is from Amstudio: https://github.com/AM-STUDIO/32-FUNCTION-BUTTON-BOX
#include <Key.h> #include <Keypad.h>
#include <Joystick.h>
//BUTTON BOX //USE w ProMicro //Tested in WIN10 + Assetto Corsa //AMSTUDIO //20.8.17
#include <Keypad.h> #include <Joystick.h>
#define ENABLE_PULLUPS #define NUMROTARIES 4 #define NUMBUTTONS 24 #define NUMROWS 5 #define NUMCOLS 5
byte buttons[NUMROWS][NUMCOLS] = { {0,1,2,3,4}, {5,6,7,8,9}, {10,11,12,13,14}, {15,16,17,18,19}, {20,21,22,23}, };
struct rotariesdef { byte pin1; byte pin2; int ccwchar; int cwchar; volatile unsigned char state; };
rotariesdef rotaries[NUMROTARIES] { {0,1,24,25,0}, {2,3,26,27,0}, {4,5,28,29,0}, {6,7,30,31,0}, };
#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
byte rowPins[NUMROWS] = {21,20,19,18,15}; byte colPins[NUMCOLS] = {14,16,10,9,8};
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[i].stateChanged )
{
switch (buttbx.key[i].kstate) {
case PRESSED:
case HOLD:
Joystick.setButton(buttbx.key[i].kchar, 1);
break;
case RELEASED:
case IDLE:
Joystick.setButton(buttbx.key[i].kchar, 0);
break;
}
}
}
}
}
void rotary_init() { for (int i=0;i<NUMROTARIES;i++) { pinMode(rotaries[i].pin1, INPUT_PULLUP); pinMode(rotaries[i].pin2, INPUT_PULLUP); #ifdef ENABLE_PULLUPS digitalWrite(rotaries[i].pin1, HIGH); digitalWrite(rotaries[i].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[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); }; } }
Do you have a 1k resistor in place? It seems more like a hardware issue than a library issue.
In your "setup()" routine you should use pinMode() to define your pin modes. If you put "pinMode(<pin #>, INPUT_PULLUP)" there as the OP mentioned it will enable the internal pullup. Or you can add a stronger external pullup. If that isn't good enough a small 0.01uF cap to ground may help. All, make sure you have enough power to handle the steppers. A big cap 100uF or more across the power supply feeding the steppers could help.
Tim
In your "setup()" routine you should use pinMode() to define your pin modes. If you put "pinMode(<pin #>, INPUT_PULLUP)" there as the OP mentioned it will enable the internal pullup. Or you can add a stronger external pullup. If that isn't good enough a small 0.01uF cap to ground may help. All, make sure you have enough power to handle the steppers. A big cap 100uF or more across the power supply feeding the steppers could help.
Tim
Can you give some details about how to put the pinMode in the setup? Since I didn't find out how he defines the pins. Also, how should I connect the resistors? Should I connect every pin to the ground?
Thanks for reply
The key matrix decoding library may already be enabling them for the relevant pins, I think that's what the "#define ENABLE_PULLUPS" is meant to do.
Otherwise, in the setup() function add lines like so:
void setup() {
// switches
pinMode(7, INPUT_PULLUP);
}
See: https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/
The internal pullups are a bit weak though. If you want to try an external pullup, connect a 1K resistor from the GPIO pin the appropriate voltage (3.3V or 5V depending on your Arduino). Don't use the wrong voltage it could damage the chip.
Also you can try a small capacitor (0.01uF or 0.001uF) from the GPIO to GND as a filter.
Long wires can pickup noise/generate noise, high power connections like the ones that drive the stepper can couple interference into the low power sensitive GPIO signals. Try to keep the stepper motor wires far away from the switch wires. Don't share any GND wires between the two circuits, they should only connect together back near the power supply, otherwiese the high currents from the stepper can cause "ground bounce" to affect the GPIO.
Are you using a stepper driver? Which one?
Tim
If its because of EMI, make a plastic casing for it or cover the stepper motor with plastic wrapping. I know it sounds a little silly but hope it works because i have not tried it myself.
i am also struggling because of same issue. is there any confirmed solution ?