Micropython Basics: Analog Input
Table of Contents
So far, you’ve learned how to work with digital inputs and outputs — signals that are either ON or OFF, HIGH or LOW. But what if you need to measure values that change gradually, like light intensity, temperature, or knob position?
That’s where analog inputs come in. Using MicroPython’s ADC
(Analog-to-Digital Converter) feature,
your microcontroller can read analog voltages and convert them into numerical values that your code can process.
What Is an Analog Signal?
Unlike a digital signal, which has only two states (0 or 1), an analog signal varies continuously. For example, a potentiometer’s output changes smoothly between 0V and the reference voltage (often 3.3V), depending on its position.
The microcontroller can’t process continuous voltages directly — so the ADC converts these analog voltages into digital numbers.
- 0V → Digital value
0
- 3.3V → Digital value
4095
(for a 12-bit ADC)
2048
.
Supported Boards and ADC Pins
Most MicroPython-compatible boards come with one or more ADC (Analog-to-Digital Converter) channels. These channels allow the board to measure varying voltage levels and convert them into digital values that your program can process. However, the number of available ADC pins and their resolution (the precision of measurement) depend on your specific board model.
Below is a summary of the most commonly used boards and how they handle analog input:
ESP32
- ADC Channels: Up to
18
(pins from ADC1 and ADC2 groups) - Resolution: 12-bit (values range from
0
to4095
) - Input Voltage Range: 0V to approximately 3.3V
- ADC1 Pins: GPIO32 to GPIO39
- ADC2 Pins: GPIO0, GPIO2, GPIO4, GPIO12–15, GPIO25–27
ESP32 offers the most flexible and high-performance ADC system among common MicroPython boards. However, there are a few important considerations:
- ADC2 channels cannot be used when Wi-Fi is active, since Wi-Fi hardware shares those pins internally.
- Different ESP32 variants (such as WROOM and WROVER) may have slightly different ADC behavior or pin mapping.
- Readings can vary slightly due to internal reference voltage fluctuations — adding a calibration step can improve accuracy.
ESP8266
- ADC Channels: 1 (labeled
A0
) - Resolution: 10-bit (values range from
0
to1023
) - Input Voltage Range: 0V to 1.0V (on most boards)
Unlike the ESP32, the ESP8266 has only a single ADC channel. This means it can read only one analog signal at a time. Its biggest limitation is the input voltage range: the ADC pin accepts a maximum of 1.0V. Exceeding this voltage can damage the chip.
Many development boards (such as the NodeMCU or Wemos D1 Mini) include a built-in voltage divider that allows the ADC pin to read up to 3.3V safely. Always confirm this by checking your board’s schematic or documentation.
Raspberry Pi Pico
- ADC Channels: 3 dedicated pins (
GP26
,GP27
,GP28
) - Resolution: 12-bit (values range from
0
to4095
) - Input Voltage Range: 0V to 3.3V
- Internal Sensor: One extra ADC channel (
ADC4
) is connected to the onboard temperature sensor.
The Raspberry Pi Pico’s ADC system is straightforward and very stable, ideal for learning and experimentation.
It includes an internal temperature sensor you can access using ADC(4)
in MicroPython.
adc_temp = ADC(4)
reads the internal temperature sensor on the Pico.
Other Boards
- PyBoard: 16-bit ADC with 12 external channels — excellent for high-resolution readings.
- STM32-based boards: Multiple 12-bit ADC channels, often with configurable reference voltages.
- BBC micro:bit: A few analog pins available (10-bit resolution, 0–3.3V).
These boards vary in precision and number of ADC channels, but the usage pattern in MicroPython remains largely the same:
create an ADC
object, pass in the pin, and read the value.
Hardware Setup: Reading a Potentiometer
To explore analog input, you’ll use a simple potentiometer — a variable resistor that outputs a range of voltages based on its knob position.
Required Components
- 1 × MicroPython board (ESP32, ESP8266, or Raspberry Pi Pico)
- 1 × 10kΩ potentiometer
- Breadboard and jumper wires
Wiring Guide
- Potentiometer left pin → 3.3V
- Potentiometer right pin → GND
- Potentiometer middle (wiper) pin → ADC pin (e.g., GP26 on Pico, A0 on ESP8266)
As you rotate the knob, the voltage on the middle pin changes between 0V and 3.3V, providing a smooth analog signal for your board to read.
Reading Analog Values in MicroPython
MicroPython provides the ADC
class under the machine
module to read analog values.
Here’s how it works:
from machine import ADC, Pin
import time
# Create an ADC object on pin 26 (Raspberry Pi Pico example)
pot = ADC(Pin(26))
while True:
value = pot.read_u16() # Read 16-bit value (0–65535)
print(value)
time.sleep(0.2)
This continuously prints the potentiometer’s reading to the REPL. Turning the knob changes the value in real time.
adc.read()
returns a 12-bit value (0–4095),
while on others (like Pico), read_u16()
returns a 16-bit value (0–65535).
Always refer to your board’s documentation for details.
Converting Raw ADC Values to Voltage
To make readings more meaningful, you can convert the raw ADC value to a voltage using this simple formula:
voltage = (value / 65535) * 3.3
This expresses the potentiometer’s position in volts, which is often easier to interpret.
value = 32768
, then voltage ≈ 1.65V
— exactly half of 3.3V.
Using Analog Input to Control an LED
You can combine analog and digital concepts to make interactive projects — for instance, adjusting LED brightness using a potentiometer.
In this case, you’ll read the analog value from the potentiometer and use it to adjust the LED’s pulse width using PWM (Pulse Width Modulation).
Common Analog Sensors
Once you understand analog inputs, you can connect a wide variety of sensors:
- Light-dependent resistor (LDR): Measures brightness.
- NTC thermistor: Measures temperature changes.
- Soil moisture sensor: Detects water level in soil.
- Gas sensor (MQ series): Detects specific gases based on voltage output.
Testing and Troubleshooting
- Ensure your ADC pin supports analog input — not all pins do.
- Check that your sensor operates within 0–3.3V (never 5V unless your board supports it).
- If readings are unstable, use a small capacitor (0.1µF) between signal and GND to smooth the signal.
Summary
In this section, you learned how to work with analog inputs using MicroPython’s ADC
class.
You read varying voltages from a potentiometer, converted raw values into volts, and understood how
analog sensors communicate with your board.
With this foundation, you can now explore sensors that output variable voltages — enabling environmental monitoring, control systems, and interactive hardware designs.
Next, we’ll move on to PWM (Pulse Width Modulation) — a technique for simulating analog output, allowing you to control LED brightness or motor speed smoothly.