Skip to the content
2 layers78 × 99.5 mmPrecision AFE ESP32, the printed circuit board in 3D

A highly precise, ±100 mV analog front-end (AFE) designed for the ESP32 and ADS1115. Features a 4-stage TL082 architecture including a Sallen-Key low-pass filter, delivering 9.4 µV/LSB resolution for precision data acquisition.

Size
78 × 99.5 mm
Copper layers
2
Thickness
1.6 mm
Parts
29
Nets
52
Pads
115
Tracks, vias
209, 10
Pours
2
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
24 Aug 2026
Updated
20 Sep 2026

Overview

Precision AFE ESP32 is an open-source printed circuit board by LemonAidLee, from the LemonAidLee/Precision-Analog-Front-End repository on GitHub, published under the CERN-OHL-P-2.0 licence. It is a 2-layer board of 78 × 99.5 mm with 29 parts on 52 nets, routed with 209 tracks and 10 vias.

It is built around the TL082, LM7812 and LM7912T. Its parts include 7 capacitors, 5 connectors, 4 ICs and 2 resistors. It belongs with the ESP32 boards of this library.

Main components

3

README

README.md

Precision Mixed-Signal Data Acquisition Front End (AFE)

A four-stage precision analog front end that conditions a ±100 mV bipolar sensor signal into the 0–3.3 V unipolar window of a 16-bit ADS1115 ADC, designed for an ESP32-WROOM-32 host. Designed, simulated in LTspice, and laid out in KiCad. Not built — no physical hardware exists.

PCB 3D render, top view

Rev A board (78 mm × 100 mm, 2-layer), KiCad 3D render. The physical board has not been manufactured.


Overview

A sensor that outputs a few tens of millivolts, swinging both positive and negative, cannot be connected to a single-supply ADC. It is too small to use the converter's resolution, it goes below the converter's ground rail, and it carries out-of-band content the converter will alias.

This project is the hardware that sits between the two: an analog front end that band-limits, amplifies, and re-centres the signal so that a 16-bit ADC sees a well-conditioned, in-range voltage, and an ESP32 can read it over I²C.

Input±100 mV bipolar, single-ended (J1)
Output0.31 V … 2.96 V unipolar, centred on VREF (to ADS1115 A0)
Overall gain13.25 V/V (22.4 dB)
Bandwidth2nd-order Butterworth low-pass, f₀ = 1.06 kHz
Analog supply±15 V (unregulated), external via screw terminal (J2); regulated on-board to ±12 V by LM7812 / LM7912
Digital supply3.3 V from the ESP32 module's on-board regulator
Op-amps2 × TL082 (dual JFET-input), DIP-8
ADCADS1115 breakout, 16-bit, I²C, ±4.096 V FSR
Board78 mm × 100 mm, 2-layer, 1.6 mm, all through-hole
StatusDesigned · Simulated (DC) · Schematic complete · PCB fully routed with GND pour

Engineering motivation

Connecting a low-level sensor directly to a microcontroller ADC fails for four independent reasons, and each one needs its own circuit stage:

ProblemConsequenceStage that solves it
Signal is out-of-band above ~1 kHzHigh-frequency interference folds back into the measurement bandStage 1 — Sallen-Key low-pass
Signal is ~100 mV into a 4.096 V converter spanOnly ~2.4 % of the ADC range is used; quantisation noise dominatesStage 2 — ×10 gain
Signal is bipolar; the ADC ground rail is 0 VNegative half-cycles are clipped or damage the inputStage 3 — inverting summing level shift onto VREF
The summing stage inverts the signalPolarity is wrong at the ADCStage 4 — unity-gain inverter

Doing all four in one stage is possible but couples the design decisions together — the gain would set the filter Q, the offset would move with gain, and nothing could be probed independently. Splitting them keeps every design equation independent and gives four testable nodes.


Signal flow

text
                 ±100 mV                  ±159 mV               ±1.59 V
   SENSOR ──▶ ┌───────────┐  VFILTER  ┌───────────┐  VAMP  ┌──────────────┐
   J1         │  STAGE 1  │ ────────▶ │  STAGE 2  │ ─────▶ │   STAGE 3    │
              │ Sallen-Key│           │ Non-inv.  │        │  Inverting   │
              │  LPF ×1.59│           │  amp ×10  │        │  summer      │
              │  U1A      │           │  U1B      │        │  U2A         │
              └───────────┘           └───────────┘        └──────┬───────┘
                                                                  │ VX
                        +3.3 V                                    │ −2.96 … −0.31 V
                          │                                       ▼
                     ┌────┴────┐  VREF = 1.637 V           ┌──────────────┐
                     │ 470/470 │ ─────────────────────────▶│   STAGE 4    │
                     │ divider │                           │ Unity inv.   │
                     │ + 100 nF│                           │  U2B         │
                     └─────────┘                           └──────┬───────┘
                                                                  │ VADC
                                                                  │ 0.31 … 2.96 V
                                                                  ▼
                                                        ┌────────────────────┐
                                                        │ ADS1115  (A0)      │
                                                        │ 16-bit, ±4.096 V   │
                                                        └─────────┬──────────┘
                                                                  │ I²C (SDA/SCL)
                                                                  ▼

Full node-by-node breakdown: 03 — Signal Path


Key specifications

ParameterDesign valueSource
Input range±100 mVDesign target (silkscreened on board)
Stage 1 passband gain, K1 + 5.9k/10k = 1.590Calculated, LTspice-confirmed
Stage 1 cutoff, f₀1/(2π·1.5k·100n) = 1061 HzCalculated
Stage 1 Q1/(3 − K) = 0.709 (Butterworth ≈ 0.707)Calculated
Stage 2 gain1 + 90k/10k = 10.00Calculated, LTspice-confirmed
Stage 3 signal gain−30k/36k = −0.8333Calculated, LTspice-confirmed
Stage 3 reference gain−30k/30k = −1.000Calculated
Stage 4 gain−10k/10k = −1.000Calculated
Total gain, VSENSOR → VADC13.25 V/VLTspice: 13.248 V/V
VREF (unloaded)3.3 × 470/940 = 1.650 VCalculated
VREF (loaded by Rref1)1.637 VLTspice: 1.6372 V
VADC at −100 mV / 0 / +100 mV0.313 / 1.637 / 2.962 VLTspice (TL082)
ADC resolution referred to input4.096 V / 2¹⁵ / 13.25 = 9.4 µV/LSBCalculated

Hardware architecture

Analog section (left half of the board) — two TL082 dual op-amps in DIP-8 provide the four amplifier stages. All resistors are 1/4 W axial through-hole on a 10.16 mm pitch, arranged in a single labelled column so every feedback network can be identified and swapped without a schematic in hand. Analog supplies enter on a 3-pin 5 mm screw terminal (+15V_RAW / GND / −15V_RAW) from an external bench supply; on-board LM7812 / LM7912 linear regulators (U3/U4, with C4–C7 input/output bypass) clean this to the ±12 V the op-amps actually run on. The raw rail needs headroom above 12 V for the regulators to hold regulation, which is why the connector is no longer labelled ±12 V directly.

Digital section (right half) — the ESP32 dev board seats in two 1×19 pin sockets and supplies 3.3 V from its own regulator; the ADS1115 breakout seats in a 1×10 socket above it. The two sections meet only at the VADC trace and the shared ground.

Details: 07 — KiCad Schematic and PCB


Simulation

Design verification was done in LTspice in two phases.

Phase 1 — stage development with OP1177. Each stage was designed, simulated, and iterated on its own bench: the Sallen-Key filter (AC sweep + transient), the ×10 gain stage (AC + transient), the level shifter, and then a two-stage and finally a four-stage integration. This phase used the OP1177 model that ships with LTspice, and produced the resistor values now in the schematic.

Phase 2 — TL082 substitution. The physical build targets TL082, so a third-party TL082 PSpice macromodel (TL082.lib) was brought in and the full chain re-run against it. The DC transfer at −100 mV / 0 / +100 mV was extracted and matches the ideal transfer function to within 0.02 %.

LTspice full chain, TL082

Four-stage chain as simulated with the TL082 macromodel.

Test conditionIdeal (calculated)LTspice, TL082Δ
VSENSOR = 01.637 V1.63737 V+0.4 mV
VSENSOR = +100 mV2.962 V2.96220 V+0.2 mV
VSENSOR = −100 mV0.313 V0.31254 V−0.2 mV

Two simulation issues are open and are not hidden here: the TL082 build's filter section is wired as a passive two-pole RC rather than the Sallen-Key that is in the KiCad schematic (DC results unaffected, AC results not representative), and the OP1177 reference file no longer runs. Both are documented in 05 — LTspice Simulation.

Full detail: 05 — LTspice Simulation · 06 — Simulation Results


PCB design

PCB layout, 2D

F.Cu (red), B.Cu (blue — mostly the GND pour), silkscreen and board outline. Fully routed.

  • 78.1 mm × 99.6 mm bounding box (2 layers, 1.6 mm FR4)
  • 29 footprints, all through-hole; 115 pads
  • 209 track segments (112 on F.Cu, 97 on B.Cu), ≈1355 mm total; 10 vias (0.6 mm / 0.3 mm drill)
  • GND poured on both F.Cu and B.Cu (2 zones, 0.25 mm min thickness)
  • Design rules: 0.2 mm min clearance, 0.2 mm min track, 0.5 mm copper-to-edge
  • DRC: 0 violations. ERC: 0 errors, 32 warnings (all "label connected to only one pin" — the unused ESP32 GPIO breakout labels)
  • No test points; no local decoupling at the op-amp supply pins

Routing is complete. Every net — including the seven internal analog nodes (the two filter nodes and the five op-amp inverting-input/feedback nodes) that an earlier netlist-sync bug had left with no copper — now has a fully routed connection, plus a GND pour on both layers. See 07 — KiCad Schematic and PCB for the routing table and the story of that bug.


ESP32 + ADS1115 interface

The digital side is a hardware interface only — no firmware has been written.

ADS1115 (J5)NetGoes to
1 VDD+3V3J3-1 (ESP32 3V3)
2 GNDGNDBoard ground
3 SCLSCLJ4-3 (ESP32 GPIO22)
4 SDASDAJ4-6 (ESP32 GPIO21)
5 ADDRGNDSets I²C address 0x48
6 ALRT—Not connected
7 A0VADCStage 4 output
8–10 A1–A3—Not connected

Details: 09 — ESP32 + ADS1115 Interface


Verification status

ItemDesignedSimulatedOn PCBRoutedPhysically tested
Sallen-Key low-pass (U1A)✓✓ (AC/transient, OP1177 · DC only, TL082)✓✓—
×10 gain stage (U1B)✓✓ (AC/transient, OP1177 · DC, TL082)✓✓—
Level shifter (U2A)✓✓ (DC, TL082)✓✓—
Unity inverter (U2B)✓✓ (DC, TL082)✓✓—
1.65 V reference divider✓✓ (DC, TL082, incl. loading)✓✓—
ADS1115 interface✓—✓✓—
ESP32 interface✓—✓✓—
±12 V regulation (LM7812/LM7912)✓ideal sources only in signal-chain sims✓✓—
Firmware—————

No physical prototype exists. The board has not been fabricated, assembled, powered, or measured. Every performance figure in this repository is either a hand calculation or an LTspice result. Physical hardware validation is outside the current project scope.


Engineering challenges

  • Choosing K = 1.59 rather than "gain = 1". In an equal-component Sallen-Key, the passband gain and the pole Q are the same knob: Q = 1/(3 − K). A unity-gain buffer would give Q = 0.5 (overdamped, soft knee). K = 1.586 is the value that lands Q on 0.7071 — maximally flat. The 5.9 kΩ / 10 kΩ pair gives K = 1.590 and Q = 0.709, 0.3 % from ideal, using stock values.
  • Sizing the level shifter so the extremes stay inside the rail, not just the centre. An earlier iteration used Rin1 = 20 kΩ. That still centred on 1.65 V at zero input, but the ±100 mV extremes landed at −0.74 V and +4.03 V — outside the ADC's supply rails in both directions. Rin1 = 36 kΩ trades gain for headroom and puts the extremes at 0.31 V / 2.96 V.
  • Predicting the reference divider's error before simulating it. VREF is not 1.650 V in circuit; Rref1 (30 kΩ) sinks ~55 µA from a 235 Ω source, pulling it to 1.637 V. That 13 mV shift is a fixed offset the firmware can calibrate out — but it had to be identified as a systematic error rather than mistaken for simulation noise.
  • Migrating from a model that exists to a part that can be bought. OP1177 has a vendor-supplied LTspice model; TL082 does not ship with LTspice. Getting the TL082 macromodel to converge required source stepping, and re-running the chain surfaced the fact that the two integration files had drifted apart.

Current project status

Designed · Simulated · Schematic complete · PCB placed and fully routed with a GND pour · Documented.

Not manufactured, not assembled, not physically validated, not production-ready.


Limitations

  • No physical prototype; no oscilloscope, multimeter, or spectrum measurements of any kind.
  • No local supply decoupling at the TL082 pins, no test points on the current board.
  • ±12 V is regulated on-board (LM7812/LM7912), but the input rail is still an external, unregulated ±15 V supply — there is no AC-mains or USB-derived path to that rail.
  • The TL082 full-chain simulation covers DC only; there is no AC or transient run against the TL082 model, and its filter section does not match the board.
  • The AC and transient results in this repository were produced with OP1177, not the TL082 that is on the schematic.
  • The 1.06 kHz filter corner sits above the ADS1115's 430 Hz Nyquist frequency at its 860 SPS maximum rate — it band-limits the signal but does not anti-alias the converter.
  • No input protection, no reverse-polarity protection, no sensor characterisation.
  • No firmware.

Future improvements

  1. Resolve the two open simulation discrepancies (filter topology in the TL082 file; repair the OP1177 reference bench).
  2. Run AC and transient sweeps against the TL082 model and compare to the OP1177 reference.
  3. Add 100 nF decoupling at each TL082 supply pin, and test points at VSENSOR / VFILTER / VAMP / VREF / VADC.
  4. Fabricate and assemble; bring up the rails before the signal chain.
  5. Measure DC transfer, frequency response, and noise floor; compare against simulation.
  6. Write ESP32 firmware: I²C driver for the ADS1115, offset/gain calibration, data logging.
  7. Revise to Rev B against measured data.

Done since the last revision of this document: PCB routing is complete (including seven internal analog nets a netlist-sync bug had silently left unrouted — see 07 §5), a GND pour was added on both copper layers, and on-board LM7812/LM7912 regulation replaced the external-±12V-only supply architecture.


Repository structure

text
.
├── README.md                     ← this file
├── docs/                         ← full engineering documentation
│   ├── README.md                 ← documentation index
│   ├── 01_Project_Overview.md
│   ├── 02_System_Architecture.md
│   ├── 03_Signal_Path.md
│   ├── 04_Analog_Circuit_Design.md
│   ├── 05_LTspice_Simulation.md
│   ├── 06_Simulation_Results.md
│   ├── 07_KiCad_Schematic_and_PCB.md
│   ├── 08_Components_and_BOM.md
│   ├── 09_ESP32_ADS1115_Interface.md
│   ├── 10_Engineering_Decision.md
│   ├── Portfolio_Summary.md      ← recruiter-facing summary
│   ├── images/                   ← schematic, PCB and LTspice figures
│   └── design_files/             ← generated PDF / BOM exports + source pointers
├── KiCAD_PCB_Design/             ← KiCad 10 project (schematic, PCB, STEP)
├── LTSpice_Simulation/           ← LTspice schematics, netlists, TL082 model
└── Precision DAQ AFE_Documentation/   ← original engineering log / working notes

Skills demonstrated

Analog design — active filter synthesis (Sallen-Key, Butterworth Q targeting), op-amp gain-stage design, inverting summing amplifiers, level shifting, resistive reference design with loading analysis, supply-rail headroom budgeting.

Simulation — LTspice AC / transient / DC-sweep analysis, third-party SPICE macromodel integration, convergence troubleshooting (Gmin and source stepping), model-substitution verification, netlist-level inspection.

PCB design — KiCad 10 schematic capture, footprint assignment, through-hole layout, functional block placement, analog/digital section separation, DRC/ERC.

Mixed-signal / embedded — external ADC selection and interfacing, I²C bus wiring, ADS1115 address strapping and PGA range selection, ESP32 dev-board integration.

Engineering process — requirement-driven stage decomposition, quantitative trade-off analysis, iterative design revision with superseded values preserved, honest separation of calculated / simulated / measured, self-audit of design-file consistency.


Documentation

Start at docs/README.md for the full index.

  • docs/01–09 — the technical documentation: overview, architecture, signal path, circuit design, simulation, PCB, BOM, and the ESP32/ADS1115 interface.
  • docs/10_Engineering_Decision.md — every significant design choice, the alternative it was taken over, and the reasoning.
  • docs/Portfolio_Summary.md — a short, recruiter-facing summary of the same project.

Parts

29
QtyValueFootprintReferences
5100nCapacitor_THT:C_Disc_D5.0mm_W2.5mm_P5.00mmC1, C2, C3, C5, C7
410kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalRf4, Rg1, Rg2, Rin2
21.5kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR1, R2
230kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalRf3, Rref1
2330nCapacitor_THT:C_Disc_D5.0mm_W2.5mm_P5.00mmC4, C6
2470Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalRref_a1, Rref_b1
2TL082Package_DIP:DIP-8_W7.62mmU1, U2
136kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalRin1
15.9kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalRf1
190kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalRf2
1ADS1115_MODULEConnector_PinSocket_2.54mm:PinSocket_1x10_P2.54mm_VerticalJ5
1ESP32_LEFT_HDRConnector_PinSocket_2.54mm:PinSocket_1x19_P2.54mm_VerticalJ3
1ESP32_RIGHT_HDRConnector_PinSocket_2.54mm:PinSocket_1x19_P2.54mm_VerticalJ4
1LM7812Package_TO_SOT_THT:TO-220-3_VerticalU3
1LM7912Package_TO_SOT_THT:TO-220-3_VerticalU4
1POWER_INPUTTerminalBlock:TerminalBlock_MaiXu_MX126-5.0-03P_1x03_P5.00mmJ2
1SENSOR_INPUTConnector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_VerticalJ1

Similar boards

  • 2 layersAccutronics Reverb, the printed circuit board in 3D

    Accutronics Reverb

    DiegoRosales/PCB_Designs

    This repository contains some of the designs I've made. Everything here is Open Source Hardware

    25 parts1
  • 2 layers99 × 96.5 mmPSU, the printed circuit board in 3D

    PSU

    danlarsson/Modular

    My Modular Eurorack Synth

    37 parts1
  • 2 layersEurorackPSU, the printed circuit board in 3D

    EurorackPSU

    spmasterman/EurorackPSU

    +/- 12v Eurorack PSU

    25 parts1
  • 2 layers91.5 × 68.7 mmMfos power, the printed circuit board in 3D

    Mfos power

    blthree/synth_schematics

    31 parts
  • 2 layers95 × 58 mmEurorack PSU, the printed circuit board in 3D

    Eurorack PSU

    MitchReyno/Electronics-Projects

    A collection of various electronics projects I've worked on over the years

    27 partsGPL-3.0
  • 2 layers160 × 63.5 mmJme euro power, the printed circuit board in 3D

    Jme euro power

    memestreak/kicad

    Personal KiCad project repo

    22 parts

Questions

How big is the Precision AFE ESP32 PCB?

It measures 78 × 99.5 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Precision AFE ESP32 use?

29 parts, built around the TL082, LM7812 and LM7912T. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Precision AFE ESP32 KiCad files?

From the LemonAidLee/Precision-Analog-Front-End repository on GitHub, at the commit this page was made from: the board is KiCAD_PCB_Design/Precision_AFE_ESP32.kicad_pcb and its schematic KiCAD_PCB_Design/Precision_AFE_ESP32.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Precision AFE ESP32 design in my own project?

Its repository publishes it under the CERN-OHL-P-2.0 licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).