← AXS-032

Circuit review & bench-test guide

AXS-032 — ADS1115 16-bit precision ADC PMOD module

Design-stage — board not yet fabricated

Document purpose#

This document explains the axs-032-ads1115 prototype at component level and turns the design evidence into a practical manual-review and bench-test plan. It is based on the generated schematic (generate_design.py, rev 0.1-schematic, 2026-07-12), the README, and the TI ADS111x datasheet.

The board is a design-stage prototype. The schematic is generated and ERC clean (0 errors / 0 warnings) and the netlist has been reviewed, but PCB layout has not started and no board has been fabricated or assembled. There is no first-article bench result of any kind. Every expected value below is a design target to verify, not proof that an assembled board works.

1. What the board does#

The board is a 12-pin PMOD (Type 6 extended, I2C) module carrying a TI ADS1115 16-bit delta-sigma ADC: 4 single-ended / 2 differential inputs, an internal reference and oscillator, a PGA spanning ±0.256 V to ±6.144 V full scale, 8–860 SPS, and a comparator/conversion-ready output. AIN0–AIN3 plus a GND reference land on header J2 for breadboard use. SDA/SCL carry on-module 4.7 kΩ pull-ups (removable via solder jumpers JP1/JP2), ALERT/RDY has a 10 kΩ pull-up and reaches PMOD pin 1 through a 100 Ω series resistor, and solder jumper JP3 straps the I2C address to 0x48 (default) or 0x49.

It is the general-purpose precision analog input for the sensor line; it has no input protection network beyond the ADS1115's internal ESD diodes.

Functional block diagram#

PMOD J1                                   U1 ADS1115 (TSSOP-10)
 1 ADC_RDY <── R4 100R ── ADC_RDY_RAW <── ALERT/RDY (open drain)
                              └─ R3 10k pull-up to 3V3
 3/9  SCL ──┬── JP2 ── R2 4.7k ── 3V3    SCL
 4/10 SDA ──┴── JP1 ── R1 4.7k ── 3V3    SDA
 5/11 GND, 6/12 3V3 ── C1 100n ──────    VDD = 3V3, GND

 JP3: ADDR ── 1-2 GND (0x48, default) / 2-3 3V3 (0x49)
 J2: 1 AIN0, 2 AIN1, 3 AIN2, 4 AIN3, 5 GND

2. Safety and scope boundaries#

3. Power and control sequence#

  1. 3V3 and GND arrive on PMOD pins 6/12 and 5/11; C1 (100 nF) decouples VDD as the datasheet's typical application recommends.
  2. The ADS1115 resets on power-up, loads Config = 0x8583, and enters power-down single-shot mode: it responds on I2C but converts nothing.
  3. JP3 (bridged 1-2 by default) holds ADDR at GND, so the device answers at 7-bit address 0x48 (1001000b). ADDR is sampled continuously.
  4. The host writes the Config register to select MUX, PGA, mode, and data rate; OS = 1 starts a single-shot conversion (device wakes in ~25 µs).
  5. Results are read from the Conversion register as 16-bit two's complement. ALERT/RDY (open-drain, pulled up by R3) can signal comparator events or, with the threshold-register MSB trick, conversion-ready.
  6. If the bus idles mid-transaction for more than 25 ms, the interface times out and the transaction must be restarted.

4. Interfaces and pin maps#

PMOD pin123456789101112
NetALERT/RDYNCSCLSDAGND3V3NCNCSCLSDAGND3V3
J2 pin12345
NetAIN0AIN1AIN2AIN3GND

I2C address strap review (datasheet Table 7-2 vs this board):

ADDR wiring7-bit addressAvailable on this board?
GND0x48 (1001000b)Yes — JP3 pads 1-2, bridged by default
VDD0x49 (1001001b)Yes — cut 1-2, bridge JP3 pads 2-3
SDA0x4A (1001010b)No — not routed; noted in README for multi-module buses
SCL0x4B (1001011b)No — not routed

So at most two AXS-032 modules can share one bus. JP1/JP2 must be cut on all but one module when chaining, or the parallel pull-ups get too stiff (two modules: 2.35 kΩ effective, still legal; more is marginal).

5. Component-by-component review#

Every reference designator in generate_design.py appears below. #FLG01 and #FLG02 are ERC power-flag pseudo-components on 3V3 and GND; they have no physical footprint and are listed only for completeness.

Ref.Part / valueFunction and why neededIf absent/openIf shorted, wrong, or misassembled
J112-pin PMOD plug (I2C, doubled on pins 9/10)Host power, I2C, and ALERT/RDY connectionNo power or busOffset insertion puts 3V3 on signal pins; verify orientation
U1TI ADS1115IDGSR, TSSOP-10 (DGS)16-bit delta-sigma ADC with MUX, PGA, comparator — the entire module functionNo conversionsRotated package puts VDD on AIN3; SDA/SCL bridge hangs the whole bus
J21x5 2.54 mm headerBreadboard access to AIN0–AIN3 and the GND referenceNo analog inputsMiscounting pins puts a source on GND; unconnected AINx float (MUX to GND reads ~0 only when selected against GND)
R14.7 kΩ 0603 (Yageo RC0603FR-074K7L)SDA pull-up; I2C is open-drain and dead without one somewhere on the busBus works only if the host provides pull-upsToo small (< ~1 k) exceeds sink capability margins; duplicated across chained modules stiffens the bus
R24.7 kΩ 0603SCL pull-up, same reasoningSame as R1Same as R1
R310 kΩ 0603ALERT/RDY pull-up; the pin is open-drain and "requires a pullup resistor" in RDY mode (datasheet 7.3.8)ALERT/RDY floats; conversion-ready edges never appearToo large slows the RDY edge into cable capacitance (10 k x 50 pF = 0.5 µs rise vs the 8 µs pulse — acceptable, but do not increase)
R4100 Ω 0603Series protection between ADC_RDY_RAW and PMOD pin 1; limits current if the host drives the lineDirect connection; host contention stresses U1's pin (abs max ±10 mA)Too large forms a divider with host input loading; 100 Ω is negligible
C1100 nF 16 V X7R (Murata GRM188R71C104KA01D)VDD decoupling; supplies the transient conversion currents (datasheet 9.1.1)Noisier conversions, worse PSR in practiceShort kills the rail (host limit should catch it)
JP12-pad solder jumper, bridged (DNP in BOM/POS)Disconnects R1 when chaining modulesIf cut with no other SDA pull-up: bus hangsRe-bridge with solder to restore
JP22-pad solder jumper, bridgedSame for SCL/R2Same as JP1Same as JP1
JP33-pad solder jumper, 1-2 bridgedADDR strap: 1-2 = GND = 0x48, 2-3 = 3V3 = 0x49ADDR floats — address undefined/unreliable; never leave openBridging all three pads shorts 3V3 to GND through the jumper
#FLG01/#FLG02ERC power flags (3V3, GND)Schematic ERC bookkeeping onlyERC warningsNot applicable; no physical part

6. Datasheet summary and design interpretation#

Consulted: TI ADS1113/ADS1114/ADS1115 datasheet SBAS444E (May 2009 – revised December 2024), <https://www.ti.com/lit/ds/symlink/ads1115.pdf>, product page <https://www.ti.com/product/ADS1115>.

Manufacturer fact (SBAS444E)Board-specific interpretation
Supply 2.0–5.5 V; operating I_VDD 150 µA typ (200/300 µA max), power-down 0.5 µA typ3.3 V PMOD rail fits; whole module draws well under 1 mA
I2C standard (100 kHz), fast (400 kHz), and high-speed (3.4 MHz) modes; Hs needs the 00001xxx controller-code preamble; 25 ms bus-idle timeoutBring up at 100 kHz, run at 400 kHz; Hs mode is possible but pointless at these data rates and untested here
ADDR pin selects 0x48/0x49/0x4A/0x4B (GND/VDD/SDA/SCL), sampled continuouslyJP3 exposes only 0x48 and 0x49 (Section 4)
PGA FSR / LSB: ±6.144 V / 187.5 µV, ±4.096 / 125 µV, ±2.048 / 62.5 µV (default), ±1.024 / 31.25 µV, ±0.512 / 15.625 µV, ±0.256 / 7.8125 µVFSR is a scaling choice; at VDD = 3.3 V the top two ranges can never produce full-scale codes (max input ≈ VDD)
Inputs must stay within GND − 0.3 V to VDD + 0.3 V no matter the PGA settingThe single most important user-facing rule for J2; repeated on the schematic pin-map note
Data rates 8–860 SPS (DR[2:0]); conversion time = 1/DR; single-shot wake ~25 µs; result is 16-bit two's complement, cleared to 0x0000 at power-upSingle-ended readings span 0x0000–0x7FFF; a small negative offset can legitimately read 0xFFxx near 0 V
Registers via pointer byte: 00b Conversion (reset 0x0000), 01b Config (reset 0x8583), 10b Lo_thresh (reset 0x8000), 11b Hi_thresh (reset 0x7FFF)See exact byte sequences in Section 9.C/9.E
Conversion-ready mode (7.3.8): Hi_thresh MSB = 1 and Lo_thresh MSB = 0, COMP_QUE != 11; ALERT/RDY then gives an ~8 µs conversion-ready pulse in continuous mode, or asserts at conversion end in single-shot; COMP_POL still selects polarityNote the reset values have the MSBs the wrong way round (Lo = 0x8000, Hi = 0x7FFF): both thresholds must be rewritten to enable RDY mode
Internal reference and 1 MHz oscillator; no external reference or clock possible; reference error folded into gain error (0.01% typ / 0.15% max at FSR ±2.048)Unlike the MCP3008 board, readings are absolute, not ratiometric: a 3V3-derived divider input will move with the rail while the ADC's scale does not
Common-mode/differential input impedance is finite and FSR-dependent (e.g. 6 MΩ CM at ±2.048 V FSR; 710 kΩ differential at ±0.512/±0.256)High-impedance dividers on J2 will read low; keep divider Thevenin impedance a few kΩ or budget the error

Check the latest datasheet revision before procurement.

7. Expected values before bench testing#

Targets assume VDD = 3.300 V, address 0x48, and the divider tests of Section 9.D built from 1% resistors. All are design targets, not measured results.

QuantityDesign target / calculatedWhat to measure
Supply current, idle (power-down)~0.5–5 µA device + ~0 moduleBench supply, standalone context
Supply current, continuous 128 SPS~150–300 µASame
I2C scanACK only at 0x48 (JP3 1-2) / 0x49 (2-3)Adapter address scan
Config readback after reset0x8583First read, Section 9.C
Conversion register at power-up0x0000Read before any conversion
Divider A (10k/10k from 3V3): V(AIN0)1.650 V ± ~1.7% (resistor + rail tolerance)DMM at J2 pin 1
Divider A code, FSR ±6.144 V~0x2260 (8800)Section 9.D
Divider A code, FSR ±4.096 V~0x3390 (13200)Same
Divider A code, FSR ±2.048/1.024/0.512/0.256 V0x7FFF (clipped — input exceeds FSR; still safe, well under VDD + 0.3 V)Same
Divider B (33k/1k from 3V3): V(AIN1)~97.1 mV nominalDMM at J2 pin 2
Divider B code, FSR ±6.144 V~0x0206 (518)Section 9.D
Divider B code, FSR ±4.096 V~0x0308 (776)Same
Divider B code, FSR ±2.048 V~0x0611 (1553)Same
Divider B code, FSR ±1.024 V~0x0C22 (3106)Same
Divider B code, FSR ±0.512 V~0x1844 (6212)Same
Divider B code, FSR ±0.256 V~0x3088 (12424)Same
RDY pulse, continuous 128 SPS~8 µs pulse every ~7.8 msScope on ADC_RDY
Grounded AINx, FSR ±2.048 V0x0000 ± ~3 LSB (offset spec ±3 LSB single-ended)Jumper to J2 GND

Divider-B codes scale with the actual rail and resistor values; compute the expected code as V_meas / LSB and compare within ±(0.2% + noise) as a sanity bound. Datasheet RMS noise at 128 SPS is a few µV — negligible next to resistor tolerance.

8. Manual schematic and assembly review checklist#

Ordered bench-test procedure#

Stop at the first abnormal result. Record board serial, host identity, bus speed, measured VDD, and divider resistor values.

A. Unpowered inspection and resistance tests#

  1. Complete the checklist above under magnification.
  2. Measure 3V3-to-GND resistance in both polarities; investigate < 1 kΩ.
  3. Confirm SDA and SCL each read ~4.7 kΩ to 3V3 and are not shorted to each other or to GND.

B. First power, no I2C traffic#

Context (a) — PMOD host: plug into a 3.3 V PMOD port on the ECP5 host (ULX3S-class) with the FPGA unconfigured. Context (b) — standalone: wire 3V3/GND from a current-limited bench supply and SDA/SCL/ALERT to a 3.3 V lab adapter (Raspberry Pi Pico, FT2232H, Bus Pirate — I2C mode).

  1. Supply current in the idle band; SDA, SCL, and ADC_RDY all sit at 3V3 (pull-ups working, nothing stuck low).
  2. Measure VDD at U1 pin 8.

C. First transaction bring-up (exact bytes)#

Bus speed 100 kHz for bring-up. Address 0x48 means write byte 0x90 and read byte 0x91 on the wire.

  1. Address scan / probe read. Read 2 bytes: S 0x91 [D15] [D7..D0] P. After power-up the pointer resets and the Conversion register reads 0x00 0x00. An ACK on 0x91 at all is the first pass criterion; NACK means address/JP3/solder trouble.
  2. Config readback. Write the pointer only: S 0x90 0x01 P, then read two bytes: S 0x91 [MSB] [LSB] P. Expect the reset value 0x85 0x83.
  3. First conversion. Write Config for a single-shot conversion of AIN0 vs GND, FSR ±4.096 V, 128 SPS, comparator disabled — bytes on the wire:

S 0x90 0x01 0xC3 0x83 P

(0xC3 = OS 1, MUX 100 = AIN0/GND, PGA 001 = ±4.096 V, MODE 1; 0x83 = DR 100 = 128 SPS, COMP_MODE 0, COMP_POL 0, COMP_LAT 0, COMP_QUE 11 = disabled.)

  1. Wait >= 9 ms (1/128 s + margin), or poll Config until the MSB's OS bit reads 1 (0xC3 0x83 back; 0x43 0x83 while still converting).
  2. Set the pointer to Conversion and read: S 0x90 0x00 P, then S 0x91 [MSB] [LSB] P. With Divider A on AIN0 expect ~0x33 0x90 (Section 7). With AIN0 grounded expect 0x0000 ± ~3 LSB (small negative values read as 0xFFxx — two's complement, not a fault).

D. PGA range walk with known dividers#

Build on a breadboard from J2: Divider A = 10.0k/10.0k (1%) from 3V3 to GND, tap to AIN0 (~1.650 V); Divider B = 33.0k/1.00k (1%) from 3V3 to GND, tap to AIN1 (~97.1 mV). Both taps are DMM-verified before trusting any code.

  1. For each FSR, write Config MSB with the PGA bits set, single shot, MUX = AIN0 (0x4x/0xCx values below), LSB = 0x83, then read the result:
FSRConfig MSB (AIN0)Divider A expectedConfig MSB (AIN1: MUX 101)Divider B expected
±6.144 V0xC1~0x22600xD1~0x0206
±4.096 V0xC3~0x33900xD3~0x0308
±2.048 V0xC50x7FFF (clip)0xD5~0x0611
±1.024 V0xC70x7FFF (clip)0xD7~0x0C22
±0.512 V0xC90x7FFF (clip)0xD9~0x1844
±0.256 V0xCB0x7FFF (clip)0xDB~0x3088
  1. The Divider A clips are the teaching point: the code saturates cleanly because 1.65 V exceeds those FSRs, and this is only safe because 1.65 V is far below VDD + 0.3 V. Never demonstrate clipping with a voltage above the supply window.
  2. Cross-check each unclipped code x LSB against the DMM reading of the tap. Note the finite input impedance (Section 6): Divider B's ~0.97 kΩ Thevenin impedance keeps loading error below ~0.15% even at the 710 kΩ differential-impedance ranges.

E. ALERT/RDY conversion-ready bring-up (exact bytes)#

Reset defaults (Lo = 0x8000, Hi = 0x7FFF) have the MSBs in the comparator orientation; RDY mode requires rewriting both thresholds.

  1. Write Hi_thresh MSB = 1: S 0x90 0x03 0x80 0x00 P (Hi_thresh = 0x8000).
  2. Write Lo_thresh MSB = 0: S 0x90 0x02 0x00 0x00 P (Lo_thresh = 0x0000).
  3. Write Config for continuous conversion, AIN0, ±4.096 V, 128 SPS, COMP_QUE = 00 (assert after one conversion), COMP_POL = 1 (active-high pulse, matching datasheet Figure 7-8):

S 0x90 0x01 0xC2 0x88 P

(0xC2 = OS 1/ignored, MUX 100, PGA 001, MODE 0; 0x88 = DR 100, COMP_MODE 0, COMP_POL 1, COMP_LAT 0, COMP_QUE 00.)

  1. Scope ADC_RDY (PMOD pin 1): expect an ~8 µs high pulse every ~7.8 ms (128 SPS). With COMP_POL = 0 (LSB 0x80) the pulse inverts: the line idles high through R3 and pulses low. In single-shot mode (MODE = 1) ALERT/RDY instead asserts at the end of each triggered conversion.
  2. In the PMOD-host context, this is the interrupt line for the eventual HDL: verify the FPGA sees clean edges through R4 and that a conversion read always follows a pulse before the next one arrives.
  3. Restore comparator-off defaults afterwards (Config LSB COMP_QUE = 11) or power-cycle.

F. Rate, chaining, and host-integration tests#

  1. Repeat 9.D at 8 SPS and 860 SPS; codes must agree within the extra noise at 860 SPS (tens of µV RMS).
  2. Two-module bus test (when two boards exist): one at 0x48, one strapped 0x49, JP1/JP2 cut on the second; scan must show both, and neither 0x4A nor 0x4B (not supported by this board's strap).
  3. 400 kHz fast-mode regression of 9.C–9.E.
  4. Temperature, EMC, and long-cable testing are out of scope for the first article.

10. Troubleshooting map#

SymptomFirst measurementsLikely areas
No ACK at 0x48ADDR pin voltage, SDA/SCL idle levelsJP3 open or bridged 2-3 (device is at 0x49), TSSOP solder, pull-ups
ACK at unexpected addressADDR voltage (should be 0 V or 3V3)JP3 floating/partial bridge
Bus hangs (SDA stuck low)Which device holds SDA; power-cycle testSolder bridge, mid-transaction abort (25 ms timeout eventually releases), host driver
Config readback != 0x8583 at power-upRepeat after clean power cycleBytes misordered (MSB first), pointer not 0x01, earlier write persisted
Conversion always 0x0000OS bit behavior, MODE bitNever started (OS not set in single-shot), reading before first conversion
Codes ~half expectedConfig PGA bits readbackWrong FSR/LSB pairing in host math
Code clipped at 0x7FFF unexpectedlyDMM the input, check FSRInput exceeds selected FSR (or approaches VDD)
Small negative codes on grounded inputOffset within ±3 LSB?Normal two's-complement offset, not a fault
No RDY pulsesHi/Lo_thresh MSBs, COMP_QUE bitsThresholds left at reset values, QUE = 11, R3/R4 path, MODE single-shot
RDY polarity invertedCOMP_POL bitConfig LSB 0x88 vs 0x80
Readings drift with 3V3 railRail voltage vs codeExpected for rail-derived dividers: the ADC reference is internal/absolute — the divider voltage itself moved

11. Bench record template#

FieldRecord
Board revision / serial
Host context (PMOD FPGA / standalone adapter) and IDs
JP1/JP2/JP3 states as inspected
Bus speed(s) used
Measured VDD
Address scan result
Config readback (expect 0x8583)
First conversion bytes sent/received
Divider A/B measured voltages and resistor values
PGA walk table (6 FSRs x 2 dividers) actual codes
RDY pulse width / period capture
8 vs 860 SPS comparison
Deviations, captures, raw-file paths
Reviewer / date / disposition

12. Review conclusion#

The design is a clean minimal application of the ADS1115: correct open-drain treatment of all three shared lines, cuttable pull-ups for multi-module buses, a two-position address strap that covers the two addresses reachable without routing ADDR to SDA/SCL, and series protection on the one line the ADC drives toward the host. The datasheet's central caution — that no PGA setting extends the safe input window beyond VDD + 0.3 V — is carried onto the schematic and must be carried into user documentation. The principal open risks are that no PCB exists yet (layout, input routing, and decoupling placement unverified), the total absence of input protection parts on J2 (deliberate, but it makes the input-window rule load-bearing), only two bus addresses being available, and the fact that every expected code in this guide is calculated from the datasheet rather than measured on hardware.