I have a simple project that I prototyped using those little breadboard momentary buttons. I've debounced them and everything works great. For my final product, I switched to a larger momentary button, but now they tend to very rapidly double register their LOW state when pressed which is breaking the functionality.
I guess my question is, could the buttons themselves just be cheap and not as precice? As cheap as those little momentary buttons are, they have a definitive 'click' where the bigger buttons do not, but they're all I could find....
I've double checked my solder connections. I just don't know if I should be looking at the buttons or the code, but like I said those little buttons work flawlessly...
flyagaricus:
I had the debounce at 50, but have moved it up to 500ms which seems to be the sweet spot for these buttons.
Then something is terribly wrong. Those tact switches are not that bad. What happens when you run a known to be good switch debounce and read sketch, like the IDE example?
I suspect those push buttons are pretty rubbish without reliable connection. A proper push button
momentary switch has an internal spring that makes the contact reliable (after any bouncing has
died away). Without such a mechanism you are pressing two bits of metal together by finger pressure
alone, and that can be unreliable as fingers tend to move around a bit.
A decent push switch is tactile - you feel the spring operate and release.
I see, it's not tact switches, it's the panel mount switches. Indeed, they might not be as good. Still, I would like to see the results of using them with a standard, already proven debounce routine.
aarg:
Then something is terribly wrong. Those tact switches are not that bad. What happens when you run a known to be good switch debounce and read sketch, like the IDE example?
The buttons 'switch from LOW to HIGH more than one in the the 50ms...I guess? So by code picks up two presses which is not acceptable.
Switch is on A0, buzzer is on D08, LED1 on D07, heartbeatLED on D13.
Open the Serial monitor at 9600 baud to see the counter increment.
If all okay, change line #24 to 50ms.
//
// YY/MM/DD Version
// 18/04/27 1.00 Working code
//
#define PUSHED LOW //the switch is connected between GND and our pin
#define LEDon HIGH //LED anode connected to +5V
#define LEDoff LOW
#define BUZZERon true
#define BUZZERoff false
const byte buttonPin = A0;
const byte led1Pin = 7;
const byte buzzerPin = 8;
const byte heartbeatLED = 13; //toggles every 500ms if code is non-blocking
float sinVal;
unsigned int toneVal; //sound frequency
unsigned int buzzerNumber = 0;
unsigned int counter;
byte lastButtonState;
byte pushNumber = 0;
bool buzzerStateFlag = BUZZERoff;
//timing stuff
unsigned long switchBounceInterval = 100; // <-----<<<< change to 50ms for shorter period
unsigned long buzzerTime = 5;
unsigned long switchMillis;
unsigned long buzzerMillis;
unsigned long heartbeatMillis;
//********************************************************************
void setup()
{
Serial.begin(9600);
pinMode(heartbeatLED, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(led1Pin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); //closed = LOW
} //END of setup()
//********************************************************************
void loop()
{
//*********************************
//time to toggle the heartbeat LED ?
if (millis() - heartbeatMillis >= 500)
{
//restart the Timer
heartbeatMillis = millis();
digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
}
//*********************************
//check the switches
checkSwitches();
//*********************************
//time for the next sound to be made ?
if (buzzerStateFlag == BUZZERon && millis() - buzzerMillis >= buzzerTime)
{
//restart the Timer
buzzerMillis = millis();
//buzzer program with sins wave
sinVal = sin(buzzerNumber * (PI / 180)); // Calculate the sine of x
toneVal = 3300 + sinVal * 500; // Calculate sound frequency according to the sine of x
tone(buzzerPin, toneVal); // Output sound frequency to buzzerPin
//buzzerNumber++;
buzzerNumber = buzzerNumber + 20;
if (buzzerNumber > 360)
{
buzzerNumber = 0;
}
}
//*********************************
//Other non-blocking code goes here
//*********************************
} //END of loop()
//********************************************************************
void checkSwitches()
{
//*********************************
//time to proceed with switch checking ?
if (millis() - switchMillis < switchBounceInterval)
{
return;
}
//restart the Timer
switchMillis = millis();
byte buttonState = digitalRead(buttonPin);
//*********************************
//has the switch changed state ?
if (lastButtonState == buttonState)
{
return;
}
//update to the new state
lastButtonState = buttonState;
//*********************************
//was the switch closed ?
if (buttonState == PUSHED)
{
//odd/even number of pushes
pushNumber = 1 - pushNumber;
//*********************************
//should we enable the buzzer ?
if (pushNumber == 1)
{
//enable the buzzer
buzzerStateFlag = BUZZERon;
//restart the Timer
buzzerMillis = millis();
buzzerNumber = 0;
//turn LED ON
digitalWrite(led1Pin, HIGH);
Serial.println(counter++);
}
//*********************************
//should we disable the buzzer ?
else if (pushNumber == 0)
{
//disable the buzzer
buzzerStateFlag = BUZZERoff;
noTone(buzzerPin);
//turn LED OFF
digitalWrite(led1Pin, LOW);
}
} //END of if (buttonState == PUSHED)
//*********************************
//Other switch code goes here
//*********************************
} //END of checkSwitches()
//********************************************************************