I am trying to come up with a debounce for an analog switch. So far, the program I have written seems to agree with my logic about 66% of the time. I want to think that the other 33% the time it is taking false readings from a loose breadboard and bad connections. Also, on occasion, it will continue to spit out zeros until I input a solid reading. In any case, I would appreciate some advise to improve this.
const int buttonPin = A0;
int buttonstateCounter = 0;
int lastanalogvalue = 0;
int analogvalue = 0;
int difference;
long previousMillis = 0;
long interval = 1000;
void setup() {
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
analogvalue = analogRead(buttonPin); // read the pushbutton input pin
difference = abs(lastanalogvalue - analogvalue);
if (difference > 5 ) { // button has either been pressed or released
buttonstateCounter++;
if (buttonstateCounter % 2 != 0)// button pressed, take value
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
{
previousMillis = currentMillis;
Serial.println (analogvalue);
}
}
lastanalogvalue = analogvalue;
}
}
and here is serial monitor output (anything less the ~160 is some sort of error):
Yes, sorry about that. I must clarify... I should have said that there are multiples switches connected to one analog pin through their own unique resistor. I am trying to use one analog pin to do different things. the rest of this program has already been posted multiple times on this forum so I didn't want people to get sick of seeing it. ("Oh, this guy again...")
The increments between button values is approximately 150, though some are more than 200 because of the values of the resistors I had on hand.
All the resistors have the same (10K) value. I get:
All off - 1024
S1 on - 820
S2 on - 768
S3 on - 683
S4 on - 513
S5 on - 0
Combinations take the lowest value.
Then I average the results of my reading - depending on the program I am using that might just be do a number of reads and average them, or do a constant rolling average of the reads, using say 10 data points.
If you want to debounce it then simplest general algorithm is to wait until it has provided consistent values for some period. You will have to decide how long that is - for example 0.1 seconds might be appropriate.
To implement that you would do your resistance comparisons to convert the input analog value to one of the switch positions, presumably held as an enum.
Your debounce algorithm takes a raw switch position as an input and produces a debounced switch position as the output.
It uses a state variable recording the input switch position at the last sample, and the time when the input switch position last changed, and the current debounced position.
Each time you read the analog value and convert it to a raw switch position, apply your debounce algorithm to it:
If the raw position is the same as the previous sample and the last change happened long enough ago, the debounced state changes to the new position.
If the current position is different to the previous position, record the new position and note the time when this change happened.
Record the raw position for next time.
Return the debounced position.
Note that the debounce algorithm treats the 'switch not pressed' state exactly the same as any other state - you have to take your hand off the switch long enough for your debounced state to change to 'not pressed' before you tell your application the switch has stopped being pressed.
You would put this debouncing code in front of the code discussed on your other thread which looks for changes in the debounced state.
ah it worked. I know this hardware set up works , i have used it with other examples without any issues with floating pins. for instance this code works very reliably:
const int sensorPin = A0;
const int ledPin = 9;
const int threshold1 = 50; // an arbitrary threshold level that's in the range of the analog input
const int threshold2 = 200;
const int threshold3 = 400;
const int threshold4 = 540;
const int threshold5 = 640;
const int threshold6 = 740;
const int threshold7 = 900;
int sensorValue = 0;
const int sensorMin = 0; // sensor minimum, discovered through experiment
const int sensorMax = 1023;
void setup() {
// turn on LED to signal the start of the calibration period:
Serial.begin(9600);
pinMode(sensorPin, INPUT);
}
void loop() {
sensorValue = analogRead(sensorPin);
Serial.print(sensorValue);
int range = map(sensorValue, sensorMin, sensorMax, 0, 9);
delay(500);
switch (range) {
case 0: //
Serial.println("0"); //0-102
break;
case 1: // 54k ohm - 175
Serial.println("r");
break;
case 2: // 205-306
Serial.println("0");
break;
case 3: // 307-409 18.5k ohm 378
Serial.println("c");
break;
case 4: // 410-511
break;
case 5: // 512-613 8.5k ohm 579
Serial.println("e");
break;
case 6: // 614-716 5.5k ohm 682
Serial.println("s");
break;
case 7: // 717-818 3k ohm 807
Serial.println("f");
break;
case 8: // 819-920 1.2k ohm 913
Serial.println("ph adjust");
break;
case 9: // 921-1023 0 ohm
Serial.println("auto");
break;
}
}
but nevertheless, it is a valid consideration. it could also be floating from bad connections.
PeterH,
I appreciate your detailed explanation of debounce, but sadly my brain isn't processing it. could I trouble for a raw example of how the program might be set up, (If you have the time). I have tried adapting the arduino example but it returns two values for every press and I only want one. I would also like it to only return a value once the button has been pressed