Button project. Is voltage necessary?

:+1:
Debouncing via software is so simple that it really isn't worth using HW for it

To quote a very knowledgeable person on this forum: :wink:

You will see that with Rpu=Rsw=5 kΩ and C=6µF, the digital input will never be pulled low — the capacitor voltage will have a lower limit of 2.5 V.

In addition, making the two resistors equal, the two time constants will not equal! You'll get 30 ms on charging, but half that (15 ms) on discharging.

Writing the ODEs shows that the two time constants can never be equal. For the switch open and closed, respectively:

τopen = RpuC

τclosed = RpuRswC / (Rpu + Rsw)

The minimum state pin voltage (Vmin) on switch closure is given by

Vmin = RswVcc / (Rpu + Rsw)

which gives

Vmin / Vcc = τclosed / τopen

For the digital input to switch from HIGH to LOW, we need Vmin < Vil. This establishes the following relationship between the two time constants:

τclosed / τopen < Vil / Vcc

I hope this clarifies why I chose different resistance values for the pull-up resistor and the switch series resistor!

Right, need to take my own advice

This will pull the pin low but has different time constatnts.

You can play around with something like this if you need symmetrical time constants:

I've liked these:

The Ganssle paper gives equations for selecting values of the circuits posted above.

So now we're up to circuits with 3 - 5 components (including an active component) all to avoid the trivial ask of debouncing in the code.

The Ganssle writeup has this:

Consider the simplest of all debouncing strategies: read the switch once every 500 msec or so, and set a flag indicating the input's state. No reasonable switch will bounce that long. A read during the initial bounce period returns a zero or a one indicating the switch's indeterminate state. No matter how we interpret the data (i.e., switch on or off) the result is meaningful. The slow read rate keeps the routine from deducing that bounces are multiple switch closures.

I do that sometimes with code like:

bool pollIO() {
  const uint32_t PollInterval = 50;
  static uint32_t lastIoMs = -PollInterval;
  bool polled = false;
  if (now - lastIoMs > PollInterval) {
    lastIoMs = now;
    switchVal = digitalRead(SwitchPin);
    potVal = analogRead(PotPin);
    //...
    polled = true;
  }
  return polled;
}
Example

Wokwi - Online ESP32, STM32, Arduino Simulator

// https://wokwi.com/projects/427234882861614081
// for https://forum.arduino.cc/t/button-project-is-voltage-necessary/1369536/47
//
// Periodically poll the inputs 
// Also do state-change detection on the polled inputs 
//

const int SwitchPin = 2;
const int PotPin = A0;

int potVal = -1, lastPotVal = -1;
int switchVal = -1, lastSwitchVal = -1;

uint32_t now;

void setup() {
  Serial.begin(115200);
  pinMode(SwitchPin, INPUT_PULLUP);
}

void loop() {
  now = millis();
  if (pollIO()) {
    if (switchVal != lastSwitchVal) {
      Serial.print("Switch:");
      Serial.println(switchVal);
      lastSwitchVal = switchVal;
    }
    if (abs(potVal - lastPotVal) > 2) {
      Serial.print("Pot:");
      Serial.println(potVal);
      lastPotVal = potVal;
    }
  }
}


bool pollIO() {
  const uint32_t PollInterval = 50;
  static uint32_t lastIoMs = -PollInterval;
  bool polled = false;
  if (now - lastIoMs > PollInterval) {
    lastIoMs = now;
    switchVal = digitalRead(SwitchPin);
    potVal = analogRead(PotPin);
    //...
    polled = true;
  }
  return polled;
}

Cant claim 5 sigma Jim, it wasnt a PhD project. Lots - it was a bit obsessive to try to find a really bad switch. Tested some relays as well to see the difference, and some old switches from my rally car days.
The results I show on my site are for switches that are commonly used in simple arduino projects, but I've also posted the sketch so anyone can test their own.

Feel free to give it a try.

I agree with everything you say except the part about the current cleaning the contacts and putting a cap directly across a switch.

I think you are referring to what is called "wetting current" when you talk about current cleaning the contacts. Certainly, depending on the presence or type of contact plating, a certain minimum current is necessary to prevent a buildup of surface contamination.
A capacitor in parallel with the switch contacts, if the correct value, can reduce arcing but I don't know what effect it has on bounce. Perhaps that effect is what your experiments show.

Thanks @Jim. Perhaps your concern is that the stored energy could possibly cause metal to transfer between the contacts, or even weld them together.
With a sensible size of cap I think thats unlikely as the energy is so small, and the self inductance and resisitance will limit the current. Maybe if/when I get time I'll look again at the waveform. If I'm right you have some experience with RF?

yes @EmilyJane thanks wetting current.

Yes, I have first hand experience with that and a reed switch.

@Jim I've discovered another benefit of putting a small cap across the switch contacts.
I have a switch triggering an interrupt.
On approaching the switch the input was picking up signals (likely mains), and connecting a 0.047 uF cap across the contacts fixed it.
When the switch is open the wire from the arduino to the switch is an antenna, connected to a relatively high impedance input (even when its input-pullup).