stray voltage on a few pins

Hello,

In the shown simple code, when I read the voltage and print to Serial, it fluctuates between HIGH and LOW, on it's own.
I have a wire going from 5v out on the arduino, to a switch, to Digital Pin 2, which is set as an INPUT....
I'm finding that the voltage fluctuates alot, and stays HIGH for a few seconds after re opening the switch. Sometimes even if I take the wire out of digital pin 2, and I put my fingers near the pin, it will pick up a HIGH... making my project frustrating... I'm using an Ethernet Shield on my arduino.
Any special config I need to do to clean those pins up?
Same set up works great on digital pin 4.. but on pin 2 and a few others I get these crazy readings.

#include <SPI.h>
int light;

void setup() {
  // put your setup code here, to run once:

  pinMode (2, INPUT);

  
  Serial.begin(9600);

}

void loop() {
  
  // put your main code here, to run repeatedly:
  
light = digitalRead(2);
  Serial.println(light);
  delay(1000);
}

Make some simple changes to keep the pin voltage level from 'floating:

byte light;

void setup() {
 // put your setup code here, to run once:

  pinMode (2, INPUT_PULLUP);

Serial.begin(9600);

}

void loop() {

  // put your main code here, to run repeatedly:

light = digitalRead(2);
Serial.println(light);
delay(1000);
}

Wire the pin's button to connect to Gnd when pressed.

Thank you,
As a newbie, a lot of that code you put I don't understand..... could you let me know how I should wire the switch to ground? it's a tact N.O switch. Thank you.... 5v in one side, and out the other side to a Digital Pin INPUT...
And I'll try to sort through your code.. thanks alot

Hi,
The input pin is a high impedance input, so it will hold the last state it was left at after you open your switch.
Putting your finger on the pin, your body acts as an aerial to electrical noise.

CrossRoads solution above turns on internal PULL_UP resistors, so if you connect your switch from input pin to gnd, when closed you get 0 on the input, when you open the switch the internal resistor pulls the input pin to 5v so makes it 1.

Tom.... :slight_smile:
Wire your switch, between input pin and gnd, not 5V and input like you had before.
gnd is a pin on your arduino...

I changed one line:

pinMode (2, INPUT_PULLUP);

That enables the on-chip pullup resistor. When nothing is connected to the pin, it will read back as High vs acting like an antenna and just having whatever voltage on it.

Wire the NO switch so that one leg connects to the pin, and the other leg connects to Gnd. When pressed, the pin will read back as Low.

Thank you, for some reason at first it showed with a whole bunch of other code.... the one line change you made I understand :slight_smile:
OK, I'll try the ground now.. :slight_smile: thanks.

One more question, will the pin's state be normally HIGH then? and when the switch is pressed, it goes to a LOW? So in my other code where I have a part that says if the pin is HIGH (when switch is pressed) do this and that, now I should change it to say if pin is LOW (when switch is pressed) do this and that ?

will the pin's state be normally HIGH then? and when the switch is pressed, it goes to a LOW?

Yes.
That is normal in the whole of electronics except the Arduino where for some unknown reason beginners like to think of HIGH as pressed.

Thanks for your help guys - I'm learning bit by bit.
Works great now....

Hi, I was having a similar problem with stray voltage keeping an led on after it was supposed to be off and thought this might be the solution. I guess that means I’m starting to understand this better.

However, I’m not using a button. I’m using a cheap key fob and its paired rx. The Rx has a signal wire and ground. Will the INPUT_PULLUP function be the best way to solve this problem using this configuration?

Will the INPUT_PULLUP function be the best way to solve this problem using this configuration?

Not usually, the signal is likely to be driven high or low so you don’t need a pull up resistor. However there is a sort of output signal that does need a pull up resistor, it is called an “open collector” output. Look at the data sheet of your module to see if it has that sort of output.

Its normal to switch to ground mainly for historical reasons, but it means you can use the chassis or box as the return from the switch in some circumstances.

All modern logic chips use CMOS technology which us made of MOSFETs. The inputs connect to the gates of MOSFETs, and gates are completely isolated electrically, they only influence the device through their voltage and no current flows (well extremely little, measured in picoamps).

Thus to define the state of a pin you have to impose a voltage on it - an open switch can't impose anything.

"Floating" pins are at the mercy of noise pickup from nearby wires and objects through capacitance. You should never be reading a floating pin, that will lead to unreliably behaviour.

Internal pullups on the chip can be enabled to make it easier to interface to switches, but they are not very "strong" - for switches on the other end of a long cable you'll likely need real pull-up resistors in the circuit which are much stronger (lower in resistance), perhaps a couple of kilo-ohms kind of value (the internal pullups can be thought of as resistors or value around 50k (they are actually implemented as FETs in reality).

Normal logic signals are always a defined voltage and never floating, no need for any pullup or pulldown then.

After further thought, I’m thinking the best way to do it will be to analogRead the pin and then use a threshold to turn the light on. Thank you for your replies.

PS,
I read up a little on “open collectors” and that’s kind of how I imagined “cleaning up” the voltage. It also seems kind of like a pull-up/down resistor, but on the Rx/signal wire side. Thanks again. I’ll read more and experiment with what I have.

Billyprps:
After further thought, I’m thinking the best way to do it will be to analogRead the pin and then use a threshold to turn the light on. Thank you for your replies.

That will only work if there's an analog sensor or a potentiometer controlling the pin voltage. Floating pins do not have a defined voltage at all, anything may happen, different pins will behave differently, different chips will behave differently, its completely bogus to rely on a floating voltage.

This worked pretty much how I wanted it to. I started at a 200 threshold and played with it until I got a result I liked. Little confused why the yellow signal wire from the fob rx needed to be connected to the ground and the blue wire to the A0 pin, but that's how it worked out.

int sensorPin = A0;
int ledPin = 3;
int sensorValue = 0;
const int threshold = 600;

void setup() {

pinMode(ledPin, OUTPUT);
Serial.begin(9600);

}

void loop() {

sensorValue = analogRead(sensorPin);
Serial.println(sensorValue);
delay(500);
if (sensorValue > threshold) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}

}

PS: welp, it was easy to figure out why the yellow wire was ground and the blue was signal... they were on the wrong terminals on the board. Thanks for the info.