rotary potentiometer/Reading it/03. The first read
Reading it · 03 of 10

The first read

Three wires, no library, and a sketch that prints the reading and the voltage it stands for five times a second. Turn the knob from one end to the other and the number runs from 0 to 1023 on an Uno, or 0 to 4095 on the 3.3 V boards.

Three wires

Three wires
Your board
Wires
3
VCC to
3V3
SIGNAL to
GPIO 4
GND to GND, VCC to 3V3, SIGNAL to GPIO 4, an ADC1 pin, so the reading keeps working with Wi-Fi on. Never 5V: the knob's top end would put 5 V on a 3.3 V pin.

GND to GND. VCC to your board's logic supply: 5V on an Uno, 3V3 on the three 3.3 V boards. SIGNAL to an analog pin. NC stays unconnected.

The analog pin is the same in every sketch in this book: A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an ESP32-S3, GP26 on a Pico. On the two ESP32 boards those are ADC1 pins. The classic ESP32's other ADC, ADC2, is taken over by the radio once Wi-Fi starts, and a knob on it goes dead the moment your sketch connects; ADC1 pins keep working, so the book uses one on the S3 too.

If your block came with a TinkerBlock cable, it carries all four wires, and the NC wire simply ends at a pin that goes nowhere.

The sketch

analogRead(POT_PIN) does the work. It measures the voltage on the pin and returns it as a whole number: 0 for 0 V, and the full-scale number for the top of the range. It needs no pinMode.

The #if block at the top is there because the four boards differ in two ways. They use different pins, and the Uno counts to 1023 while the others count to 4095 once the sketch asks for 12 bits with analogReadResolution. The block picks both for the board you compile for, so the same file works on all four. Counts and volts is about what those numbers mean.

What you should see

The serial monitor at 115200 prints a reading and a voltage five times a second. On an Uno, turning from one end to the other, something like:

0   0.00 V
212   1.04 V
511   2.50 V
590   2.88 V
1023   5.00 V

The low end is 0 and the high end is full scale. The numbers between depend on where you stopped, with one surprise that is easier to see than to describe: on an Uno, the upper half of the turn changes the number much less than the lower half, until the very end. That is the red LED, and the next chapter is about it.

The code

No library. analogRead returns a number proportional to the voltage on the pin. The #if block picks the pin and the full-scale number for the board you compile for; change POT_PIN if you wired SIGNAL somewhere else.

rotary_pot_first_read.ino
/*
  Rotary Potentiometer - first read                      TK08 / /p/tk08

  Wiring. Count from the square pad on the TinkerBlock board, knob
  up, header at the bottom:

    GND    -> GND
    VCC    -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
              (the full turn puts VCC on your analog pin)
    NC     -> nothing   (unconnected on the board)
    SIGNAL -> A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an
              ESP32-S3, GP26 on a Raspberry Pi Pico

  Arduino IDE
    Tools > Board                 your board, e.g. ESP32S3 Dev Module
    Tools > Port                  the one that appears when you plug in
    Tools > USB CDC On Boot       Enabled   (ESP32-S3 only)
    No library needed.
*/

// The pin SIGNAL is wired to, picked for the board you compile for.
// Uno: A0. ESP32: 34. ESP32-S3: 4. Pico: 26.
#if defined(ARDUINO_ARCH_AVR)
const int POT_PIN = A0;
const int ADC_MAX = 1023;       // 10 bits
const float VREF = 5.0;         // measured against 5 V
#elif defined(ARDUINO_ARCH_RP2040)
const int POT_PIN = 26;
const int ADC_MAX = 4095;       // 12 bits, set in setup()
const float VREF = 3.3;
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
const int POT_PIN = 4;
const int ADC_MAX = 4095;
const float VREF = 3.3;
#else
const int POT_PIN = 34;         // the classic ESP32
const int ADC_MAX = 4095;
const float VREF = 3.3;
#endif

void setup() {
  Serial.begin(115200);
#if !defined(ARDUINO_ARCH_AVR)
  analogReadResolution(12);     // the Pico's core starts at 10 bits
#endif
}

void loop() {
  int reading = analogRead(POT_PIN);
  float volts = reading * VREF / ADC_MAX;

  Serial.print(reading);
  Serial.print("   ");
  Serial.print(volts, 2);
  Serial.println(" V");
  delay(200);                   // five lines a second
}

No pinMode is needed: analogRead sets the pin up itself. The volts are worked out against 5 V on an Uno and 3.3 V elsewhere. On an ESP32 that is approximate, because its ADC does not run all the way to 3.3 V.

When it does not work

It prints 0 whatever I turn.

The track has no supply: check the VCC wire. If VCC is fine, SIGNAL is on a different pin from the one the sketch reads. The red LED is a quick check: turn fully up, and it should light.

The number jumps around even with the knob still.

A few counts of wander are normal for any ADC, and more on a 12-bit one. Tens of counts, drifting when you move your hand, mean the pin is reading nothing: the SIGNAL wire is loose or on the wrong pin. Smoothing the reading comes later in the book.

My ESP32 reads 4095 before the knob reaches the end.

Expected. At the Arduino core's default setting the ESP32 and ESP32-S3 ADC stops rising at roughly 3.1 V, so the last part of the turn reads full scale. The calibration article measures where yours stops.

The serial monitor stays empty on my ESP32-S3.

Set Tools > USB CDC On Boot to Enabled and upload again. Without it the S3's USB port does not bring up a serial port at boot, so the sketch runs with nowhere to print.

Where this goes next

What the number means, and why an Uno and an ESP32 give different ones.

Counts and volts

Edit this page — content/books/rotary-potentiometer/the-first-read.mdx

Community

Questions about this product

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

Ask a question ↗

Rotary Potentiometer

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