Skip to content

Instantly share code, notes, and snippets.

@CodeZombie
Created October 31, 2017 06:55
Show Gist options
  • Save CodeZombie/2b7f986fd5aab8c7a25ebdaf33a53118 to your computer and use it in GitHub Desktop.
Save CodeZombie/2b7f986fd5aab8c7a25ebdaf33a53118 to your computer and use it in GitHub Desktop.
very responsive, low memory, near-perfect potentiometer debounce
class Pot {
uint8_t rawValue = 0; //the raw value of the potentiometer
uint8_t smoothValue = 0; //the smoothed public-facing value of the pot
uint8_t stableSteps = 0; //value that tracks how many update() calls have passed since the last time the pot value change
void (*changeMethod)(uint16_t); //the function that gets called when the smoothed value changes
public:
Pot(void (*changeMethod_)(uint16_t)) {
changeMethod = changeMethod_;
}
void update(uint8_t analogInPin_) {
/* How this method works:
* Keep track of how many steps have passed since the raw potentiometer value changed at all
* Use the number of steps as a weight factor for averaging together the raw value with the previously stored "smoothed" value of the pot.
* this will act as a software low-pass filter, cutting out any jittery noise in the numbers, as noisey bouncing will never accumulate a step-weight high enough to effect the smoothed value.
* A down-side to this is that if the user sweeps the pot above a certain speed, the stable step-count will remian at zero, causing the smoothed value to not update for a noticable amount of time.
* To compensate, we add a few lines that force the smooth value to move if the difference between it and the raw value is greater than 10. Noise is unlikely to ever reach this high,
* so the result is a constant smoothed moving average that feels very natural.
*/
uint8_t oldSmoothValue = smoothValue; //store a reference to the last smooth value
uint8_t oldRawValue = rawValue; //store a reference to the last raw value
rawValue = floor(analogRead(analogInPin_) /6.75); //read the raw analog value, divided by a value that will normalize it between 0 and 127.
if(rawValue != oldRawValue) { //if the raw value of the pot has changed...
stableSteps = 0; //reset the stable step counter to zero
}
smoothValue = floor((smoothValue + (rawValue*stableSteps)) / (stableSteps+1)); //the smoothed value is an average between the last stored smoothed value and the raw potentiometer value weighted by how long its been stable
if(abs(rawValue - smoothValue) > 10) { //if the smooth value is ten steps away from the raw value, we can assume that this is the user quickly moving the pot, not a bounce.
smoothValue = (smoothValue + rawValue)/2; //set SmoothValue to a simple average between the two values
}
if(oldSmoothValue != smoothValue) { //if the last recorded smoothValue is not the same as the one we just calculated above...
changeMethod(smoothValue); //call the change method
}
stableSteps++;//increase the number of stable steps
if(stableSteps > 255) {//rollover at 255
stableSteps = 0;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment