ArduinoJoystickLibrary icon indicating copy to clipboard operation
ArduinoJoystickLibrary copied to clipboard

Buttons activate itself

Open buguniao55555 opened this issue 4 years ago • 6 comments

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); }; } }

buguniao55555 avatar Nov 20 '20 19:11 buguniao55555

Do you have a 1k resistor in place? It seems more like a hardware issue than a library issue.

LordPato avatar Nov 22 '20 20:11 LordPato

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

ttait-vantim avatar Dec 17 '20 20:12 ttait-vantim

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

buguniao55555 avatar Dec 28 '20 11:12 buguniao55555

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

ttait-vantim avatar Dec 29 '20 00:12 ttait-vantim

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.

VkTheProgrammer17 avatar Jan 23 '21 17:01 VkTheProgrammer17

i am also struggling because of same issue. is there any confirmed solution ?

xanderhn avatar Nov 25 '21 10:11 xanderhn