Skunk Werks · Circuit Design · Rev F

Millstone-Differential Bridge

"A Balanced Bridge Dimensionless Signal Detector" (BBDSD)

Centralized dual-thermistor differential bridge for moon-temp-tracer's moonlit-vs-shaded sensor comparison. One ADS1115, one LM4040, digitally zeroed, split power domains for precise read-timing control.

What changed, and why

The original design [1] used two independent half-bridges — each sensor measured against its own local fixed-resistor reference, each with its own ADS1115 and LM4040. "Is there a difference between the two sensors" was answered by subtracting two independently-calibrated absolute readings in software.

The actual question this circuit needs to answer is narrower than two absolute temperatures: is there a difference, and which direction. Putting both thermistors as the two active arms of one bridge answers that directly, in hardware, instead of indirectly via software subtraction of two separately-erred measurements.

Why this topology

Zeroing: digital offset, not a hardware trim

An earlier revision of this design included a physical trim potentiometer to null the bridge at build time. That hardware has been removed — zeroing is done entirely digitally instead, using the same mechanism moon_temp_ads1115 already has proven in the field: an MQTT-settable per-channel offset, persisted to flash, added to the raw reading before publishing. No reflash needed to adjust it.

Calibration procedure: with both thermistors sitting together at the same known temperature, the digital offset is set so the bridge reading is zero. After that, the calibrated signal should read as pure noise around zero — that's the validation criterion. A real signal during an actual moonlight event is then judged against that established noise floor, not against zero directly.

Some drift over the sensor's lifetime is expected (thermistor aging, and the two units' Beta-value tolerance diverging slightly away from the calibration temperature). Periodic re-zeroing via the same MQTT command — no reflash required — is the mitigation. A single offset corrects a constant mismatch; the residual curve-mismatch still needs empirical multi-point calibration, same static-chamber approach as the gen-1 project's calibration notebook.

Split power domains

Two separate rails, on purpose:

With the ADC continuously powered, there's no ADC power-on/reference-startup uncertainty mixed into the read timing. The only settling time left to account for is the bridge's own RC time constant — a single, precisely-known, purely-bridge-limited quantity. Firmware can control exactly how long the bridge has been energized before triggering a conversion, without that number being confounded by ADC startup time — directly serving the accuracy goal for this measurement.

Worked numbers

MF58-family NTC (B57861S0103F045, B=3988K), -30°C to 45°C range. Bridge sensitivity peaks at balance (~25°C, where both arms are equal) and tapers toward both extremes:

Ambient baselineSensitivity (dV/dΔT)
-30°C~6.1 mV/°C (worst case)
25°C~23.0 mV/°C (peak, balanced)
45°C~17.0 mV/°C

Even at the worst-case cold end, the chosen ADC gain setting (±0.512V) covers a differential well beyond any plausible real effect without clipping, giving roughly ~780-2900 counts/°C depending on ambient baseline.

Full schematic & source

The complete KiCad schematic, BOM rationale, and design notes are in the project repository — more detail than fits cleanly in a web summary, and kept in sync with the actual buildable files.

github.com/rooster-ninja/moon-temp-tracer →

Appendix

[1] Original design (Rev D) — two independent half-bridges, two ADS1115 + two LM4040. Superseded by the centralized single-bridge design above, but kept live as a record of the earlier approach. rooster.ninja/skunk_werks/moon_temp_tracer/thermal_sensor_circuit/ →