Created
October 31, 2017 06:55
-
-
Save CodeZombie/2b7f986fd5aab8c7a25ebdaf33a53118 to your computer and use it in GitHub Desktop.
very responsive, low memory, near-perfect potentiometer debounce
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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