I want to map a noise sensor's output, minimum and maximum values 30 and 130, to a string of 24 LEDs. The sensor will be used along a road with tram tracks, cobblestones and tarmac; and depending on location, the output values fluctuate 60 - 75, or 35 - 80, or 50 - 115, and so forth. Sometimes, the amplitude change can be small, sometimes large. At the moment, I hard code lower and upper boundary values (59 and 76) for map() so that ideally all 24 LEDs are used (orange in the screenshot), but that is not a good solution. How would I go about automating: output low - output high > 0 - 23?
Just saw that Rob Tillaart's library has getLowest() and getHighest() methods. Used in map() as lower and upper boundary, with a large running median window, scales the output into the 0 - 23 range quite well (screenshot).
But maybe I should rather choose a longer time interval instead, say 10 seconds, and use the minimum and maximum found in that interval as lower and upper boundaries? So I start with 30 and 130 once powered, and then the upper and lower boundary are updated every 10 seconds (the LEDs thus become a somewhat lagging indicator)? Would that be better?
What's the "professional" word for this? Dynamic ranging? Auto-scaling? Range-fitting?
Not increasing the high and decreasing the low, but dynamically shifting both up or down, as the noise level changes, so that the whole "bandwidth" of 0 - 23 is always used:
See the 1st screenshot, where the upper and lower boundaries are roughly hard-coded for one particular situation: The orange graph is scaled into a range of 7 - 18, not 0 - 23, but follows the original signal well. If the noise level changes, I would have to hard-code the upper and lower boundaries again. And so forth.
The getLowest() and getHighest() methods, based on the size of the running median window, do scale, but the relation to the original signal is more or less lost (window size 27 samples). Hence the good old min/max calibration you suggest, not in setup(), but in loop(), may be better.
Seems to work rather nicely. Sort of like an "on the fly calibration", or whatever this sort of thing is called. Updating the lower and upper boundaries every four seconds, and now the mapping uses the full 0 - 23 range. Let's see how this plays out with LEDs and some LED code.
See above, seems to work. Every n seconds, the lower and upper boundary is reset, as the noise volume fluctuates over time. But I have to test it for, say, an hour, and with LEDs and LED code. And then see what the boundary update interval, now arbitrarily set to four seconds, should be.