Schematic
MUX / PGA config — per read cycle, both units
| Read | MUX[2:0] | AINP | AINN | PGA | Purpose |
|---|---|---|---|---|---|
| Bridge diff | 010 | AIN1 | AIN3 | 010 (±2.048V) | Bridge output → temperature |
| Rail / Vexc | 100 | AIN0 | GND | 001 (±4.096V) | Excitation health, read straight off the top of R1/R3 |
AIN2 is unused. ADS1115 only supports four fixed differential pairs — AIN0-AIN1, AIN0-AIN3, AIN1-AIN3, AIN2-AIN3 — so putting the rail monitor on AIN0 (single-ended) forces the bridge pair onto AIN1-AIN3.
Why a bridge
moon_temp_ads1115 uses a single-ended divider (3.3V → 10kΩ fixed → ADS1115 → NTC → GND), giving ~55 m°C/count. Switching to a Wheatstone half-bridge on the ADS1115's differential inputs gets three things at once: much finer resolution near the balance point, rejection of common-mode noise/lead-resistance error on the signal path (both sides of the differential pair pick up the same noise, which cancels), and a ratiometric relationship to the excitation voltage rather than an absolute one.
Component values and why
| Part | Value | Rationale |
|---|---|---|
| U1, U2 | ADS1115IDGSR (TI, VSSOP-10) | Standard industrial grade, not the AEC-Q100 automotive ADS1115BQDGSRQ1 variant — same core spec/data rate per TI's own pages; automotive qualification buys nothing here and typically costs more / has tighter sourcing. |
| R1, R2, R3 | RNCF0603TKY10K0 (Stackpole), 10.0kΩ, 0.01%, ±5ppm/°C | Matched reference divider (R1/R2) plus the sense-leg fixed resistor (R3), which has no partner to cancel against — its own drift is direct sensor error, so it gets the same spec. This part comfortably exceeds the 0.1%/≤25ppm/°C this design originally called for. |
| RT1, RT2 | B57861S0103F045 (TDK/EPCOS), 10kΩ NTC, B25/100=3988K ±0.3% | Epoxy bead, PTFE-insulated 50mm leads — good fit for thermal-epoxy mounting to the steel bar. Resistance tolerance ±1% only affects absolute matching between the two sensor units, not the bridge math. |
| U3, U4 | LM4040AEM3-2.048, A-grade | 2.048V variant lines up with the ADS1115's own ±2.048V PGA setting. A-grade (~±15ppm/°C) matters because its drift scales the entire bridge output proportionally. |
| R4 | 1.2kΩ | Bias resistor for the LM4040 shunt. From SWITCHED_3V3 this gives ≈1.04mA; after the bridge draws its own 100-245µA, ≥800µA still flows through the LM4040 — comfortably above its ~60µA minimum bias spec. |
| C1, C2 | 10µF / 100nF, ceramic, X7R | Bulk + high-frequency decoupling at the Vexc node. X7R stays stable across -55°C to +125°C — better cold-temperature behavior than tantalum/electrolytic, which degrade below about -25°C. |
| R5, R6 | 4.7kΩ | I²C pull-ups — placed once, at the ESP32 end only. Stay on the ESP32's always-on 3.3V, not the switched branch. |
| Q1 | P-channel MOSFET, e.g. DMG2305UX / AO3401A (SOT-23) | High-side switch gating SWITCHED_3V3. Placeholder recommendation — current draw here is trivial. |
| R7 | ~10kΩ | Q1 gate pull-up to 3.3V — keeps the sensor branch OFF by default during ESP32 boot/reset. |
Worked numbers (B57861S0103F045, B=3988K, -30°C to 45°C)
NTC resistance is highly non-linear over this range: ~4.3kΩ at 45°C → ~206kΩ at -30°C. With R3=10kΩ (bridge nulled at 25°C):
| Temp | R_NTC | V_diff (AIN1−AIN3) |
|---|---|---|
| -30°C | ≈206kΩ | ≈ -0.93V |
| 25°C | 10kΩ | 0V (balanced) |
| 45°C | ≈4.3kΩ | ≈ +0.41V |
PGA ±2.048V gives ~2.2× headroom over the -30°C extreme, avoiding clipping even with thermistor tolerance and self-heating factored in. Resolution at that PGA is 62.5µV/LSB; near 25°C that's roughly ~328 counts/°C — about 18× finer than the existing single-ended design's ~55 m°C/count. Temperature is recovered by inverting the actual bridge equation for R_NTC from V_diff (not a linear approximation), then feeding that into the Beta equation.
Power-gating
Both sensor boards are only powered during the brief read window, not continuously. SWITCHED_3V3 is a branch off the main 3.3V rail, gated by a single high-side P-channel MOSFET (Q1) at the host end — one switch for both sensor cables, since they're already read back-to-back in the same MQTT SendData cycle. The ESP32's own 3.3V supply is upstream of Q1 and stays continuously powered. SWITCHED_3V3 feeds the ADS1115's VDD too, not just the LM4040/bridge chain.
Settling time: R4 (1.2kΩ) + C1 (10µF) at the Vexc node form an RC with τ≈12ms. Firmware needs to wait ≥5τ (~50-100ms) after enabling SWITCHED_3V3 before triggering the first ADS1115 conversion. Trivial against a 60s read interval.
Self-heating: board draw when on is ≈4mW. Continuous-on sustains that 24/7; gated to a ~1-2s window every 60s (~2-3% duty cycle) drops the average to ~100-130µW — a 30-40× reduction. The NTC itself isn't on this board (remote on the steel bar via short flying leads), so board self-heating doesn't couple directly into the sensing element regardless.
Electrical check: with the branch de-energized, VDD/Vexc/all analog bridge nodes sit at 0V together. SDA/SCL/ADDR digital pins on a powered-down ADS1115 are still held at 3.3V by the host-side pull-ups — within spec, since the datasheet's digital I/O absolute max is a fixed GND-0.3V to 5.5V range, not referenced to VDD.
Addressing
| Sensor | ADS1115 ADDR pin | I²C address |
|---|---|---|
| Unit 1 | GND | 0x48 (same as existing moon_temp_ads1115) |
| Unit 2 | VDD | 0x49 |
Both share the ESP32's existing I²C bus (GPIO21=SDA, GPIO20=SCL). SDA/SCL address options (0x4A/0x4B) are still free for future expansion.
Physical / layout notes
- Keep the entire bridge (R1-R3, LM4040, decoupling) on the small sensor PCB, right next to the ADS1115 — minimizes lead-resistance mismatch and EMI pickup on the signal path.
- The NTC is not on this PCB — it's thermal-epoxied directly to the steel bar and connects back via short flying leads (J1 in the schematic). Thermal epoxy is electrically non-conductive, and the PCB is additionally isolated from the bar with kapton tape layers.
- I²C run is <1m for both units — standard 4.7kΩ pull-ups, 400kHz fast-mode is fine. Route SDA/SCL with a ground reference alongside (twisted pair even at this distance).
Relationship to Moon_Temp_Overview
Moon_Temp_Overview documents a separate, related project — the gen-1 deployment (moon-temp-001), a static rig using three single-ended channels (two moonlit reference sensors averaged together, differenced in software against one shaded sensor). moon-temp-tracer is gen-2: different hardware, mechanically tracking the moon via stepper motors — not a continuation or replacement of the gen-1 rig, just related in concept.
Deferred to later passes
- PCB layout/footprint placement.
- Firmware: MUX/PGA config registers, power-gate GPIO sequencing + settling delay, non-linear bridge-inversion + Beta-equation (B=3988K) calculation, MQTT payload shape.
- Connector/cable choice, enclosure/potting for outdoor exposure.