Smoothing the Noise in Fermentation Data
Your pH sensor is having a nervous breakdown. Every few seconds it reports 4.2, then 4.7, then 3.9, then 4.4. The poor thing is drowning in electrical noise, but somewhere in that chaos lies the true acidity of your sourdough starter. What you need is exponential smoothing—a deceptively simple algorithm that acts like a patient sommelier, tasting each new reading but never forgetting the wisdom of what came before.
Unlike simple averaging, exponential smoothing gives recent readings more weight while gracefully diminishing the influence of older data. Each new measurement updates your running estimate using a smoothing factor α (alpha), typically between 0.1 and 0.3 for sensor applications.
10 ALPHA = 0.2
20 SMOOTH = 4.0 ' Initial estimate
30 INPUT "Raw pH: "; RAW
40 SMOOTH = ALPHA * RAW + (1 - ALPHA) * SMOOTH
50 PRINT "Smoothed: "; SMOOTH
60 GOTO 30
In BASIC’s straightforward style, each line of input immediately updates the smoothed value. The magic happens in line 40: 20% of the new reading blends with 80% of the accumulated history.
Haskell approaches this more elegantly through infinite streams:
smooth :: Double -> [Double] -> [Double]
smooth alpha readings = scanl1 blend readings
where blend acc new = alpha * new + (1 - alpha) * acc
-- Usage: smooth 0.2 [4.2, 4.7, 3.9, 4.4, 4.1]
The scanl1 function produces a stream of progressively smoothed values, perfect for real-time monitoring. Feed it raw sensor data, get back a gentler truth that reveals genuine trends while filtering out the electronic hiccups that plague every fermentation setup.
What makes exponential smoothing brilliant isn’t just its simplicity—it’s the mathematical guarantee that recent data matters most, exactly what you want when monitoring a living, changing fermentation.