Digital Pins on Leonardo misbehaving

Hey all!

So I'm a longtime lurker, first time poster, and I'm having a really odd problem with my Leonardo.

I had hooked up some momentary push buttons (open when unpressed) into digital pins 2,3,4 and 5 with the goal of making a really simple binary calculator (each button represents a bit). I hooked up 4 LED's to pins 6,7,8 and 9 and set up a really quick test to make sure everything was wired correctly. All the buttons were wired up to 3.3 volts and all the LED's to the common ground.

I initialized all the pins and wrote the following lines into loop().

void loop()
{
   digitalWrite(pin6,digitalRead(pin2));
   digitalWrite(pin7,digitalRead(pin3));
   //etc...
}

The button on pin 2 worked fine; when I pushed the button, the light on pin 6 turned on pretty much instantly, and went off again once I released the button. The button on pin 3 also worked fine (although I noticed a very small, but noticeable, lag).

Things got weird though with the button on pin 4. Somehow the lights on both pin 6 and pin 7 turned on, although the one on pin 7 was much brighter than the one on pin 6. I measured the voltage, and pin 7 had approximately double the voltage of pin 6. The button on pin 5 doesn't seem to do anything at all, but the light flashes erratically.

Do I need to use IORef to power my buttons? I read somewhere that IORef just outputs the voltage that the board is running at for shields and stuff (which would translate to 5 volts in the case of the Leonardo) I tried putting 5 volts instead of 3.3 into the buttons, but that didn't change anything. I also confirmed that it wasn't the buttons, I switched them around in every combination I could think of, and that didn't affect anything. So, I'm assuming it's probably bad pins.

Is there anything I can do to diagnose what's going on and potentially fix it?

Code snippets don't help, so post your full code.

Are you using pull-up or pull-down resistors?

Pick better variable names than "pin2" and "pin3". This is especially confusing when you set "pin2" to a value of "4". Use names that make sense to the function, not just describing the Arduino hardware.

int onesPlaceButton = 2; //all these names were based on the idea of using this as a binary calculator later.
int twosPlaceButton = 3; 
int foursPlaceButton = 4;
int eightsPlaceButton = 5;
int onesPlaceLight = 6;
int twosPlaceLight = 7;
int foursPlaceLight = 8;
int eightsPlaceLight = 9;
void setup()
{
   pinMode(onesPlaceButton, INPUT);
   pinMode(twosPlaceButton,INPUT);
   pinMode(foursPlaceButton,INPUT);
   pinMode(eightsPlaceButton,INPUT);
   pinMode(onesPlaceLight,OUTPUT);
   pinMode(twosPlaceLight,OUTPUT);
   pinMode(foursPlaceLight,OUTPUT);
   pinMode(eightsPlaceLight,OUTPUT);
}
void loop()
{
   digitalWrite(onesPlaceLight,digitalRead(onesPlaceButton));
   digitalWrite(twosPlaceLight,digitalRead(twosPlaceButton));
   digitalWrite(foursPlaceLight,digitalRead(foursPlaceButton));
   digitalWrite(eightsPlaceLight,digitalRead(eightsPlaceButton));
}

So basically all I was trying to do in this test was a sanity check to make sure all the buttons and LED's were functioning properly. However, as I stated above, only the onesPlace and twosPlace buttons worked correctly, the other two behaved very erratically.

I set the button pins as INPUT so I would assume that means they were using the internal pull-up resistors? I'm not sure.

I set the button pins as INPUT so I would assume that means they were using the internal pull-up resistors? I'm not sure.

Wrong assumption to make. If you want internal pull-up to be enabled for an input pin you have to state it explicitly.

pinMode(ButtonPin, INPUT_PULLUP);

Or

pinMode(ButtonPin, INPUT);
digitalWrite(ButtonPin, HIGH);

Lefty

Could that fix the erratic behavior I was seeing?

On a side note, what's the difference between a pull-up and pull-down resistor?

nameless912:
Could that fix the erratic behavior I was seeing?

On a side note, what's the difference between a pull-up and pull-down resistor?

With a button switch not being pressed there is no valid logic voltage applied to a input pin and it will be said to be a floating input condition and will read erratically due to circuit noise. If an external pull-down resistor is wired between the input pin and ground it will provide a default 0 vdc or LOW condition to the pin while the button is not being pressed and if the other contact side of the button switch is wired to +5vdc then the pin will see a HIGH when pressed. If a pull-up is wired between the input pin and +5vdc (or the internal software pull-up pin is enabled) the pin will read a default HIGH when the button is not being pressed and if the other side of the switch contacts is wired to ground then the pin will read a LOW when the button is pressed.

Some form of pull-up or pull-down is always required when reading simple passive switch contacts.

Lefty

Ah okay, so basically what your'e saying is that in order to get a clean signal I should always use the internal pulldown/pullups on digital inputs? I understand why that makes sense now in this case, but I want to make sure that I don't break anything If I use them in the wrong context :slight_smile:

EDIT: Nevermind, I just saw the last sentence of Lefty's post.

So let me make sure I've got this right: the internal pullup resistors can be set by using INPUT_PULLUP instead of just INPUT, and will read high when the button is open and connected to ground. When the button is pushed, the pin will read low.

And to use a pulldown resistor, I just need to put a resistor between my button/switch/whatever and the input pin, and that should clean up the noise?

I should always use the internal pulldown/pullups on digital inputs?

Internal resistors are pullups only.

nameless912:
Ah okay, so basically what your'e saying is that in order to get a clean signal I should always use the internal pulldown/pullups on digital inputs? I understand why that makes sense now in this case, but I want to make sure that I don't break anything If I use them in the wrong context :slight_smile:

Well there is only an internal pull-up option available, no internal pull-down option. External resistor is required if you need to have a pull-down state.

Keep in mind that which you use, pull-up or pull-down, effects how you interpret the state of a button, using a pull down means the digitalRead will return a HIGH when the button is pressed and using a pull-up means digitalRead will return a LOW when the button is pressed.

Lefty

Alright, makes sense.

Thanks a lot!

nameless912:
Ah okay, so basically what your'e saying is that in order to get a clean signal I should always use the internal pulldown/pullups on digital inputs?

If you want to see video of a scope showing why you need to use pull-ups, see below:

http://www.cmiyc.com/tutorials/arduino-pull-ups/

Have a look at the schematic in this tutorial, which is a pull-down example.

The reason, by the way, that it needs to be a resistor not just a piece of wire can be seen from that diagram. If it was just wire right thru where the resistor is, when the switch was closed the switch will cause a dead short between the 5v and ground. That will be expensive.

On the other hand, as a resistor, when the switch is open there's "enough" connection to ground for the input pin to read low. Then when the switch is closed, the plain wire connection to 5v "wins" the battle and there's a better connection to 5 than to ground, so the pin reads high.

Thanks a bunch James and Jimbo!

This whole pullup/pulldown nonsense makes a lot more sense now haha.

This whole pullup/pulldown nonsense makes a lot more sense now

Taking the non out of non-sense... 8)