Part VII: Health, Biosignals, and Wearable AI
Chapter 28: Biosignal Foundations

Electrode and optical measurement issues

"I was trained to trust the waveform. Nobody told me the waveform starts as a chemical argument between a metal disc and someone's skin."

A Recently Grounded AI Agent

Why this section matters

The previous section treated the biosignal as roughly given and asked how motion and physiology corrupt it. This section goes one layer deeper, to the transducer itself. Before a single ECG sample reaches your model, it has crossed an electrochemical junction between a metal electrode and living tissue; before a heart-rate estimate exists, photons have been scattered and absorbed by skin, blood, and bone. Those interfaces are not passive wires. They add offsets, drift, mismatched impedances, and systematic biases that no downstream filter fully repairs and that, in the optical case, can differ by the color of the wearer's skin. If you do not understand the interface, you will attribute its failures to your algorithm and tune forever against a hardware problem.

This section assumes the measurement-model view from Chapter 2, where a reading is written \(x = h(s) + \eta\) and the sensor response \(h\) is imperfect and unknown, and the sampling and synchronization vocabulary of Chapter 3. Where Section 28.2 covered noise that rides on the signal, here we study defects baked into \(h\) at the electrode and the optical path. We keep motion in view but treat it as a coupling mechanism into the interface, not as the topic itself.

The electrode-skin interface is an electrochemical cell

A biopotential electrode does not simply touch skin; it forms a half-cell. Where a metal (typically silver coated with silver chloride, written Ag/AgCl) meets an electrolyte (sweat, gel, or interstitial fluid), ions exchange until an equilibrium potential builds across the junction. That standing voltage is the half-cell potential, and for a pair of nominally identical electrodes it does not cancel: manufacturing variation, uneven chloriding, and local sweat chemistry leave a differential DC offset that can reach several hundred millivolts. Set that against an ECG whose informative deflection is on the order of one millivolt and you see the problem immediately. The offset is two to three orders of magnitude larger than the signal you want. It is why every biopotential front end is AC-coupled or actively servo-corrected, and why a slow drift in that offset (as gel dries or sweat pools) shows up as baseline wander that a naive high-pass can distort.

The interface also has an impedance, modeled as a resistor in parallel with a capacitor in series with the bulk skin resistance. This matters because your amplifier reads the electrode voltage through a divider formed by the electrode impedance \(Z_e\) and the amplifier input impedance \(Z_{in}\). The fraction of signal that survives is \( Z_{in}/(Z_{in}+Z_e) \), so a dry electrode at \(Z_e = 500\,\mathrm{k\Omega}\) feeding a \(10\,\mathrm{M\Omega}\) input already loses about five percent of amplitude before anything else happens. Worse, \(Z_e\) is not constant: it depends on contact pressure, skin hydration, and the stratum corneum (the dead outermost skin layer), which is why aggressive skin prep (abrasion, alcohol) is standard clinical practice and why a wearable dry electrode behaves nothing like a gelled clinical one.

The signal you want is the small difference of two large uncertainties

A biopotential channel measures the difference between two electrodes, each carrying a large, drifting half-cell potential and a variable contact impedance. The cardiac or muscular signal is a tiny perturbation on top. Every design choice in the analog front end (differential amplification, AC coupling, high input impedance, active reference) exists to reject the large shared nuisance and preserve the small difference. When your model sees a clean trace, thank the interface engineering; when it sees a wandering, saturating mess, the interface is usually where it broke.

Reference, ground, and why mismatch destroys common-mode rejection

Real recordings are not two-wire. A third electrode sets a body reference so the differential amplifier has a common-mode operating point, and in ECG this is often actively driven (the driven-right-leg circuit) to push the body's common-mode voltage, dominated by \(50/60\,\mathrm{Hz}\) mains pickup, toward the amplifier's midpoint. The amplifier's job is expressed by its common-mode rejection ratio (CMRR): how strongly it suppresses a voltage common to both inputs relative to a difference between them. Datasheets quote CMRR figures above \(100\,\mathrm{dB}\), yet real recordings show mains interference far worse than that number predicts. The reason is not the amplifier; it is electrode mismatch.

When the two electrode impedances differ by \(\Delta Z\), the shared common-mode voltage \(V_{cm}\) passes through slightly different dividers on each input and converts into a differential voltage the amplifier cannot distinguish from signal. The effective rejection is capped at roughly \( Z_{in}/\Delta Z \) regardless of how good the chip is. A \(100\,\mathrm{k\Omega}\) impedance imbalance against a \(1\,\mathrm{G\Omega}\) input limits you to about \(80\,\mathrm{dB}\), erasing the amplifier's headroom. The code below makes this concrete, and it is the reason "balance your electrode impedances" is a clinical instruction, not a nicety.

import numpy as np

Zin   = 1e9        # amplifier input impedance, ohms
Z1    = 500e3      # electrode A impedance (well-prepped)
Z2    = 600e3      # electrode B impedance (mismatched by 100k)
V_cm  = 1.0        # 1 V of 50 Hz common-mode pickup on the body

# each input sees its own divider; the difference leaks through as signal
leak = V_cm * abs(Z1/(Z1 + Zin) - Z2/(Z2 + Zin))
cmrr_from_mismatch_dB = 20 * np.log10(V_cm / leak)

print(f"differential leakage:      {leak*1e6:8.2f} uV")
print(f"effective CMRR (mismatch): {cmrr_from_mismatch_dB:8.1f} dB")
# differential leakage:        100.00 uV
# effective CMRR (mismatch):     80.0 dB
Electrode impedance mismatch, not the amplifier chip, sets the practical common-mode rejection: a \(100\,\mathrm{k\Omega}\) imbalance turns \(1\,\mathrm{V}\) of mains pickup into \(100\,\mu\mathrm{V}\) of differential error (roughly a tenth of an ECG's amplitude) and caps CMRR near \(80\,\mathrm{dB}\).

That \(100\,\mu\mathrm{V}\) of leaked interference sits directly in the band of the ECG, so no downstream notch or band filter (Chapter 6) removes it without also carving into real cardiac content. The lesson generalizes: interface defects that fall inside the signal band are not a filtering problem, they are an acquisition problem, and they must be logged as a channel-quality feature rather than silently averaged over.

The dry-electrode ring that flatlined overnight

A sleep-research team shipped a wearable ring logging single-lead ECG with dry stainless electrodes, validated beautifully in a two-hour lab session. In multi-night home use, roughly a fifth of recordings degraded into flat, saturating segments after several hours. The cause was not motion and not the algorithm. Without wet gel, the electrode impedance climbed as the skin under the contact dried and cooled during sleep, the half-cell offset drifted past the AC-coupling corner, and the front end railed. The fix lived entirely in the measurement layer: a small conductive hydrogel pad to stabilize \(Z_e\), a real-time impedance monitor to flag channels crossing a threshold, and a training set re-labeled so the model learned to emit "signal unusable" instead of hallucinating beats from amplifier noise. None of it was a change to the classifier.

Optical measurement: the photon path is its own transducer

Photoplethysmography (PPG), the basis of most wrist heart-rate and blood-oxygen sensing, replaces the electrochemical junction with an optical one, and inherits an entirely different family of interface issues. An LED shines into tissue and a photodiode measures the light that returns after absorption and scattering by skin, bone, and pulsating arterial blood. The pulsatile (AC) component riding on a large static (DC) component is your signal, and it is typically well under one percent of the returned light. Every optical interface defect competes with that tiny fraction. Contact pressure changes the perfusion of the tissue under the sensor and can squeeze the pulsatile signal to nothing; an air gap lets ambient light and specular reflection swamp the photodiode; and wavelength choice determines how deep the light penetrates and which chromophores it probes (green light for robust heart rate because it is strongly absorbed and less motion-sensitive, red and infrared for the oxygen-saturation ratio because their differential absorption by oxygenated versus deoxygenated hemoglobin is what makes \(\mathrm{SpO_2}\) possible).

Ambient light ingress deserves special attention because it is the optical analogue of the electrode's common-mode problem. Sunlight and flickering indoor lighting couple straight into the photodiode; sensors reject this with light-tight mechanical seals, synchronous detection (modulating the LED and demodulating only that frequency), and ambient-subtraction samples taken with the LED off. When those defenses fail, you get a periodic interference at the mains or LED-flicker frequency that a heart-rate tracker can lock onto and report as a plausible but entirely fictitious pulse. We return to PPG-specific modeling in depth in Chapter 30; here the point is that the optical path, like the electrode, is part of \(h\) and shapes what your model can ever recover.

Signal-quality indexing without hand-rolling it

Deciding whether a PPG or ECG segment is trustworthy is a classic reinvented wheel: template correlation, spectral concentration, perfusion-index thresholds, and flatline or saturation detection each take a dozen lines and a pile of magic constants. The neurokit2 library packages validated signal-quality indices behind one call:

import neurokit2 as nk

# clean, then score PPG signal quality per sample (0 = unusable, 1 = excellent)
ppg = nk.ppg_clean(raw_ppg, sampling_rate=64)
quality = nk.ppg_quality(ppg, sampling_rate=64)   # template + spectral SQI
One ppg_quality call replaces roughly 40 to 60 lines of bespoke template-matching and spectral-purity scoring, and it handles the windowing, reference-template construction, and normalization internally.

The library computes the quality indices; your job shrinks to choosing an actionable threshold and deciding what a low-quality flag does downstream (suppress the estimate, widen its uncertainty, or drop the window). That decision, not the arithmetic, is where domain judgment belongs.

Skin tone, melanin, and systematic optical bias

The optical interface carries a consequence electrodes do not: its behavior depends on the wearer's skin. Melanin in the epidermis absorbs strongly in the green and red bands that PPG relies on, so darker skin returns less pulsatile light for the same LED drive, lowering the effective signal-to-noise ratio and, in pulse oximetry, biasing the red-to-infrared ratio that maps to \(\mathrm{SpO_2}\). This is not a rare edge case. Multiple clinical studies have documented that pulse oximeters overestimate blood oxygen more often in patients with darker skin, meaning true hypoxemia can be missed precisely in the population a device is meant to protect. A model trained and validated on a light-skinned cohort will inherit and can amplify that hardware bias, and standard aggregate accuracy metrics will hide it because the affected group is a minority of the test set.

A biased transducer is a fairness problem you cannot filter away

Skin-tone bias in PPG lives in the physics of light and melanin, upstream of every algorithm. You cannot post-process it out of a signal that was never captured with adequate quality. The obligations it creates are concrete: stratify every evaluation by skin tone (report per-group error, not just the pooled number), calibrate and validate across the full range of the intended population, and propagate an honest per-sample uncertainty so a low-perfusion, high-melanin reading is flagged as uncertain rather than delivered with false confidence. These duties connect directly to the validation and equity requirements in Chapter 34, and to the calibration machinery introduced in Chapter 18.

Exercise: attribute the failure to the right layer

You are handed three failing wearable channels and their raw traces. (1) An ECG that drifts slowly then saturates flat after 40 minutes of wear. (2) A wrist PPG that reports a rock-steady 60 bpm heart rate that never varies, even during a brisk walk. (3) A pulse-oximeter reading that is consistently 3 to 4 points too high for one subgroup of users but accurate for another. For each, name the most likely interface mechanism (electrode or optical), state one measurement-layer diagnostic that would confirm it, and give the minimal hardware-or-acquisition fix. Which of these can a downstream filter or model plausibly repair, and which cannot?

Self-check

  1. An ECG amplifier chip advertises \(110\,\mathrm{dB}\) CMRR, yet your recording is buried in \(50\,\mathrm{Hz}\) hum. Explain, using the electrode-impedance-mismatch argument, why the chip's specification is not the limiting factor, and name the practical fix.
  2. Why is a several-hundred-millivolt electrode half-cell potential a design problem when the ECG itself is about one millivolt, and what two front-end techniques keep it from saturating the amplifier?
  3. A PPG heart-rate tracker performs worse on darker skin. Is this fixable purely in software? Justify your answer in terms of where the bias enters the measurement model \(x = h(s) + \eta\), and state what an honest evaluation must report.

What's Next

In Section 28.4, we move from the quality of the signal to what we do with it, framing biosignal analysis as event detection: finding heartbeats, breaths, and seizures as discrete occurrences in a noisy stream. The channel-quality flags and interface diagnostics built here become gating inputs to that detector, so an event is never declared on a segment the electrode or optical path could not actually measure.