Go Down

Topic: Writing an analog pot debounce as a function (Read 1 time) previous topic - next topic

missing_n

Hello,

So  a while back I had some issues with some flickering pots. I found this thread which basically solved my issue:  http://forum.arduino.cc/index.php/topic,43982.0.html

Awesome.

Except. For one pot, its ok. But 3 or more = does it ever get hairy. So I'm trying to re-write this as a re-usable function. I've only gotten part way there. Any help on how I can get the rest of the way there?

Things I've tried: Moving the debounce code into the function, declaring those "global" variables in the function instead. I've gotten to the point where it will return 'potFinal' for different pins, but calling it in the loop = it just returns that over and over again ignoring the if statements. So I backtracked to this point:

Code: [Select]
const int conPin = A2;

int lastpotVal = 0; // last volume pot value
int prevpotVal = 0;  // previous volume pot value
int potFinal = 0;
int potThresh = 2;

void setup(){
  Serial.begin(9600);
}


void loop(){
  int j;

  j = readPot(conPin);
 
  if(j != lastpotVal) {
     
    if(abs(j - prevpotVal) >= potThresh){
       
      prevpotVal = j;
       
      potFinal = (j/2);       
      Serial.println(potFinal);   
   
      lastpotVal = j;

    }
  }
delay(10);

}


int readPot(int potPin) {
 
  int potVal = (analogRead(potPin));         
  int mappedPotVal = map(potVal, 0, 664, 0, 200);  //map value to 0-100 ... volptval is now mapped potval
   
  return mappedPotVal;

}


Suggestions on how to clean this spaghetti up?  ^_^

I'm also reading over this for reference: http://forum.arduino.cc/index.php?topic=54737.0

Thank you.

PaulS

Quote
Suggestions on how to clean this spaghetti up?

Sure. You have a function that reads a potentiometer value. If you want to debounce the output of that function, the debouncing belongs in that function.

Although, debouncing is the wrong term. Potentiometers do not bounce like mechanical switches. So, you really should be clear on what you are trying to accomplish.

Let me ask this. If you have multiple pots, how can you "debounce" them all using one "last value" variable?
The art of getting good answers lies in asking good questions.

missing_n

Hmm. Ok, let me see if I can word this better. Sorry about that.

First your question: Likely can't. I've tried declaring it locally, tried making it a parameter, but I can't quite figure out what I'm doing wrong.

Second: Behaviour
Right now if you leave that nested if statement in the loop the pot functions the way I need it too. It sends the proper value only when you are turning it. When its resting nothing gets sent. Its just silent.

If I move that "debounce" (or threshold) into the function, then call the function in the loop, it'll return whatever values I tell it too, but I will loose the desired behaviour of the pot being silent when its not being turned.

So I guess my questions are:

1) Is there a way to move that if statement into that function, while still maintaing the "silent while not being turned" behaviour?
2) How can I write this to be re-useable for multiple pots?

I hope that's better? I find forums sometimes difficult to outline stuff in. But I appreciate the extra set of eyes and feedback.



PaulS

Let me take a turn asking questions.

To determine if this potentiometer reading is the same as the last one, how many variables are needed? How many do you have?

If the readings are the same, is the mapping necessary? The other manipulations?

In other words, the function should return the mapped, manipulated value only if the current reading is not the same as the previous reading, and the only values that need to be persisted are the previous reading and the previously returned value.

Return the same value if the readings are the same. Calculate and return a new value if the readings are different.

Use names that appear to be related, like currentReading and previousReading, not j and lastPotVal (or is that prevPotVal?).
The art of getting good answers lies in asking good questions.

missing_n

#4
Jan 14, 2014, 04:03 am Last Edit: Jan 14, 2014, 08:36 pm by missing_n Reason: 1
Ok, here's the simplest I can make this function and this setup to behave the way I want it too with one analog pot pin.

Can I please get some help on how to make this function work with multiple analog pot pins?


Thanks!

Code: [Select]


byte pots[2] = {A0, A2};
int lastPotVal = 0;


void setup(){
  Serial.begin(9600);
 
}


void loop(){
 
  // get the pin out of the array
  rePot(pots[0]); 
  delay(10);
 
}

int rePot(const int potPin){
 
 
 
  // there is probably an issue around here somewhere...

 
  int potThresh = 2;
  int potFinal = 0;
  int potVal = 0;
 
  // set and map potVal
 
  potVal = (analogRead(potPin));         
  potVal = map(potVal, 0, 664, 0, 200); 
       
    if(abs(potVal - lastPotVal) >= potThresh){
         
      potFinal = (potVal/2);       
      Serial.println(potFinal);
      lastPotVal = potVal;
     
      return lastPotVal;
         
     }   // end of if statement
 
} // end of rePot

PaulS

Quote
Can I please get some help on how to make this function work with multiple analog pot pins?

Here's a clue:
Code: [Select]
byte pots[] = {A0, A2};

You have an array of pin numbers. Well, guess what? You need arrays for the previous readings, the current readings, the previous returned values, etc.

Code: [Select]
  for (int thisPot = 0; thisPot < size; thisPot++){
In my opinion, for loop indices should be single letter names.

Code: [Select]
  potVal = (analogRead(potPin));         
(What's) (with) (the) (extra) (parentheses) (?)

Code: [Select]
  static int lastPotVal = 0;
  static int lastpotVal = 0;

NO! NO! NO! NEVER!

Variable names that differ only by case are NEVER to be used.
The art of getting good answers lies in asking good questions.

missing_n

#6
Jan 14, 2014, 03:15 pm Last Edit: Jan 15, 2014, 03:11 pm by missing_n Reason: 1
Went over to StackOverflow and found a good explanation on how to do things better.

Sharing here for people who run by this thread.

Code: [Select]

  struct Pot {
  byte pin;
  int threshold;
  int lastReading;
  int currentReading;
 };
   
 struct Pot pots[] = { {A0, 2},{A2,2},{A4,2} };

 void rePot(struct Pot * pot) {
   int reading = map(analogRead(pot->pin), 0, 665, 0, 200);
   
   if(abs(reading - pot->lastReading) >= pot->threshold){
     pot->currentReading = (reading/2);
     Serial.println(pot->currentReading);
     pot->lastReading = reading;
   }  // end of if statement
 
 } // end of rePot

void setup(){
    Serial.begin(9600);
  }
 
  void loop(){
    rePot(&pots[0]);
    rePot(&pots[1]);
    rePot(&pots[2]);
    delay(10);
  }


Go Up