ESP32 binary sensors flip flopping despite internal or external (10K) pullup or pulldown resistors

I have a problem with ESP-32 (Dev Kit C V4) binary sensors flip flopping.

I am only using normal input/ output GPIO pins (i.e. not strapping pins)

I have tried internal pullup resistors. I have then tried 10K external resistors but in pullup and pulldown configurations

I suspect it may be due to interference being picked up by the 3m lead between the ESP32 and the limit switches that are connected to the binary sensors

I wonder if it might be worth using 5V for the switch circuits and then a step down optocoupler in case that increases the signal to noise ratio in that 3m lead?

I have had this problem before and trying other pins has normally resolved it. However this time I am using all the normal GPIO pins, so no option to swap them

Thanks in advance for any suggestions

Add a delayed_on_off filter fixed it

Software filtering as you mention is a cheap solution.

For future reference, a few other approaches to improve noise immunity:

  1. Change to a double-throw switch toggling between VCC and GND. Does require an extra wire in your cable to your switch.
    a. As a bonus, this allows you to check if the switch is connected. Enable pullup on the input, see if the input is high, enable pulldown on the input, see if the input is low. Do that quickly a few times. If the input follows the pulls, the switch is either disconnected, broken, sitting exactly at the middle break-before-make position (unlikely), or being toggled exactly at the same rate as your pullup/pulldown toggle (unlikely).
  2. An external Schmitt trigger at the IO pin (or if you already have one, a Schmitt trigger with a higher hysteresis, or a microcontroller that has Schmitt-trigger inputs built-in). ESP-32 doesn’t have Schmitt triggers on the inputs I don’t believe…
    a. You can do a poor-man’s Schmitt trigger by just having a resistor at the input and enabling pull-up when you see a 1 and pull-down when you see a 0. Not great by any means, and doesn’t really work with a single-pole switch, but still a fun little technique to keep in your back pocket.
  3. Reduce your pullup / pulldown resistor. Hurts power draw of course.
  4. A choke on the line close to the ESP-32. Ferrite beads are cheap & simple and don’t tend to hurt. Does somewhat hurt response time for obvious reasons. Not typically enough to be noticeable.
  5. A RC filter close to the ESP-32. Does somewhat hurt response time for obvious reasons. Not typically enough to be noticeable.
  6. Use a shielded cable.
  7. Increase signal voltage. Again, hurts power draw of course.
  8. Reduce cable length. Isn’t always feasible of course.

(Why would you use these over software filtering? For one, these work even if you’re having metastability or latchup issues.)

There are of course more complex approaches too (such as driving a pseudorandom signal and checking correlation, or reworking to get a differential signal, or moving to the digital domain closer to the sensor e.g. by putting a microcontroller at the sensor itself). Way overkill here however.

Sorry for the delayed response

Many thanks for these very helpful suggestions!

Unfortunately I have no way to change the wiring because it’s part of a third party component. I suppose I could cut their wire short and then use shielded twisted pair wiring for the main run.

However before seeing your response, I had already decided to try an RC filter which is obviously one of your suggestions. So adding a 10nf decoupling capacitor between each input and GND and smaller 1K resistor in series with the each switch

Input 1 |— pullup 10K resistor — VCC
|— 10nf capacitor — GND
|— 1K resistor — Switch 1

Hope my simplistic diagram makes sense!

So when switch in N/C, input is pulled up and decoupled. When switch goes to GND, the smaller resistor pulls it to GND

Waiting to try it…

Many thanks!