Input pins flicker when I'm using all pins with input_pullup

So I made a gamepad out of cardboard and some buttons. I'm using Arduino Leonardo with this code I found:

// Simple example application that shows how to read four Arduino
// digital pins and map them to the USB Joystick library.
//
// Ground digital pins 9, 10, 11, and 12 to press the joystick 
// buttons 0, 1, 2, and 3.
//
// NOTE: This sketch file is for use with Arduino Leonardo and
//       Arduino Micro only.
//
// by Matthew Heironimus
// 2015-11-20
//--------------------------------------------------------------------

#include <Joystick.h>

Joystick_ Joystick;

void setup() {
  // Initialize Button Pins
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;

// Last state of the button
int lastButtonState[4] = {0,0,0,0};

void loop() {

  // Read pin values
  for (int index = 0; index < 4; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(50);
}

Everything works fine. I can use it in games etc. But here is the problem. I wanted to use every input possible(so pins 2-13 and A0-A5 that gives 18 in total). So I looked at this code and added required pinMode lines, changed lastButtonState from 4 to 18, added needed "0" in the same line and changed index from 4 to 18 as well. Here comes my problem. All of the inputs flicker in a random pattern when not pressed(even if nothing is connected to the board!) and only couple of them holds their state when pressed. Everything is connected properly and buttons were checked with multimeter.

Post the code that does not work.

Kudos for code tags on your first post. Most people do not bother to read how to use the forum before posting.

Oh sorry. Here is that not working code. Also I'm a complete newbie so please I will appreciate any help.

// Simple example application that shows how to read four Arduino
// digital pins and map them to the USB Joystick library.
//
// Ground digital pins 9, 10, 11, and 12 to press the joystick 
// buttons 0, 1, 2, and 3.
//
// NOTE: This sketch file is for use with Arduino Leonardo and
//       Arduino Micro only.
//
// by Matthew Heironimus
// 2015-11-20
//--------------------------------------------------------------------

#include <Joystick.h>

Joystick_ Joystick;

void setup() {
  // Initialize Button Pins
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
  pinMode(A0, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
  pinMode(A2, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A5, INPUT_PULLUP);
  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;

// Last state of the button
int lastButtonState[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void loop() {

  // Read pin values
  for (int index = 0; index < 18; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(50);
}

Also if I can't use all pins is there an option to use matrix or handle some of the buttons to an arduino Uno and send the data via serial or something? If not then I'm gonna just buy another one and I will use both.

The builtin pullups are very weak, about 20k to 50k, which usually is not enough if you have long wires
connected to the pins, due to noise pick up.

Improving the layout may help - logic signals are very sensitive and are best routed alongside a ground
return wire and kept short.

Will using external pull up resistors help? Also can I just use regular input instead of pull up config?

Yankiel:
Will using external pull up resistors help? Also can I just use regular input instead of pull up config?

Yes you can use regular INPUT, but you will definitely need external pullups.
Tom.... :slight_smile:

So I Learned couple things:

  1. I found this in tutorial about pull up resistors:

So why was the LED flickering? Simply the logic static of the open switch is floating so it could be either a '0' or a '1. When the button is pressed this produces a clear logic state of LOW since its grounded.

Now I know why my inputs flicker and that makes my gamepad useless.
2) Using regular input just does not work. Inputs flicker as well and they not even reacting to pressed button

All that makes me think that my board is broken

All that makes me think that my board is broken

No, if it does you have not understood what it says.
You need to connect your buttons between the input and ground and use the INPUT_PULLUP when you set the pin mode. Then you look for a lowa when the button is pressed.
If you still have problems then add an extra 1K resistor between the input and 5V.

If you still have problems then post a schematic, note that is a schematic not a Fritzing physical layout piece of crap. A Photo clearly showing your wiring would also help.

Yankiel:
2) Using regular input just does not work. Inputs flicker as well and they not even reacting to pressed button

All that makes me think that my board is broken

What value of external pullup resistors are you using?
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

How long are the wires from the switches to the controller?

Thanks.. Tom.. :slight_smile:

Hi,

 pinMode(1, INPUT_PULLUP);

This pin is one of the programming pins, best not to use it.

int currentButtonState = !digitalRead(index + pinToButtonMap);

So you read a button input, inputs are from 1 to 18.

const int pinToButtonMap = 9;

So the first pin you read is 0 + 9 = 9.
The last pin you read is 17 + 9 = 26.

You are not reading pins 1 to 18.

Tom.... :slight_smile:

Okay. Here is the schematic made in EasyEDA. I've read that arduino have it's own pull up resistors so I didn't bother to add external ones at the beginning.

TomGeorge:
This pin is one of the programming pins, best not to use it.

I fixed it as soon as I saw it. And I'm using pins 2-13, A0-A5

TomGeorge:
So the first pin you read is 0 + 9 = 9.
The last pin you read is 17 + 9 = 26.

You are not reading pins 1 to 18.

So I should put 0 in there right?

OP image.

How to post images so we don't have to down load them.

groundFungus:
OP image.

Sorry I had no idea how to put it like this and imgur link wasn't working

TomGeorge:

 pinMode(1, INPUT_PULLUP);

This pin is one of the programming pins, best not to use it.

Not on a Leonardo. Pins 0 and 1 can be used freely if you are not using Serial1.

Hi,
Why do you declare pin 1 as an input?
You aren't using it!

You will need to check your pin mapping;
The digital pins are in your case, 2,3,4,5,6,7,8,9,10,11,12,13, then 18,19,20,21,22,23.

Not 2,3,4 all the way to 17..

Tom... :slight_smile:

Okay so after some tweaking I'm able to use all digital pins(I mean from 2 to 13) flawlessly with input_pullup resistors built in Arduino. I just changed pinToButtonMap to 2 and here is the code:

#include <Joystick.h>

Joystick_ Joystick;

void setup() {
  // Initialize Button Pins
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 2;

// Last state of the button
int lastButtonState[12] = {0,0,0,0,0,0,0,0,0,0,0,0};

void loop() {

  // Read pin values
  for (int index = 0; index < 12; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(50);
}

So now I would like to use analog pins as a digital inputs.
From this image I can see that they are pins 18 to 23. I assume that in line where I have pinToButtonMap should be something like this:
for pins 2 to 13 use pinToButtonMap = 2
for pins 18 to 23 use pinToButtonMap = 18
Correct me if I'm wrong.

No the analogue pins can be addressed as digital using the pin numbers 14 to 18.

And as we told you you have a Leonardo so pins 0 and 1 can be used as well.

See that code in setup where you take a line to specify the pin mode of each pin. You could replace all that in two lines of code with a simple for loop and use the loop index to specify the pin number.

Also the reading of your pins could be just

values
  for (int index = 2; index < 14; index++)
  {
    int currentButtonState = !digitalRead(index);

Grumpy_Mike:
No the analogue pins can be addressed as digital using the pin numbers 14 to 18.

Analog pins of Leonardo are 18 to 23, see post #16.
Tom... :slight_smile:

YES! Everything(well... almost) works flawlessly! Only digital pins 2 and 3 are not working but I can live without them. Maybe because I accidentaly shorted 5v and ground twice. Thank you all for patience and help.