voltmeter/Reading a voltage/08. The first reading
Reading a voltage · 08 of 12

The first reading

Two wires to your board, two to a battery, and a sketch that reads SIG, multiplies by five and prints volts. A fresh 9 V battery should read a little over 9 V.

Four wires

Four wires
Your board
SIG to
A0
VCC
none
Most on the terminal
25.0 V
GND to GND, SIG to A0. The battery's minus on the left screw, plus on the right. A 9 V battery puts 1.8 V on A0, well inside the Uno's 5 V.

GND to your board's GND, SIG to an analog pin. The two NC pins stay unconnected, and there is no VCC wire because the block has no VCC. Then the battery: minus on the left screw, plus on the right.

The analog pins in the sketch are A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an ESP32-S3 and GP26 on a Pico. On both ESP32s they are on ADC1, the converter that keeps working while Wi-Fi is on; the other one, ADC2, stops. GPIO 34 on a classic ESP32 is input-only, which is all an analog input needs to be.

The sketch

sigVolts() is the only part that differs between boards. On an ESP32 or ESP32-S3, analogReadMilliVolts returns SIG in millivolts, using the chip's own calibration. On an Uno or a Pico, analogRead returns a count, and the count's share of ADC_MAX times VREF is SIG in volts. From a number to volts works through both.

Then loop() multiplies by SCALE, five, and prints both numbers twice a second.

What you should see

With a fresh 9 V alkaline battery, something like:

SIG 1.852 V   input 9.26 V
SIG 1.852 V   input 9.26 V
SIG 1.847 V   input 9.24 V

A new battery usually reads a little above 9 V. The last digit or two wanders from line to line, and the number may differ from a multimeter's by a percent or two. Both are expected, and calibrating and averaging fixes both. With the battery unscrewed, the reading falls to zero or very near it.

The code

No library. On an ESP32 or ESP32-S3 the sketch asks the core for millivolts, which applies the chip's own calibration. On an Uno or a Pico it scales the raw count by the reference voltage. Either way it multiplies by five.

voltmeter_first_reading.ino
/*
  Voltmeter - first reading                              TK09 / /p/tk09

  Wiring. Count from the square pad on the TinkerBlock board, terminal
  at the top, header at the bottom:

    GND    -> GND
    NC     -> nothing   (both NC pins are unconnected on the board)
    SIG    -> A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an
              ESP32-S3, GP26 on a Raspberry Pi Pico

  Terminal, same way up. Nothing is printed on it:
    left screw   GND: the minus side of what you measure
    right screw  +:   the plus side. DC only. At most 25 V on an Uno,
                      about 15.5 V on an ESP32 or ESP32-S3, 16.5 V on
                      a Pico. Never mains.

  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 SIG is wired to. Uno: A0. ESP32: 34. ESP32-S3: 4. Pico: 26.
const int SIG_PIN = A0;

// Uno: 5.0 and 1023. Pico: 3.3 and 1023. The ESP32s do not use these.
const float VREF = 5.0;
const float ADC_MAX = 1023.0;

// The board's divider: 30 k over 7.5 k, so the terminal is 5 x SIG.
const float SCALE = 5.0;

float sigVolts() {
#if defined(ARDUINO_ARCH_ESP32)
  return analogReadMilliVolts(SIG_PIN) / 1000.0;  // calibrated
#else
  return analogRead(SIG_PIN) * VREF / ADC_MAX;
#endif
}

void setup() {
  Serial.begin(115200);
}

void loop() {
  float sig = sigVolts();
  Serial.print("SIG ");
  Serial.print(sig, 3);
  Serial.print(" V   input ");
  Serial.print(sig * SCALE, 2);
  Serial.println(" V");
  delay(500);
}

SIG_PIN is the analog pin SIG is wired to. VREF and ADC_MAX are only used on the Uno and the Pico: 5.0 and 1023 on an Uno, 3.3 and 1023 on a Pico. analogReadMilliVolts needs the Arduino-ESP32 core 2.0 or later.

When it does not work

It prints 0.00 V with the battery connected.

The battery's minus is not reaching the GND screw, or the plus is not reaching the + screw. Check both wires are clamped on copper, not insulation, and that minus is on the left screw. Then check SIG_PIN names the pin SIG is actually on.

It prints the same large number whatever I connect.

SIG is probably wired to a supply pin rather than the analog pin, or the input is above your board's limit. Take the battery off: with nothing on the terminal the reading must fall to zero. If it does not, the SIG wire is in the wrong place.

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.

On MicroPython my ESP32 never reads above about 5 V.

The ADC's attenuation is still at its default, which reads only to about 1 V on SIG. The sketch sets ADC.ATTN_11DB for that reason; if you wrote your own, add it. read_uv needs a recent MicroPython release; an old one raises an AttributeError.

Where this goes next

What the arithmetic in sigVolts is doing, on each board.

From a number to volts

Edit this page — content/books/voltmeter/the-first-reading.mdx

Community

Questions about this product

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

Ask a question ↗

Voltmeter

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