Chapters

35 ADC and DAC: Conversion Calculations

electronics
analog
digital
esp32
power
signal
adc
resolution
measurement

35.1 Start With the Decision

An ADC count is useful only when it maps back to the measured voltage. Work the scale, error, and range at the bench.

35.2 Route Overview

This is part 1 of 2. Continue with ADC and DAC: Interactive Design Calculators.

35.3 Part Objectives

  • Test adc/dac worked examples with a concrete scenario and pass criteria.
  • Validate adc/dac calculation links with a concrete scenario and pass criteria.

35.4 Start Simple

Make the Bench Value and the Screen Value Agree

Picture a light sensor producing 1.20 volts while a device shows a digital count and the dashboard shows a percentage. The test engineer must show how one known input becomes both outputs without hiding a reference value, scale factor, unit change, or rounding choice.

Write the known values first. Record input range, reference, number of steps, output unit, formula, and rounding rule. Calculate the expected count by hand, then run the same value through the device. Keep the code, board, settings, and meter reading with the result.

Try zero, mid-range, near-full-scale, just outside range, a changed reference, a negative input where allowed, and a value between two codes. Check clipping, rounding, output reconstruction, and the final display. Reverse the calculation to see whether the reported value can recover the original within the stated limit.

Do not use a neat digital result as proof that the physical input is safe or accurate. Keep urgent control on a path that handles out-of-range and failed-input states locally. A distant chart may show the result, but it cannot restore resolution lost at conversion.

This opening does not cover every converter design. Practitioner builds the input-to-output worksheet and bench check. Under the Hood examines step size, reference error, noise, sample timing, output levels, and uncertainty.

Use this value check:

  • Write each known value.
  • Keep each stated unit.
  • Work the sum once.
  • Test the mid point.
  • Test both end points.
  • Check the round trip.

Imagine a datasheet number, an ADC code, and a dashboard value that must all agree. Worked examples show the conversion path step by step so no scale factor, reference voltage, or rounding decision hides in the code. Start with one known input, calculate the expected digital value, and compare it with a measured result.

In 60 Seconds

This chapter turns ADC and DAC ideas into worked engineering calculations. You will convert sensor voltages into digital readings, choose useful reference voltages, estimate quantization error, select sampling rates, compute DAC outputs, and build a gamma-corrected LED dimming table. The goal is a repeatable method: identify the known values, choose the formula, calculate, verify, and interpret the result.

The mathematical gist. A 10-bit, 3.3 V ADC has (q=V_{ref}/2^{10}=3.22) mV. At 1.65 V, the chapter’s endpoint rule gives (D=\lfloor(1.65/3.3)1023\rfloor=511), reconstructing 1.648 V within half an LSB. The same bit depth sets an ideal 62.0 dB SNR, while 8 kHz sampling places Nyquist at 4 kHz and folds a 20 kHz tone to that band edge.

Math Bridge · guided foundationsWhat does a 10-bit ADC actually report for 1.65 V?Let Eddie connect bin width, code rounding, reconstruction error, ideal SNR, Nyquist, and aliasing.
Chapter Roadmap
  • Start Simple
  • In 60 Seconds
  • Phoebe’s Field Notes: Where the Converter Numbers Come From
  • Key Concepts
  • ADC/DAC Worked Examples
  • Prerequisites
  • Why This Chapter Matters
  • How To Use This Chapter
  • ADC Conversion Formula
  • 10-bit Temperature ADC
  • LM35 Temperature Example
  • Quantization Error Example
  • Checkpoint: ADC Codes and Error
  • Knowledge Check: ADC Step Size
  • Nyquist Audio Sampling
  • Vibration Accelerometer Example
  • ESP32 Soil Moisture Example
  • Ultrasonic Distance Example
  • Checkpoint: Sampling and Sensor Fit
  • 8-bit DAC Motor Control
  • Gamma-Corrected LED Dimming
  • Checkpoint: DAC and Dimming
  • Knowledge Check Quiz
  • Quiz: ADC Conversion Calculation
  • Quiz: DAC Output Voltage
  • For Kids: Meet the Sensor Squad!
  • ADC Input Impedance Pitfall
  • Key Takeaway
  • ADC/DAC Calculation Links

Use this path through the worked examples:

  1. First turn input voltage into ADC codes, then convert the code back into a physical value.
  2. Then quantify the limits: reference voltage, step size, and quantization error.
  3. Next apply the same discipline to sampling-rate and sensor-fit examples.
  4. Finally reverse the direction with DAC output, gamma correction, calculators, and review quizzes.

Checkpoints recap the calculation pattern; collapsed examples and calculators are deeper practice once the main flow is clear.

Key Concepts
  • Worked Example Structure: Each worked example follows the same format: problem statement, identify knowns and unknowns, select the appropriate formula, substitute values with units, compute result, verify the answer is physically plausible, and state the practical implication
  • Unit Consistency Checking: All quantities in a formula must use consistent SI base units before computing; convert mA to A, kOhm to Ohm, nF to F, and mV to V before substituting into formulas to prevent systematic errors by factors of 10^3
  • Voltage Divider Analysis: Vout = Vin x R2 / (R1 + R2); used in thermistor circuits, LDR circuits, and reference voltage generation; the key insight: Vout approaches Vin when R2 >> R1, and approaches 0 when R2 << R1
  • LED Current Limiting Design: R = (Vsupply - Vf) / If; typical values: Vsupply = 3.3 V, Vf = 2.0 V (red LED), If = 10 mA; R = (3.3 - 2.0) / 0.010 = 130 ohm; round up to 150 ohm standard value for safety
  • RC Filter Cutoff Calculation: fc = 1 / (2 pi R C); 10 kohm and 100 nF gives fc = 1 / (2 pi x 10000 x 100e-9) = 159 Hz; any noise above 159 Hz is attenuated; signals well below 159 Hz pass without significant attenuation
  • Battery Life Estimation: Runtime (hours) = Battery capacity (mAh) / Average current (mA); for duty-cycled devices: Iavg = Iactive x duty_cycle + Isleep x (1 - duty_cycle); a 1000 mAh battery powering a 50 mA active / 0.1 mA sleep device at 10% duty cycle: Iavg = 5 + 0.09 = 5.09 mA; runtime = 1000/5.09 = 196 hours
  • ADC Voltage Conversion: Voltage = (ADC_reading / (2^bits - 1)) x Vref; for a 12-bit ADC reading 2048 with Vref = 3.3 V: V = (2048/4095) x 3.3 = 1.65 V; verify: at maximum reading (4095), output = Vref = 3.3 V (correct)
  • Power Dissipation Check: P = V^2 / R or P = I^2 x R; a 100 ohm resistor carrying 50 mA: P = (0.050)^2 x 100 = 0.25 W; requires at least a 0.5 W rated resistor (50% safety margin); a 1/4 W (0.25 W) resistor would run at its absolute limit and fail early

35.5 Learning Objectives

By the end of this section, you will be able to:

  • Calculate ADC Output: Compute digital values from analog voltage inputs using the ADC conversion formula
  • Select Reference Voltages: Evaluate and match Vref to sensor output ranges for maximum resolution
  • Quantify Quantization Error: Derive measurement precision limits across different ADC resolutions
  • Determine Nyquist Sampling Rates: Compute minimum and practical sampling frequencies for specific signal types
  • Compute DAC Output Voltages: Derive specific analog voltages from digital input values
  • Construct Gamma Correction Tables: Build non-linear mappings for perceptually accurate LED dimming

This chapter walks through the math behind converting real-world sensor voltages into digital numbers and back again, step by step. If you have ever wondered how a temperature sensor’s voltage becomes the “23.5C” on your screen, these worked examples show exactly how that calculation happens. No advanced math is needed — just multiplication and division.

35.6 Prerequisites

Before diving into this chapter, you should be familiar with:

35.7 Why This Chapter Matters

Follow these connections in order: This is the chapter that turns the earlier ideas into engineering workflow. Students often think they understand a topic until they have to plug in numbers and justify a design choice. In real IoT work, this kind of calculation is what connects a sensor datasheet, a microcontroller spec, and an actual usable measurement or control signal. After this chapter, a beginner should be able to work through converter problems step by step instead of treating ADC and DAC settings as mysterious configuration values.

35.8 How To Use This Chapter

  • Work the examples in order. They were chosen to move from direct formula use toward more realistic design decisions.
  • Before reading each solution, try to identify the known values, the unknown value, and the governing formula yourself.
  • If you get stuck, the goal is not speed. The goal is to learn a repeatable method: identify, calculate, verify, interpret.

35.9 ADC Conversion Formula

Start with the smallest complete loop: a voltage goes into the converter, a digital code comes out, and the code must still make physical sense when converted back.

The fundamental ADC conversion formula relates analog input voltage to digital output value:

Digital Output=VinVref×(2n1)\text{Digital Output} = \left\lfloor \frac{V_{in}}{V_{ref}} \times (2^n - 1) \right\rfloor

Where:

  • VinV_{in} = Analog input voltage (volts)
  • VrefV_{ref} = Reference voltage (maximum measurable voltage)
  • nn = ADC resolution (number of bits)
  • \lfloor \rfloor = Floor function (round down to nearest integer)

Inspect the labelled evidence in Figure 35.1 as the entry point to adc conversion formula. The visual is specifically about aDC conversion showing how continuous analog voltage is sampled and quantized into discrete digital steps.

Temperature and resistance follow a linear response curve from start to end. Data points mark the relationship T = R/140.
Figure 35.1: ADC conversion showing how continuous analog voltage is sampled and quantized into discrete digital steps

First identify Temperature vs Resistance in Figure 35.1, then contrast it with Resistance (OHMs) and test the claim beside Relationship. These visible labels explain aDC conversion showing how continuous analog voltage is sampled and quantized into discrete digital steps. They keep adc conversion formula tied to evidence that can be inspected on the schematic, part, or trace.


35.10 10-bit Temperature ADC

Given:

  • ADC Resolution: 10 bits (Arduino Uno)
  • VrefV_{ref} = 3.3V
  • VinV_{in} = 1.65V (sensor output at 25C)

Calculate Digital Output:

Digital Output=1.65V3.3V×(2101)\text{Digital Output} = \left\lfloor \frac{1.65V}{3.3V} \times (2^{10} - 1) \right\rfloor

=0.5×1023= \left\lfloor 0.5 \times 1023 \right\rfloor

=511.5= \left\lfloor 511.5 \right\rfloor

=511= 511

Result: The ADC outputs 511 (binary: 0111111111)

Verification:

  • 511.5 is exactly half of 1023, so the floor gives 511, confirming VinV_{in} is half of VrefV_{ref}
  • This digital value would be read by analogRead(A0) as 511

35.11 LM35 Temperature Example

The LM35 is a popular precision temperature sensor that outputs 10mV per degree Celsius.

LM35 Specifications:

  • Output: 10mV/C
  • Temperature Range: 0-100C
  • Voltage Range: 0-1.0V

Scenario: Measuring room temperature (25C) with 10-bit ADC

Step 1: Calculate Sensor Output Voltage

Vsensor=Temperature×10mV/CV_{sensor} = \text{Temperature} \times 10\text{mV/C}

Vsensor=25C×10mV/C=250mV=0.250VV_{sensor} = 25C \times 10\text{mV/C} = 250\text{mV} = 0.250V

Step 2: ADC Configuration

For optimal resolution with 0-1V sensor range:

  • Use VrefV_{ref} = 1.0V (external reference or ATmega internal 1.1V)
  • Resolution: 10-bit → 1024 discrete values

Step 3: Calculate Digital Output

Digital Output=0.250V1.0V×1023\text{Digital Output} = \left\lfloor \frac{0.250V}{1.0V} \times 1023 \right\rfloor

=255.75=255= \left\lfloor 255.75 \right\rfloor = 255

Step 4: Calculate Resolution (Temperature per ADC Count)

Resolution=Temperature RangeADC Counts=100C1024=0.0977C per count\text{Resolution} = \frac{\text{Temperature Range}}{\text{ADC Counts}} = \frac{100C}{1024} = 0.0977C \text{ per count}

This means each ADC step represents approximately 0.1C change.

Step 5: Convert ADC Reading Back to Temperature

Temperature=ADC Value1023×100C\text{Temperature} = \frac{\text{ADC Value}}{1023} \times 100C

Temperature=2551023×100C=24.93C25.0C\text{Temperature} = \frac{255}{1023} \times 100C = 24.93C \approx 25.0C

Key Insight: By matching VrefV_{ref} to sensor range (1V instead of 5V), we maximize resolution and minimize wasted ADC range.

Comparison: 5V Reference vs 1V Reference

ConfigurationResolutionWasted RangeTemperature Precision
5V Vref4.88mV/count80% (1V used, 4V unused)0.488C/count
1V Vref0.977mV/count0% (1V used, 1V available)0.098C/count

Using 1V reference gives 5x better temperature resolution by fully utilizing ADC range!


35.12 Quantization Error Example

Quantization error is the inherent inaccuracy introduced when converting continuous analog signals to discrete digital values.

Quantization Error Formula:

Max Error=±12LSB=±Vref2n+1\text{Max Error} = \pm \frac{1}{2} \text{LSB} = \pm \frac{V_{ref}}{2^{n+1}}

Where LSB (Least Significant Bit) is the smallest voltage change the ADC can detect.

10-bit ADC with 3.3V Reference:

LSB Step Size=3.3V210=3.3V1024=3.22mV\text{LSB Step Size} = \frac{3.3V}{2^{10}} = \frac{3.3V}{1024} = 3.22\text{mV}

Max Quantization Error=±3.22mV2=±1.61mV\text{Max Quantization Error} = \pm \frac{3.22\text{mV}}{2} = \pm 1.61\text{mV}

What This Means:

  • Any voltage between 1.650V and 1.653V will round to the same digital value (512)
  • Worst-case error: +/-1.61mV from actual voltage

Comparison Across ADC Resolutions:

ResolutionLSB Step (3.3V)Max ErrorExample Use Case
8-bit12.9mV+/-6.45mVLow-cost light sensors
10-bit3.22mV+/-1.61mVArduino Uno (general purpose)
12-bit0.805mV+/-0.403mVESP32 (precision sensors)
16-bit0.0503mV+/-0.0252mVThermocouples, strain gauges

Reducing Quantization Error:

  1. Use Higher Resolution ADC

    • 12-bit vs 10-bit: 4x reduction in error (1.61mV → 0.403mV)
    • 16-bit vs 10-bit: 64x reduction in error
  2. Oversampling and Averaging

    • Average N samples to gain extra resolution
    • Effective bits increase by log2(N)/2
    • Example: Average 16 samples with 10-bit ADC → 12-bit effective resolution
  3. Match Vref to Signal Range

    • If measuring 0-1V signal, use 1V reference (not 3.3V or 5V)
    • Maximizes use of ADC’s available range

VeraCheckpoint: ADC Codes and Error

You now know:

  • A 10-bit ADC reports codes from 0 to 1023, so half of a 3.3V reference lands at code 511 after the floor operation.
  • Matching the LM35’s 0-1V range to a 1V reference gives about 0.1C per count instead of wasting 80% of a 5V range.
  • Quantization error is bounded by half an LSB: 3.22mV steps give +/-1.61mV worst-case error, while 16-sample averaging can reach 12-bit effective resolution.


35.13 Nyquist Audio Sampling

The ADC examples handled voltage resolution. The next question is time resolution: how often must the system sample so the changing signal is still recoverable?

Given:

  • Human voice frequency range: 300 Hz to 3.4 kHz
  • Highest frequency: fmaxf_{max} = 3.4 kHz

Calculate Minimum Sampling Rate:

fsample2×3400 Hz=6800 Hzf_{sample} \geq 2 \times 3400\text{ Hz} = 6800\text{ Hz}

Practical Implementation:

  • Telephone systems: 8 kHz (provides margin above 6.8 kHz minimum)
  • VoIP codecs: 8-16 kHz
  • Audio recording: 44.1-48 kHz (for full 20 kHz human hearing range)

35.14 Vibration Accelerometer Example

Given:

  • Machine vibration events: 0-100 Hz
  • Highest frequency: fmaxf_{max} = 100 Hz

Calculate Minimum Sampling Rate:

fsample2×100 Hz=200 Hzf_{sample} \geq 2 \times 100\text{ Hz} = 200\text{ Hz}

Practical Implementation:

  • Industrial IoT: 500-1000 Hz (2.5-5x oversampling for safety margin)
  • Allows detection of unexpected high-frequency faults
  • Ensures anti-aliasing filter has gradual roll-off

Real-World Sampling Rates:

ApplicationSignal BandwidthNyquist MinimumPractical RateOversampling Factor
Audio (telephone)3.4 kHz6.8 kHz8 kHz1.2x (minimal)
Audio (music)20 kHz40 kHz44.1-48 kHz1.1-1.2x
Accelerometer100 Hz200 Hz500-1000 Hz2.5-5x
ECG (heartbeat)150 Hz300 Hz500-1000 Hz1.7-3.3x
Ultrasonic distance40 kHz80 kHz200 kHz+2.5x

35.15 ESP32 Soil Moisture Example

Soil Moisture Sensor ADC Optimization for Precision Agriculture

Scenario: A smart irrigation system uses a capacitive soil moisture sensor that outputs 1.2V (dry) to 2.8V (saturated). You need to determine optimal ADC configuration on an ESP32 to detect 1% moisture changes for water-efficient farming.

Given:

  • Sensor output range: 1.2V (dry/0%) to 2.8V (saturated/100%)
  • ESP32 ADC: 12-bit, configurable attenuation (0 dB, 2.5 dB, 6 dB, 11 dB)
  • Moisture measurement range: 0-100%
  • Required resolution: 1% moisture change detection

Steps:

  1. Calculate voltage per percent moisture: ΔV=VmaxVminMoisture Range=2.8V1.2V100%=16mV/%\Delta V = \frac{V_{max} - V_{min}}{\text{Moisture Range}} = \frac{2.8V - 1.2V}{100\%} = 16mV/\%

  2. Determine required ADC resolution:

    • To detect 1% change, need LSB < 16mV
    • With 11 dB attenuation: range = 0-3.6V, LSB = 3.6V/4096 = 0.88mV (sufficient)
    • With 6 dB attenuation: range = 0-2.2V (cannot read 2.8V - too narrow)
    • Select 11 dB attenuation (0-3.6V range covers sensor output)
  3. Calculate actual resolution achieved: ADC steps per 1%=16mV0.88mV=18.2 steps\text{ADC steps per } 1\% = \frac{16mV}{0.88mV} = 18.2 \text{ steps}

    • Theoretical moisture resolution: 1/18.2 = 0.055% per ADC step
  4. Account for ESP32 ADC nonlinearity:

    • ESP32 ADC has known nonlinearity at extremes (0-0.1V and >3.0V)
    • Sensor range (1.2-2.8V) falls in linear region - acceptable
    • Consider factory calibration values in eFuse for better accuracy
  5. Implement oversampling for noise reduction:

    • Average 64 samples to gain ~3 effective bits
    • Effective resolution: 12 + 3 = 15 bits equivalent
    • New moisture resolution: 0.055% / 8 = 0.007% per averaged reading

Result:

  • Raw ADC values: 1365 (dry) to 3185 (saturated) with 11 dB attenuation
  • Moisture formula: moisture_percent = (adc_value - 1365) / 18.2
  • With 64-sample averaging: <0.01% moisture resolution

Key Insight: Proper attenuation selection is critical. Using 0 dB attenuation (0-1.1V range) would clip the signal, while 11 dB provides headroom. The ESP32’s ADC nonlinearity is most pronounced at range extremes - design sensor output to fall in the 0.5-2.5V linear region when possible.


35.16 Ultrasonic Distance Example

Ultrasonic Distance Measurement Timing with ADC Sampling

Scenario: An autonomous robot uses an HC-SR04 ultrasonic sensor for obstacle detection. The echo pulse width (10us to 25 ms) must be measured accurately. You need to determine if ADC-based measurement or timer-based capture is appropriate.

Given:

  • HC-SR04 echo pulse: 10us (2cm) to 25 ms (4m)
  • Speed of sound: 343 m/s at 20C
  • Required distance accuracy: 1cm
  • ESP32 ADC sampling rate: 2 MSPS maximum (but limited in practice)
  • ESP32 timer resolution: 12.5ns (80MHz clock)

Steps:

  1. Calculate time per centimeter of distance: t1cm=2×0.01m343m/s=58.3μst_{1cm} = \frac{2 \times 0.01m}{343 m/s} = 58.3\mu s (Factor of 2 because sound travels to object and back)

  2. Evaluate ADC-based approach:

    • If we sample analog echo signal at 100kHz: 10us between samples
    • Time resolution: 10us corresponds to 0.17cm
    • Problem: HC-SR04 outputs digital pulse, not analog - ADC not appropriate
  3. Evaluate timer-based approach (correct method):

    • ESP32 timer at 80MHz: 12.5ns resolution
    • Theoretical distance resolution: 0.5 x 343 m/s x 12.5ns = 0.002mm
    • Far exceeds 1cm requirement
  4. Implement with pulseIn() timing (try on Wokwi):

    duration_us = pulseIn(ECHO_PIN, HIGH);  // Measures pulse width
    distance_cm = duration_us / 58.3;       // Convert to distance
  5. Consider temperature compensation:

    • Speed of sound: v=331.3+0.606×Tcelsiusv = 331.3 + 0.606 \times T_{celsius} m/s
    • At 0C: v = 331.3 m/s (time factor = 60.3 us/cm)
    • At 40C: v = 355.5 m/s (time factor = 56.2 us/cm)
    • 7% error if temperature not compensated over 0-40C range

Result:

  • Use hardware timer capture, not ADC, for pulse width measurement
  • Distance calculation: distance_cm = duration_us * speed_of_sound / 20000
  • With temperature compensation: <1cm accuracy achievable

Key Insight: ADCs are for converting analog voltage levels to digital values. For timing measurements (pulse width, frequency), use hardware timers or input capture peripherals.

VeraCheckpoint: Sampling and Sensor Fit

You now know:

  • Voice at 3.4 kHz needs at least 6.8 kHz sampling, so 8 kHz gives a practical telephone-rate margin.
  • A 100 Hz vibration signal needs 200 Hz minimum sampling, but 500-1000 Hz gives filter and fault-detection margin.
  • Sensor interface choice matters: 64-sample averaging can make the soil example effectively 15-bit, while ultrasonic distance needs timer capture for 58.3us-per-cm timing and <1cm accuracy.


35.17 8-bit DAC Motor Control

Now reverse the conversion path. Instead of asking which code represents a measured voltage, ask which output voltage a digital code will command.

Given:

  • DAC Resolution: 8 bits (0-255)
  • VrefV_{ref} = 5V
  • Motor controller accepts 0-5V (0V = stopped, 5V = full speed)

DAC Formula:

Vout=Vref×Digital Input2n1V_{out} = V_{ref} \times \frac{\text{Digital Input}}{2^n - 1}

Calculate Output Voltages:

Speed SettingDigital InputCalculationDAC OutputMotor Speed
Stopped05V×02555V \times \frac{0}{255}0.00V0%
25% Speed645V×642555V \times \frac{64}{255}1.25V25%
50% Speed1285V×1282555V \times \frac{128}{255}2.51V50%
75% Speed1925V×1922555V \times \frac{192}{255}3.76V75%
Full Speed2555V×2552555V \times \frac{255}{255}5.00V100%

Arduino Code Example (try on Wokwi):

// Control motor speed with DAC output
int speed_percent = 50; // 50% speed
int dac_value = map(speed_percent, 0, 100, 0, 255);

// On ESP32 with built-in DAC (8-bit, 0-3.3V output):
dacWrite(DAC1, dac_value); // Outputs ~1.65V (50% of 3.3V Vref)
// Note: For 0-5V motor control, add an op-amp gain stage after DAC

35.18 Gamma-Corrected LED Dimming

Human eyes perceive brightness logarithmically, not linearly. A “50% brightness” setting needs gamma correction.

Linear DAC (appears too bright):

  • 50% digital value (128/255) → 2.5V → appears ~75% bright to human eye

Gamma-Corrected DAC (perceptually accurate):

Corrected Value=(Desired Brightness100)2.2×255\text{Corrected Value} = \left(\frac{\text{Desired Brightness}}{100}\right)^{2.2} \times 255

For 50% perceived brightness:

Corrected Value=(50100)2.2×255=(0.5)2.2×255=0.2176×25556\text{Corrected Value} = \left(\frac{50}{100}\right)^{2.2} \times 255 = (0.5)^{2.2} \times 255 = 0.2176 \times 255 \approx 56

Comparison:

Desired BrightnessLinear DAC ValuePerceived BrightnessGamma-Corrected DACPerceived Brightness
25%64~45% (too bright)1225%
50%128~75% (too bright)5650%
75%192~90% (too bright)13575%

Arduino Gamma Correction Code:

// Gamma correction lookup table (saves computation)
const uint8_t gamma8[] = {
    0,  0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  2,  3,  3,  4,  4,
    5,  5,  6,  7,  8,  8,  9, 10, 11, 12, 13, 15, 16, 17, 18, 20,
   21, 23, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 45, 48, 50, 53,
   56, 59, 62, 65, 68, 71, 75, 78, 82, 85, 89, 93, 97,101,105,110,
  114,119,123,128,133,138,143,149,154,160,165,171,177,183,189,195,
  202,208,215,222,229,236,243,250,255 // ... (256 values total)
};

void setLEDBrightness(int percent) {
    int linear = map(percent, 0, 100, 0, 255);
    int corrected = gamma8[linear]; // Apply gamma correction
    analogWrite(LED_PIN, corrected); // PWM output
}

VeraCheckpoint: DAC and Dimming

You now know:

  • An 8-bit DAC spans 0-255 codes, so 64, 128, 192, and 255 produce about 1.25V, 2.51V, 3.76V, and 5.00V on a 5V reference.
  • On an ESP32, the same 50% code maps to about 1.65V because the built-in DAC uses a 3.3V output range.
  • Gamma correction changes a 50% perceived LED setting from linear code 128 to about code 56 with gamma 2.2.


35.19 Knowledge Check Quiz


Math helps the Sensor Squad turn real-world measurements into exact numbers!

35.19.1 Temperature Detective Story

Temperature Terry was measuring the temperature of a fish tank. “It is 25 degrees Celsius! I am sending out 0.250 volts.”

ADC Andy looked at the signal. “Okay, I need to turn that into a number Max can understand. My scale goes from 0 to 1023 — that is 1024 steps because I am a 10-bit ADC.”

the microcontroller was curious. “How do you figure out which step number matches 0.250 volts?”

Andy pulled out his formula notebook. “Easy! The fish tank sensor goes from 0 volts (freezing) to 1 volt (boiling hot for fish). So 0.250 volts is one quarter of the way. One quarter of 1023 is about 255. So I tell Max: the reading is 255!”

the LED wanted to know more. “And how does Max turn 255 back into a temperature?”

Max smiled. “I divide 255 by 1023 and multiply by 100 degrees. That gives me about 25 degrees — exactly what Sammy measured!”

the battery chimed in. “But what if you only had 256 steps instead of 1024?”

Andy nodded. “Then each step would be a bigger jump — about 0.4 degrees instead of 0.1 degrees. I would be less precise. That is why more steps (higher resolution) means better measurements!”

35.19.2 Key Words for Kids

WordWhat It Means
ADC FormulaThe math equation that converts voltage to a number
ResolutionHow many steps you have (more steps = more precise)
Reference VoltageThe maximum voltage the ADC can measure
Quantization ErrorThe tiny mistake from rounding to the nearest step
Gamma CorrectionSpecial math to make LED brightness look right to human eyes

35.19.3 Try This at Home!

The Step Calculator Game!

  1. Imagine you have a ruler that only goes from 0 to 10 (11 marks)
  2. Measure something that is about 7.3 cm long
  3. With only 11 marks, you would round to 7 — that is like an ADC with low resolution!
  4. Now imagine a ruler with 0 to 100 (101 marks) — you could say 73!
  5. With 0 to 1000 (1001 marks) — you could say 730!

What you learned: More marks on your ruler (higher ADC resolution) means you can measure more precisely. The rounding you do is quantization error — it is small but always there!

ADC Input Impedance Pitfall
  1. Voltage Vera crosses out a high-resistance sensor wired straight to a sampling converter with a falsely low meter reading; the same panel inserts an amplifier buffer and shows the input charging correctly.

    Wrong: A weak sensor source always gives a true reading. Add a buffer so the input can charge.

Correct the belief that a high-resistance sensor source can always drive a converter input accurately without a buffer.

The Error: You design a voltage divider to scale a 5V sensor output to 3.3V for an ESP32 ADC input using 10kΩ resistors. The circuit works in simulation but reads incorrectly in hardware. What went wrong?

Why It Happens: ADC inputs are not infinite impedance. The ESP32 ADC has an internal sample-and-hold capacitor that draws charging current during conversion. High-impedance sources (like voltage dividers with large resistors) cannot supply enough current fast enough, causing the ADC to read lower voltages than expected.

The Numbers:

  • ESP32 ADC: Input impedance ~100 MΩ (DC), but sample capacitor ~6 pF
  • Voltage divider: 10kΩ + 10kΩ = 20kΩ output impedance
  • RC time constant: 20kΩ × 6pF = 120 ns
  • ESP32 ADC conversion time: ~10 µs

Problem: The 120 ns charging time seems fast, but if the source impedance is too high, the sample capacitor doesn’t fully charge during the ADC’s acquisition phase. Result: readings are 5-10% low.

Correct Design Rules:

  1. Keep source impedance low: For ESP32 ADC, keep total resistance <10kΩ

    • Use 1kΩ + 1kΩ divider instead of 10kΩ + 10kΩ
    • Trade-off: Lower resistance = more current draw (power vs accuracy)
  2. Add buffer capacitor: 0.1µF capacitor at ADC input

    • Acts as local charge reservoir
    • Reduces effect of source impedance
    • Place within 1 cm of ADC pin
  3. Use op-amp buffer: For high-impedance sensors (>10kΩ)

    • Rail-to-rail op-amp (MCP6002) between sensor and ADC
    • Input impedance: >1 GΩ (doesn’t load sensor)
    • Output impedance: ~50Ω (drives ADC easily)

Example Calculation:

5V sensor → 3.3V ADC with proper buffering:

Wrong (10kΩ divider):

  • R1 = 10kΩ, R2 = 20kΩ (ratio: 3.3/5 = 0.66)
  • Output impedance: 10kΩ || 20kΩ = 6.67kΩ
  • Problem: Too high for ESP32 ADC

Right (1kΩ divider):

  • R1 = 1kΩ, R2 = 2kΩ (same ratio)
  • Output impedance: 1kΩ || 2kΩ = 667Ω ✓
  • Current draw: 5V / 3kΩ = 1.67 mA (acceptable for USB-powered)

Best (op-amp buffer):

  • High-impedance divider (100kΩ resistors, low power)
  • Op-amp output drives ADC directly
  • Total current: ~50 µA (battery-friendly)

Verification: Measure the ADC reading with a known precision voltage (e.g., voltage reference IC). If readings are consistently low, source impedance is likely the culprit.

Key Takeaway

ADC and DAC calculations are the practical math behind every sensor and actuator interface in IoT. The key formulas — Digital Output = floor((Vin/Vref) x (2^n - 1)) for ADC and Vout = Vref x (Digital Input / (2^n - 1)) for DAC — along with matching reference voltage to sensor range and applying Nyquist sampling rates, form the essential toolkit for reliable IoT hardware design.

35.20 ADC/DAC Calculation Links

Calculation TypeKey FormulaDepends OnUsed In
ADC Outputfloor((Vin/Vref) × (2^n - 1))Input voltage, Reference voltage, Resolution (n bits)All sensor readings
DAC OutputVref × (Digital / (2^n - 1))Digital value, Reference voltage, ResolutionAnalog control signals
Step SizeVref / 2^nReference voltage, ResolutionQuantization error analysis
Quantization Error±(Step Size / 2)Step sizeSensor accuracy specs
Sampling Ratefs ≥ 2 × fmaxMaximum signal frequencyNyquist compliance
PWM Duty Cycle(Desired Output / Vmax) × 100%Target voltage, Supply voltageLED dimming, Motor speed
Gamma CorrectionVout = Vin^γ (γ ≈ 2.2)Linear input valueLED brightness perception
Voltage DividerVout = Vin × (R2 / (R1+R2))Input voltage, Resistor ratioLevel shifting 5V→3.3V
Source ImpedanceRtotal = R1R2

Key Insight: Every ADC calculation starts with matching Vref to the sensor’s output range to maximize resolution. The floor() function causes quantization error (±½ LSB), which sets the fundamental accuracy limit. For output, choose DAC (true analog) for audio/RF or PWM (cheaper, digital) for LED/motor control where fast switching is acceptable.


35.21 Continue to the Next Part

Carry this evidence into ADC and DAC: Interactive Design Calculators, which begins with Interactive Calculators.