slim joystick/Six buttons on one wire/06. Telling them apart
Six buttons on one wire · 06 of 11

Telling them apart

Seven levels on one pin: six buttons and nothing. A sketch reads BTNS and asks which level it is nearest, by drawing a line halfway between each pair of neighbours. The closest pair, U8 and U6, are 0.11 V apart, which is about 22 counts on an Uno and 34 on a Pico: plenty, if the lines sit halfway and 3V3 is on 3V3.

Seven levels, six lines

Telling them apart
Your board
U11 reads
675
Closest pair
U8, U6: 22 apart
In volts
0.11 V apart
With 3V3 on the header and an Uno measuring against 5 V, the six levels are 675, 338, 225, 169, 135, 113, and nothing is 0. The top third of the scale is never used. The closest two, U8 and U6, are 22 counts apart: plenty, if the lines sit halfway.

BTNS can sit at seven levels: all of 3V3, a half, a third, a quarter, a fifth, a sixth, and 0. A sketch reads it and has to say which. The simple way is to draw a line halfway between each pair of neighbours; a reading above a line and below the one over it is that button.

In millivolts, with 3V3 on the header, the six lines are:

Aboveand belowis
2475 mVU11
1375 mV2475 mVU10
963 mV1375 mVU5
743 mV963 mVU7
605 mV743 mVU8
275 mV605 mVU6
275 mVnothing

The sketches carry exactly this list, highest first, and stop at the first line the reading is above:

const int LIMIT_MV[] = {2475, 1375, 963, 743, 605, 275};

Millivolts, so one list fits every board

An Uno counts against 5 V, a Pico against 3.3 V, and an ESP32 against a reference of its own. A count means something different on each, so the sketches convert to millivolts first. On an ESP32 and an ESP32-S3, analogReadMilliVolts does it with calibration stored in the chip; on an Uno and a Pico the count is scaled by the ADC's full scale, 5000 mV or 3300 mV. Then one list of lines works everywhere.

The ESP32's ADC reads nothing below about 0.1 V and tops out near 3.1 V at the Arduino core's default setting. Neither end matters here: the lowest button, U6, is at 0.55 V, and U11's full 3.3 V reads as the top of the scale, far above its line at 2475 mV.

How much room there is

The tightest pair is U8 and U6, a fifth and a sixth of 3.3 V: 0.66 V and 0.55 V, 0.11 V apart. Their line is halfway, so a reading can wander about 55 mV either way before it is misread. In counts that is roughly:

BoardU8U6apart
Arduino Uno13511322
Raspberry Pi Pico20517134

Ordinary noise on a breadboard is a few counts, so both are comfortable. What eats the margin is a wrong supply: 5V on the header's 3V3 pin raises every level by half and puts most of them over the wrong line.

When it does not work

U8 and U6 get mixed up.

They are the closest pair, a fifth and a sixth of 3V3. Check that the header's 3V3 pin is on 3V3, that the sketch's lines are the ones in this article, and on an Uno that FULL_SCALE_MV matches your 5V pin; a USB supply a little under 5 V shifts every millivolt reading up a few per cent.

Most buttons are named wrong, U6 as U7.

The header's 3V3 pin is on 5V. Every level is half as high again, and lines drawn for 3.3 V name most buttons as one nearer BTNS: U5 as U10, U6 as U7. Move it to 3V3. Only U11, which reads the top either way, still comes out right.

A press sometimes shows a different button for one reading.

The contacts bounce as they close, and a reading taken in the middle of that can land anywhere. Believe a button only when two readings in a row agree, or read once per frame of your program, which is slower than the bounce.

Where this goes next

What BTNS reads when two buttons are pressed together.

One button at a time

Edit this page — content/books/slim-joystick/telling-them-apart.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

Slim Joystick

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum