2026 · 08 · 16

The haunted potentiometer

I spent an evening accidentally building a capacitive touch sensor.

The plan was Week 3 of the robotics year: read a potentiometer, drive a servo. Read input, transform, drive output, repeat. The first closed control loop, with my hand still inside it. It worked in about twenty minutes.

Then it started answering to me touching the pot. Not turning it. Touching it. The servo would swing to one end, jitter, and come back, all while the knob sat perfectly still.

Illustrated bench setup on a blue ESD mat: an Arduino UNO R4 WiFi wired to a potentiometer at lower left, a full size breadboard in the middle, and an MG996R servo at right, with bench supply leads clipped in through a red alligator clip.
The rig. The potentiometer is at lower left, and its ground jumper is the entire story.

My first instinct was to read the code. That is the tell. Software trains you to assume the layer below you is deterministic, so when something behaves strangely the explanation must be upstream, in your own logic. Wrong assumption, wrong state, wrong ordering. That instinct is right almost every time in software, and it is exactly what makes hardware debugging feel like the floor has been removed.

There was no bug. The core of the loop is three lines, and it had been working for an hour.

What helped was reading the shape of the data instead of the values.

I logged raw ADC counts. The signal sat at 588 for hundreds of consecutive samples, wobbling by a single count. Then one sample at 1003. Then straight back to 588. Later, a sustained plateau at 1003 for half a second, then back again.

That shape means something specific. Electrical noise is continuous and small, a couple of counts, always present. Contact bounce is a burst of transitions inside a few milliseconds. But a rock steady baseline with occasional excursions that hug the rails is not noise at all. It is a connection that is intermittently absent.

Once the wire opens, the pin floats, and a floating input picks up your body like an antenna. So the touch sensitivity was real, but it was a symptom of the break rather than the cause of it. I had built the world’s worst proximity sensor, and it only worked while something else was broken.

In software, “it only works when I hold it” is a joke. On the bench it is a diagnosis.

The culprit was a ground wire. Specifically the female DuPont jumper on the pot’s ground leg. Those sockets are crimped to grip square 0.64 mm header pins. A potentiometer’s legs are flat and thin, so the socket catches on two edges instead of clamping four faces. Hold it and the circuit is perfect. Let go and it is a coin flip.

Ground, naturally. The one connection everything else is measured against. A flaky ground does not hand you one clean symptom, it hands you three unrelated looking ones at once, which is why I spent a while convinced I had three problems.

The learning, such as it is.

Isolate the half you can test alone. I could not tell what was wrong while the pot and the servo were both in the loop. The moment I flashed a sketch that only read the pot and printed it, the servo stopped being a suspect.

Read the signature, not the number. Steady baseline plus rail hugging spikes means open circuit. I can now tell three failure modes apart from a log alone, and I collected all three in one week without meaning to.

Do not filter a fault away. I could have rejected any sample that jumped more than 200 counts, since no human hand moves a knob that far in 20 milliseconds. It would have looked fixed. It would also have hidden a loose wire until it came back six months later wearing a different costume.

And when several unrelated things break at once, suspect ground first.

Next up: steppers, and the first time open loop control lies to me on purpose.