Signal Conditioning & Sensor Excitation

Getting sensor signals into an ADC accurately. Learn the signal chain (excitation, protection, amplification, filtering, level shifting, ADC driving), sensor types and their electrical outputs, Wheatstone bridges (quarter, half, full) and their nonlinearity, voltage and current excitation, ratiometric measurement, RTDs (2/3/4-wire) and self-heating, thermocouples and cold-junction compensation, thermistors and linearisation, 4–20 mA current loops, gain and offset scaling to the ADC range, isolation, and input protection — with Python computing bridge outputs, RTD values and lead errors, 4–20 mA scaling and gain/offset mapping.

Sensors rarely produce ADC-ready signals: a strain gauge changes resistance by 0.2%, a thermocouple gives 41 µV/°C, a photodiode gives nanoamps, and industrial transmitters send 4–20 mA over long cables. Signal conditioning bridges that gap.

Good conditioning maximises signal and minimises noise, error and interference — while protecting the electronics from the outside world.

An analogy

Signal conditioning is like a translator and bodyguard for a quiet foreign visitor (the sensor): it amplifies their soft voice, translates it into the local language (ADC range), filters out crowd noise, and blocks anyone who tries to barge in (surges, ESD).

Sensor outputs

Know what the sensor gives you:

Bridges and excitation

A Wheatstone bridge converts small resistance changes into a differential voltage near zero, which an instrumentation amplifier amplifies while rejecting the V_ex/2 common mode. Full bridges are linear and compensate temperature; quarter bridges are nonlinear and need dummy gauges. Ratiometric designs derive both excitation and ADC reference from the same source so excitation drift cancels. AC excitation with synchronous demodulation removes offsets and thermocouple effects in wiring.

Temperature sensors

RTDs: accurate and stable, need current excitation (0.1–1 mA to limit self-heating) and 3/4-wire connections. Thermocouples: wide range, self-powered, tiny signals, need cold-junction compensation and open-thermocouple detection, and are sensitive to interference. Thermistors: high sensitivity, nonlinear (Steinhart–Hart), limited range. Semiconductor sensors: simple, ±0.5–2 °C, limited range.

Industrial practice

Input protection (series resistors, TVS, clamps to rails with current limits), RFI filters on in-amp inputs (matched differential/common-mode RCs so mismatch doesn't convert CM to DM), galvanic isolation (digital isolators, isolated ADCs/amplifiers) for ground loops and safety, 4–20 mA and HART for long cables, and diagnostics (open/short detection, burn-out currents). Calibrate the whole chain end-to-end, not block by block.

Formulas

Worked example: Half bridge

Given: V_ex 5 V, GF 2, 500 µε

Find: V_out.

Answer: 2.5 mV

Worked example: Thermocouple

Given: Type K ≈ 41 µV/°C, hot 520 °C, cold junction 20 °C

Find: Voltage.

Answer: ≈ 20.5 mV

Worked example: 4–20 mA reading

Given: 8 mA, span 0–10 bar

Find: Pressure.

Answer: 2.5 bar

A complete sensor signal chain

  Sensor ─► Excitation ─► Protection ─► In-amp / gain ─► Anti-alias ─► ADC driver ─► ADC
   (bridge,   (V_ref or     (R, TVS,      (G, CMRR,        filter        (buffer,       (V_ref shared
    RTD, TC)   I source)     clamps, RFI)  offset/level)   (RC/active)    charge kick)   → ratiometric)

Each block has a job: excite the sensor stably (ideally from the same reference the ADC uses), survive faults and RF, amplify with high CMRR, remove aliasing frequencies and drive the ADC's sampling capacitor. Errors from every block add to the final measurement.

Bridges, RTDs, 4–20 mA and ADC scaling

# Signal conditioning: strain-gauge bridge, RTD excitation, 4-20 mA scaling, gain/offset to ADC range
Vex, GF, strain = 5.0, 2.0, 1000e-6            # full-bridge, 1000 microstrain
Vout_full = Vex * GF * strain                   # full bridge (4 active arms)
Vout_quarter = Vex * GF * strain / 4
print(f"bridge output at 1000 ue: quarter {Vout_quarter*1e3:.2f} mV, full {Vout_full*1e3:.1f} mV")
print(f"gain to reach 2.0 V from a quarter bridge: {2.0/Vout_quarter:.0f}")
# PT100 RTD with 1 mA excitation: R = 100(1 + 0.00385 T)
for T in (0, 100, 200):
    R = 100 * (1 + 0.00385 * T)
    print(f"PT100 at {T:3d} C: {R:.1f} ohm, {R*1e-3*1e3:.1f} mV at 1 mA, self-heating {1e-3**2*R*1e3:.2f} mW")
print(f"2-wire lead error with 2 x 0.5 ohm leads: {1.0/0.385:.1f} C -> use 3- or 4-wire")
# 4-20 mA loop into 250 ohm -> 1-5 V; map 0-10 bar
for I in (4e-3, 12e-3, 20e-3):
    print(f"{I*1e3:4.0f} mA -> {I*250:.2f} V -> {(I-4e-3)/16e-3*10:.1f} bar")
# Map a -1..+1 V sensor to 0..3.3 V ADC: Vadc = G*Vin + Voff
G = 3.3 / 2
print(f"gain {G:.2f}, offset {1.65:.2f} V (level shift to mid-rail)")
# bridge output at 1000 ue: quarter 2.50 mV, full 10.0 mV
# gain to reach 2.0 V from a quarter bridge: 800
# PT100 at   0 C: 100.0 ohm, 100.0 mV at 1 mA, self-heating 0.10 mW
# PT100 at 100 C: 138.5 ohm, 138.5 mV at 1 mA, self-heating 0.14 mW
# PT100 at 200 C: 177.0 ohm, 177.0 mV at 1 mA, self-heating 0.18 mW
# 2-wire lead error with 2 x 0.5 ohm leads: 2.6 C -> use 3- or 4-wire
#    4 mA -> 1.00 V -> 0.0 bar
#   12 mA -> 3.00 V -> 5.0 bar
#   20 mA -> 5.00 V -> 10.0 bar
# gain 1.65, offset 1.65 V (level shift to mid-rail)

At 1000 µε a quarter bridge yields only 2.5 mV from 5 V — a gain of 800 is needed to reach 2 V; a full bridge gives 4× more and cancels temperature effects. A PT100 changes 0.385 Ω/°C, so 1 Ω of lead resistance in a 2-wire connection means a 2.6 °C error — hence 3- and 4-wire connections. 4–20 mA loops map cleanly to 1–5 V with a 250 Ω resistor and detect broken wires (0 mA).

Common mistakes

Applications

Key takeaways

Going further