DigitalRead Voltage

Hi Folks,

I have a few different arduinos, the mini, the micro and the uno.

I am currently working on the uno, were I need to read a button press. The thing is, the button seems to be triggered by the slightest of voltage, for example, I have connected a male to male breadboard wire, to pin 2 of the uno, and if I hold my fingers against the other end, the "button" is triggered. This is causing issues, because when connected into the circuit, it seems to be picking up residual current from the breadboard, or from the slightest touch, which then invokes the switch and makes the code progress.

Is there a way to configure the pin to only consider a "press" if the voltage to the pin is say, above 3.3v, as I am guessing its set to "any" voltage which in this case could be triggered by the skin voltage of 0.2v.

Thanks

That's normal behaviour for a floating pin connected to a wire acting as an antenna. If you really need it to be active HIGH then you need to add a pull-down resistor about 10-20K between the pin and GND.

For switches it's more normal to have them active LOW in which case you set pinMode(pin, INPUT_PULLUP), connect the switch between the pin and GND and you don't need any resistor. Then the pin will normally be HIGH and will read LOW when the switch is on or pressed.

Steve

Hi Steve,

I have no real preference as to the active state - whether low, or high. As long as when the button is pressed, its acknowledged.

This is my code below, is it as simple as inverting the reading == HIGH and reading == LOW values?

// Set PWM PIN Number
const int pwm = 9 ;     //initializing pin 2 as ‘pwm’ variable

// Touch Sensor Switch
int inPin = 2;         // the number of the input pin
int outPin = 13;       // the number of the output pin

int state = LOW;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = HIGH;    // the previous reading from the input pin
pinMode(inPin, INPUT_PULLUP)

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers
bool up = true;
int x = 0;

// Set Option
int PWMOption = 0;       // Option 0 indicates off, 1 = 25%, 2 = 50%, 3 = 75%, 4 = 100%
int PWMPrevOption = 0;     // The previous chosen PWM Option (used to compare and set the new flash count
void setup() {
  // put your setup code here, to run once:

 // Set the configuration for Serial and PINmodes
  Serial.begin(115200);     // Set the Serial Port BAUD rate, which must match the Monitor
Serial.println("Created: ");  // Output to Serial Monitor
Serial.println(__TIME__);     // Current Time
Serial.println(", ");         // Space beween strings
Serial.println(__DATE__);   // Current Date

// pinMode(LED_BUILTIN, OUTPUT);  // sets the pinmode - required to outut onboard LED state

   pinMode(inPin, INPUT);   // Input PIN - the pin receiving the signal from the switch
  pinMode(outPin, OUTPUT);  // Output PIN - the pin we are sending a signal to as a result of the triggered input pin 
}

void loop() {
  // put your main code here, to run repeatedly:

  //----------------------------------------------------------------------------------------------------------------------------------
  //Code begins notification
  //----------------------------------------------------------------------------------------------------------------------------------

  Serial.println("Loop Start");
  Serial.println(x);
  Serial.println("Current PWM Option");
  Serial.println(PWMOption);

  //----------------------------------------------------------------------------------------------------------------------------------
  // Identify the brightness and count
  //----------------------------------------------------------------------------------------------------------------------------------
  
if (up == true) {         // If we are counting up to 255, add 1 to the existing number = this would fade up any LED connected
  x = x +1;
  //Serial.println("+1");
}

if (up == false) {        // If we are counting down from 255, subtract 1 from the existing number = this would fade down any LED connected
  x = x -1;
  //Serial.println("-1");
}

if (x == 255) {           // When we reach the limit of the highest bit (255) we need to set the prgram to start counting down
    up = false;
    //Serial.println("Going Up");
}

if (x == 0) {             // When we reach the limit of the lowest bit (0) we need to set the prgram to start counting up
    up = true;
    //Serial.println("Going Down");
}

//----------------------------------------------------------------------------------------------------------------------------------
//Light control - illuminate the external LED 
//----------------------------------------------------------------------------------------------------------------------------------

delay(1000);
analogWrite(outPin,x);    // Write to the outpt pin the current brightness level, which should fade in and out the LED - showing the service is running

//----------------------------------------------------------------------------------------------------------------------------------
//Button Control
//----------------------------------------------------------------------------------------------------------------------------------

reading = digitalRead(inPin);    // sets the LOW / HIGH (OFF / ON) status of the switch

if (reading == HIGH) {
Serial.println("Button has been pressed") ;

delay(2000);

//----------------------------------------------------------------------------------------------------------------------------------
//Respond to button press
//----------------------------------------------------------------------------------------------------------------------------------

   if (reading == HIGH && millis() - time > debounce) {   // If this looks like it was a valid button press
     Serial.println("reading High and Previous Low");   

      if (state == HIGH) {      // If the switch was activated as a one off and the value was set then
      Serial.println("State is now High for button press");
      state = LOW;          // Set the opposing value
      Serial.println("State is now set to low for button press");
       Serial.println("reading High and Previous Low");
      Serial.println("Before PWMOption is");
      Serial.println(PWMOption);   
      Serial.println("The current state is now");
      Serial.println(state);
      delay(5000);
         }
         
      else {
      
     // state = HIGH;         // Set the opposing value
            Serial.println("Before PWMOption is");
      Serial.println(PWMOption);
      delay(2000);
      Serial.println("Increasing PWM Count now");
      delay(2000);
      PWMOption = PWMOption + 1;  // Increase the output by 25%
      Serial.println("New PWMOption is");
      Serial.println(PWMOption);
      delay(2500);
      delay(25000);
    time = millis();        // Set the time in misseconds
    //state= LOW;

previous = reading;   // Set the value.
Serial.println("Previous Status Changed");
Serial.println(previous);
        
      }
    }

}
//----------------------------------------------------------------------------------------------------------------------------------
//PWM Control - Setting
//----------------------------------------------------------------------------------------------------------------------------------

    if (PWMOption < 5) {      // If the state can be increased then
     // Serial.println("PWM Is less than 4");
     // Serial.println("The current PWM Option under review is ");
   
  //  PWMOption = PWMOption + 1;  // Increase the output by 25% //Moved up 
  Serial.println("The new PWM Option is");
  Serial.println(PWMOption);
    }
    else       {             // otherwise
    Serial.println("This suggests the PWMOption is not less than 4");
        PWMOption = 0;           // Reset the cycle and turn the fan off.
        Serial.println("Reset Cycle to 0");
        Serial.println("Light On");
  }

//----------------------------------------------------------------------------------------------------------------------------------
//PWM Control - Modulate PWM
//----------------------------------------------------------------------------------------------------------------------------------
  delay(2500);
  digitalWrite(outPin, state);    // Output the state of On/Off to the outpin (in this case, change the LED on/off)
     
........

ard2dee2:
Is there a way to configure the pin to only consider a "press" if the voltage to the pin is say, above 3.3v, as I am guessing its set to "any" voltage which in this case could be triggered by the skin voltage of 0.2v.

Thanks

Skin voltage will usually be 10 to 50Vac. You are an antenna picking up mains from all the mains cable surrounding you in a building. Unless you sit in a grounded Faraday cage you'll be floating at such
voltages all the time from capacitive pickup from the surroundings.

You must always avoid floating inputs with CMOS logic, as inputs are extremely high impedance (10^13 ohms is typical), and pick up anything if left to float.

Hi Mark, you will have to excuse me, as I am new to all this hardware control logic…

What do you mean to avoid floating inputs etc? (are you able to simplify it for the idiot within me?)

Wire your switch inputs in one of these 3 configurations:


“ (are you able to simplify it for the idiot within me?)”

No need for this kind of language.

ard2dee2:
Hi Mark, you will have to excuse me, as I am new to all this hardware control logic...

What do you mean to avoid floating inputs etc? (are you able to simplify it for the idiot within me?)

Read this: Gammon Forum : Electronics : Microprocessors : Switches tutorial

If the pin isn't connected to some voltage then it is floating and can read any voltage. So pins that are unconnected when the button isn't pressed can read presses just from the noise. That's why we use pull-up and pull-down resistors. Google those terms and you'll get a ton if info, "floating input" "pull-up resistor" "pull-down resistor". You need a resistor between your pin and some known value so you can make it read something particular when the button isn't pressed.

The board has pull-up resistors built in. So as long as you wire your button so it connects the pin to Ground and makes the pin LOW when pressed then you can use INPUT_PULLUP in your pinMode call and you don't need any extra parts.

larryd:
Wire your switch inputs in one of these 3 configurations:


“ (are you able to simplify it for the idiot within me?)”

No need for this kind of language.

Thanks Larry, first of all, I will take a look. my ability to read wiring diagrams is poor at best, so I will take a look and try interpret it correctly. As for my rhetoric, thats just me :slight_smile: I review myself honestly and the language is limited to reviewing myself and never anyone else!

Delta_G:
Read this: Gammon Forum : Electronics : Microprocessors : Switches tutorial

If the pin isn't connected to some voltage then it is floating and can read any voltage.

Thanks Delta, the site you referenced combined with the explanations Larry and yourself provided, now make more sense, and give me a direction to head with the next round of work!

“ As for my rhetoric, thats just me :slight_smile: I review myself honestly and the language is limited to reviewing myself and never anyone else!”

I’m sure you can teach us a thing or two in your area(s) of expertise. ;).

So, my lessons are

  1. Never eat yellow snow
  2. Mock yourself and no one else can mock you
  3. If you blow something up in the house only do it once
  4. If you blow something up twice, don't tell the wife, she will not be pleased
  5. Should you ever choose to lick a toad, avoid the cane toad
  6. If you haven't turned it off then on again, don't bother calling IT
  7. Exercise is dangerous, People die from it, don't do exercise.

five of those I have direct experience with, two of them are learned from cartoons. I wont spoil the judgement of which are which.

In the meantime, I have to get back to my Linux side of the laptop and then I am going to change the code to accommodate the pin 8, I think I will end up going for the internal pull-up resistor method. Shame I can't download the code running on the arduino to transfer it between windows and linux...

One thing I noted in my code, was a lack of comparing of button press state, I went down the line of "when it goes high, tell yourself its low". so I should probably review this also.

ard2dee2:
Hi Mark, you will have to excuse me, as I am new to all this hardware control logic...

What do you mean to avoid floating inputs etc? (are you able to simplify it for the idiot within me?)

A CMOS input is effectively isolated(*), so will adopt voltage of nearby objects and charges through
electrostatic induction and capacitive coupling (same thing really). Its voltage if unconnected will be
all over the place and not defined.

This is because the MOSFETs on the chip have a layer of silicon dioxide (ie quartz) between the gate and
the channel, and quartz is an extremely good insulator. The electric field across this layer of oxide is
what controls the output circuit in a "field effect" transistor, FET. No current can flow across the oxide though.

(*) Unless the voltage strays too far outside the supply rails, and is then constrained by diodes.

As already mentioned , you have to choose a known state (high or low) for a CMOS input.
Your resistor can be a pullup or pulldown, depending on the application but you cannot just
leave a CMOS input floating (not tied to any voltage) because it will be unreliable (unpredicable)

Not unexpected in the slightest, that following the guidance of the correct use of pullup and voltage, the button now works as expected. I went for the pin 8, internal resistance method!

Thank you to you all for your patience and explaining.

You could have found it here

or here:

ard2dee2:
So, my lessons are

  1. Never eat yellow snow
  2. Mock yourself and no one else can mock you
  3. If you blow something up in the house only do it once
  4. If you blow something up twice, don't tell the wife, she will not be pleased
  5. Should you ever choose to lick a toad, avoid the cane toad
  6. If you haven't turned it off then on again, don't bother calling IT
  7. Exercise is dangerous, People die from it, don't do exercise.

five of those I have direct experience with, two of them are learned from cartoons. I wont spoil the judgement of which are which.

+1 Karma for that! as for the rest of the discussion, it seems you now understand what is happening. :grin:

haha, thanks Paul, and yes its nice to have learned something new!