DEI.
Week 09 · Fab Academy 2026 · Lab Rwanda

Input Devices

Reading analog and digital sensor data from the custom ESP32-S3 board, a variable resistor for analog input and a DHT sensor for digital temperature and humidity.

Overview

Introduction

Input Devices week is about making a microcontroller board listen to the world, reading real physical signals and turning them into usable data. On my custom ESP32-S3 board, I had already mounted two input devices during Electronics Production week: a variable resistor for analog input and a DHT sensor for digital input.

This week I wrote firmware to read both sensors, observed their signals on the Serial Monitor, and understood the fundamental difference between how analog and digital inputs work at the hardware and software level.

AttributeVariable resistor (analog)DHT sensor (digital)
Signal typeContinuous voltageOne wire digital
ESP32 pinADC GPIODigital GPIO
What it reads0 to 4095 (12 bit), 0 to 3.3 VTemperature and humidity
ProtocolAnalog read (ADC)Single wire serial
Already mounted on my boardYesYes
This Week

Assignments

Group Assignment
Probe an input device's analog levels and digital signals. View the group assignment page.

As a group, we used an oscilloscope and a multimeter to observe real signal behavior. We measured the continuous voltage output from a potentiometer as it was turned, and we captured the single wire data bursts from a DHT sensor to understand the digital timing protocol. What I learned probing these inputs is documented in the section below.

Individual Assignment
Measure something: add a sensor to a microcontroller board that you have designed and read it.

For my individual work, I wrote firmware for the custom ESP32-S3 board to read both the variable resistor (analog ADC) and the DHT sensor (digital 1-wire) and print live readings to the Serial Monitor.

Concepts

Analog vs Digital Input

Understanding the difference between how these two sensors communicate with the microcontroller is fundamental to embedded systems design.

Analog Signal
The variable resistor outputs a continuous voltage between 0 and 3.3V depending on its position. The ESP32-S3's built-in 12-bit ADC converts this voltage into a number from 0 to 4095, which the firmware reads with analogRead().
Digital Signal
The DHT sensor encodes temperature and humidity as a timed sequence of high and low pulses on a single wire. The DHT library decodes this timing protocol and returns structured values, no analog-to-digital conversion needed.
Serial Monitor
Both sensors output their readings over USB to the Arduino IDE Serial Monitor, the primary tool for verifying sensor data in real time without any external display hardware.
Group Work

Probing the Signals

For the group assignment we probed an input device's analog levels and its digital signals so we could actually see what the microcontroller reads. We used two instruments. The full write up is on our group assignment page.

Multimeter
I set the multimeter to DC volts and put the probes across the variable resistor wiper and ground. As I turned the knob the reading moved smoothly from 0 V to 3.3 V. This is the analog level the ADC pin sees, and it confirmed the divider was wired right before I trusted any number on the Serial Monitor.
📈
Oscilloscope
On the analog input the scope showed a flat line that rose and fell with the knob, matching the multimeter. On the DHT data line it showed something completely different: a burst of fast high and low pulses every two seconds. That picture is the 1 wire timing protocol the DHT library decodes for us.
What I Learned
The analog signal is a steady voltage you can read at any instant. The digital signal carries no meaning in its voltage level alone. The meaning is in the timing of the edges. Seeing both on the scope made it obvious why one sensor uses analogRead and the other needs a library.
Oscilloscope trace of the two sensor signals
Oscilloscope trace of the two sensor signals
The Board

My Milled ESP32-S3 Board

I did not make a new board this week. I added the sensors to the board I designed in Electronics Design week and milled in Electronics Production week, so every reading on this page comes off my own milled board, not a breadboard. The variable resistor and the DHT sensor are soldered directly to the copper pads, with the DHT pull up resistor included in the layout. You can open the schematic, the board layout and the production files on those two pages.

Design files
Electronics Design week holds the schematic and the board layout for this ESP32-S3.

Fabrication files
Electronics Production week holds the traces, the cut outline and the milling process.

Process

Step-by-Step

Both sensors were already physically mounted on the board from Electronics Production week, so this week was purely about firmware, writing, uploading, and verifying the code for each input type.

Sensor 01
Variable Resistor, Analog Input ADC · GPIO · analogRead()
Step 01
Identify the ADC Pin
Checked the ESP32-S3 schematic from Electronics Design week to confirm which GPIO pin the variable resistor wiper is connected to. The ESP32-S3 has a 12-bit ADC on several GPIO pins, the wiper output of the resistor divider feeds directly into one of these ADC-capable pins. the variable resistor is connected to pin 35.
ESP32-S3 PinoutADC GPIO12-bit ADC
ESP32-S3 board schematic showing ADC pin connection for variable resistor
Step 02
Write the Analog Read Firmware
Opened the Arduino IDE, selected the ESP32 dev module board target. Wrote a sketch that reads the ADC value every 200 ms and prints it to Serial. The raw value (0–4095) was also mapped to 180 Degrees (0–180) for easier interpretation.
analogRead()Serial.println()map()Arduino IDE
int potPin = 35;   // GPIO 35
int potValue = 0;

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

void loop() {
  potValue = analogRead(potPin);  // range: 0–4095
  Serial.print("Analog Readings: ");
  Serial.print(potValue);

  long int Degrees;
  Degrees = map(potValue, 0, 4095, 0, 180);

  Serial.print("   Degrees: ");
  Serial.print(Degrees);
  Serial.println(" Deg");

  delay(200);
}
Step 03
Upload & Observe Analog Readings
Uploaded the sketch using the BOOT + EN button sequence. Opened the Serial Monitor at 115200 baud. Slowly turned the variable resistor through its full range and watched the ADC value sweep from near 0 to near 4095, with voltage tracking from 0 to 3.3V in real time.
Serial Monitor115200 BaudLive ADC Values

Expected behavior: Rotating the resistor to one end should give ~0 (0 Deg), the opposite end ~4095 (180 Deg), and the midpoint ~2047 (90 Deg). Any deviation indicates a wiring or grounding issue.

Serial Monitor showing full degree range output
Serial Monitor showing analog ADC readings
Sensor 02
DHT Sensor, Digital Input 1-Wire · DHT Library · Temp + Humidity
Step 04
Install the DHT Library
Opened the Arduino IDE Library Manager and searched for DHT sensor library by Adafruit. Installed it along with the Adafruit Unified Sensor dependency. This library handles the timing-critical single-wire protocol automatically, so the firmware only needs to call simple read functions.
Library ManagerAdafruit DHTUnified Sensor
Step 05
Identify the DHT Data Pin & Type
Referred back to the board schematic to confirm the GPIO pin connected to the DHT sensor's data line, and verified whether the sensor is a DHT11 or DHT22, they use the same protocol but the library constant differs between them. The data pin is connected to GPIO 14, which was already included in the board design.
DHT Data PinDHT11 / DHT22GPIO
Board schematic showing DHT sensor data pin connection
Step 06
Write the DHT Read Firmware
Wrote a sketch that initializes the DHT sensor and reads temperature and humidity every 2 seconds, the minimum polling interval required by the DHT protocol. Both values are printed to the Serial Monitor with clear labels.
DHT.hreadTemperature()readHumidity()Serial Output
// DHT Sensor — Digital Read
// Temperature and Humidity

#include <DHT.h>

#define DHT_PIN  14      // GPIO 14 on my board
#define DHT_TYPE DHT11   // DHT11 or DHT22

DHT dht(DHT_PIN, DHT_TYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();
  Serial.println("DHT Sensor Read — Starting");
}

void loop() {
  delay(2000); // DHT needs min 2s between reads

  float humidity    = dht.readHumidity();
  float temperature = dht.readTemperature(); // Celsius

  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.print(" °C  |  Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");
}
Step 07
Upload & Observe DHT Readings
Uploaded the sketch and opened the Serial Monitor at 115200 baud. Confirmed temperature and humidity values appeared every 2 seconds and were reasonable for the room environment. Breathed lightly on the sensor to verify the humidity reading responded, a quick real-world sanity check.
Serial MonitorTemperature °CHumidity %Live Readings

Result: Temperature and humidity readings updated every 2 seconds and responded correctly to changes in the environment, confirming the DHT sensor, data pin, pull-up resistor, and library are all working correctly.

Serial Monitor showing DHT temperature and humidity output
Debugging

Problems and Solutions

Nothing worked perfectly on the first try. Here is what went wrong and how I fixed each one.

DHT returned not a number
My first DHT sketch printed "DHT read failed" every time. The problem was that I had set the wrong pin in the code. I had left it at GPIO 4 from the example, but on my board the data line is GPIO 14. Once I changed DHT_PIN to 14 the temperature and humidity came straight through.
Analog value stuck near 4095
When I first read the variable resistor the value barely moved and sat near the top. I checked the wiper voltage with the multimeter and found the divider ends were swapped, so one outer leg was floating. Reseating the solder joint on that pad gave me the full 0 to 3.3 V sweep.
Garbled Serial output
The Serial Monitor showed random characters at first. The baud rate in the monitor did not match my Serial.begin call. Setting the monitor to 115200 baud fixed it, and reading both sensors in one loop reminded me the DHT delay of two seconds also paces the analog prints.
Results

Measurements

ADC Resolution
12bit
ADC Range
0 – 4095
Voltage Range
0 – 3.3V
DHT Poll Rate
2s
Analog Status
Reading
Digital Status
Reading
Full Firmware

Reading Both Sensors Together

After each sensor worked on its own I joined them into one sketch so the board reads the analog input and the digital input in the same loop and prints both to Serial. Here is how the code works. In setup() I start Serial at 115200 baud and call dht.begin() once. In loop() I call analogRead(POT_PIN) to get the 0 to 4095 ADC value from the variable resistor, then map() it to a 0 to 180 range so it is easier to read. Then I call dht.readHumidity() and dht.readTemperature(), which trigger the library to clock the 1 wire protocol and hand back floats. I guard those with isnan() because a missed read returns not a number, and I print every value on one labelled line. The DHT needs at least two seconds between reads, so the delay(2000) at the end of the loop sets the pace for both sensors.

// Input Devices - ESP32-S3 milled board
// Reads variable resistor (analog) and DHT (digital)
// Prints both to Serial

#include <DHT.h>

#define POT_PIN  35      // analog wiper, ADC GPIO 35
#define DHT_PIN  14      // DHT data line, GPIO 14
#define DHT_TYPE DHT11   // DHT11 or DHT22

DHT dht(DHT_PIN, DHT_TYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();
  Serial.println("Input Devices - reading both sensors");
}

void loop() {
  int potValue = analogRead(POT_PIN);        // 0 to 4095
  int degrees  = map(potValue, 0, 4095, 0, 180);

  float humidity    = dht.readHumidity();
  float temperature = dht.readTemperature(); // Celsius

  Serial.print("Pot: ");
  Serial.print(potValue);
  Serial.print("  (");
  Serial.print(degrees);
  Serial.print(" deg)   |   ");

  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("DHT read failed");
  } else {
    Serial.print("Temp: ");
    Serial.print(temperature);
    Serial.print(" C   Humidity: ");
    Serial.print(humidity);
    Serial.println(" %");
  }

  delay(2000); // DHT needs min 2s between reads
}
Files

Design Files and Source Code

Everything needed to reproduce this week is here. The source code is the three firmware blocks above, which you can copy with the Copy button. The board design files live on the two weeks where I made the board.

Source code
Combined firmware reading both sensors, plus the single analog and single DHT sketches in the steps above. All copyable.

Board design and fabrication files
Electronics Design for the schematic and layout, and Electronics Production for the milling files.

Hero Shot

The Board Reading Live

My milled ESP32-S3 board
My milled ESP32-S3 board
Takeaways

Conclusion

This week made the distinction between analog and digital inputs very concrete. The variable resistor gives a smooth, continuous voltage that the ESP32-S3's ADC converts into a 12-bit number, simple to read but sensitive to noise and supply voltage variation. The DHT sensor communicates through a precise timing protocol that the library handles, delivering clean, calibrated temperature and humidity values over a single wire.

Having both sensors already mounted from Electronics Production week meant all the focus could go into firmware, understanding what analogRead() actually returns and what the DHT library is doing under the hood when it decodes those 1-wire pulses.

Variable Resistor DHT Sensor Analog ADC Digital 1-Wire Arduino IDE Serial Monitor ESP32-S3 Sensor Firmware
← Week 08 · Electronics Production All Assignments →
Downloads

Downloadable files