I was planning to use potentiometers to change between animation modes and noticed your comment about a pot value sitting exactly between 2 steps and, I assume, even low noise would then make it toggle erratically. So I started to look into a simple solution and wonder how it compares with your own debouncing solution.
Basically, the mode will not get updated until the value of the potentiometer has changed by at least 25% of the range of a mode from its previous value. I have tried it with 32 modes and it is rock steady !!
Does that help you at all or am I missing something ??
Thanks, @JP_Roy . That is indeed an interesting solution. The price is, that there is no immediate reaction anymore to changes. It produces a “latency” - the time one needs to change the pot by 25 percent of the previous value.
So with all respect it is another nice workarround, but it seems not as perfect as an old car stereo with one big knob triggering an immediate reaction. But definetely a good base for further experiments and finetuning in order to come closer to the "good old analog interface feeling"™. So far my words are just theory - I´ll give it definetly a try and check, how it really FEELS (sic). Thanks for the inspiration!
@Stefan_Petrick Now I understand what you meant by latency. I assumed that you were only concerned with “Sitting exactly on the transition” case only.
However, even with the old stereo volume control you always have to turn the thing a bit before you actually noticed a change in sound levels.
If you divide the range of a potentiometer into let’s say 5 modes, you have no choice but turn the thing around 1/6th of it’s full range (For a one turn pot, full range is about 300°, actually less than 360°) So 60° of turn for each mode. I don’t think you can avoid this.
Maybe I’m still missing details about the problem you experienced or don’t understand the perfect behaviour you are hoping to develop !
Your post reminds me of a (digital) sythesizer I once had, a Quasimidi Polymorph. http://www.sequencer.de/pix/spectralis/polymorph.jpg
There you had the parameters organized in pages and banks because they where way more than the physical potis. Then you could assign the pots (potis?) to a relative or an absolute behavior: after switching a bank the actual value of an paramter did not correspond with the physical setting of the potis. So in absolute mode the value jumped to the new value when touching the knob. In relative mode the rest of the space you had to turn turned into the new available range. That felt really good and worked perfect and without any toggling (at least until the day where i spilled a drink over it…). It felt kind of analog - immediate reactions, sensitive, very stable values without touch. I wonder how they did it. High end alps potentiometers maybe?
The vision is to come close or at least closer to that feeling: sudden response, short ways (minimal rotation) to trigger a change, nothing unwanted happening when not touched…
I had a Line6 guitar amp that had similar behaviour in it’s potentiometer control.
If you very quickly read and display the value from analogRead you will likely notice a variation in the value due to noise. I am actually measuring +/-2 between samples. Note that your results may be better or worse !!
You can always fine tune the amount of variation you will accept as a change
such that you would never interpret noise as an actual change in potentiometer position.
With my current findings, I modified my sketch to only accept a variation of at least 8 (and not a percentage of the steps as I proposed earlier).
I am still getting a very stable mode selection and I could (in theory) increase to 128 stable steps from a single potentiometer.
Yes! You can totally do that. I think you’d have to make three changes.
First, write a function called “isAtMinimumBightness” that checks one color to see if it’s already at or below the minimum brightness that you choose. This function should return true if that color is at (or below) the minimum, and false if the color is brighter. Maybe like this… [NOTE: TOTALLY UNTESTED!]
Second, modify the “makeDarker” function to first check to see if the color ‘isAtMinimumBightness’, and if so – don’t darken it any further, just return, i.e.,
CRGB makeDarker( const CRGB& color, fract8 howMuchDarker)
{
if( isAtMinimumBightness( color) ) return color;
…rest of function as is…
}
Finally, find the place where the code randomly selects a new pixel to start brightening up again. Right now that code checks to see if the random LED that it has chosen is completely black – before switching it into brightening mode. If the chosen LED is not totally black, it skips it. You want to change that test to instead check to see if the color ‘isAtMinimumBightness’ (instead of just black). So right now line 95 says this:
if( !leds[pos]) {
and you’d probably want to change it to say
if( isAtMinimumBightness( leds[pos] )) {
I don’t have a test rig in front of me, but I suspect that would do it. Please let us all know what you try, and how it goes!
Oops… my bad. You can just delete the ‘const’ from the definition of isAtMinimumBightness, and I’ll open a ticket to take care of the problem on my end.
I think what I’d try first is this: periodically (every 10 seconds), loop over every pixel in the array. If the pixel is black (or isAtMinimumBightness) set it to a new random starting color. Then, regardless of whether it was already lit or not, call
setPixelDirection(pixelNumber, GETTING_BRIGHTER);
This will make them (1) all lit, and (2) all get brighter until they max out and start dimming again. They’ll be a little out of sync, because they each were at different brightnesses to start with, but it’s simple, and a starting point to play with.
You can use the EVERY_N_SECONDS macro in your loop function to take care of the timing for you:
EVERY_N_SECONDS( 10 ) {
… do your thing in here …
}
Let us know how it looks, and what other changes you make!