Thank you for your replies. I am familiar with software debounce while polling, but thought I would try hardware debouncing. I had a LM339 laying around so I thought I might try to see how well debouncing would work with hardware since I had seen others using it with apparent success.
As suggested, I did place a 2.2k resistor in series with the push button switch. I end up with the same results. Inconsistent switching with polling and with interrupt when no software debounce was utilized. Curious, (and lacking an oscilloscope) I wrote a script to count the number of bounces on the switch as it was pressed or released and track the amount of time that the switch actually bounced. The hardware as set up (including Paul__B's resistor suggestion) would bounce an average of 2 times in 12-16 us upon press and 5 to 7 times in 34-80 us when released. So I decided to try a very basic circuit. Leaving one side of the switch grounded, I pulled the other side high with a 2.2k resistor and connected my interrupt between the resistor and the switch. The bounces were reduced to 2 or less in under 16 us. The other parts of the circuit were introducing many bounces.
I used the capacitor to smooth the switching, but apparently it is hindering. I decided to test the circuit as Paul__B stated it would work (with the 1/5 value of the pull-up resistor in series with the switch) but with the capacitor removed, to see how much it was affecting performance. Bounces were "nearly" non-existent. Software debouncing will be required for this type of circuit. The capacitor was, as I find now in this circuit configuration, an error in judgement. Add this to my experiences.
Also, if you can use the included code to count switch bounces or other interrupt activations...please do. If you see a flaw that I can improve fix, please let me know.
// Constants
const unsigned int mode = FALLING; // Mode of interrupt [ LOW/CHANGE/RISING/FALLING/HIGH ] (HIGH is for Arduino Due only)
const unsigned int interrupt = 1; // Which interrupt will be used
const unsigned int baud = 38400; // Speed (Baud) of the serial connection [ 300/1200/2400/4800/9600/19600/38400/57600/115200 ]
const unsigned long waitTime = 5000; // Default timeout of the process to display bounces...if any
const unsigned long gracePeriodMs = 100; // Number of milliseconds to wait after last button action recorded before posting results
// Too short of time may not get all interrupt calls for the current switch activation
// Too long will only make you wait until "waitTime" expires
// Non-Constants
unsigned long inputExpiryTime; // When time runs out and bounce results will be displayed
// Variables modified within ISR (Interrupt Service Routine) must be declared "volatile"
volatile unsigned int count; // Number of interrupt calls
volatile unsigned long countStartTime; // Time of first interrupt in microseconds
volatile unsigned long countEndTime; // Time of last interrupt in microseconds
void setup()
{
Serial.begin( baud );
}
void loop()
{
count = 0; // Reset interrupt call count
inputExpiryTime = millis() + waitTime; // set input expiration time
attachInterrupt( interrupt , recordBounce , FALLING ); // attach the interrupt
while( millis() < inputExpiryTime ) // Wait for interrupt input
{
if( count && ( micros() - countEndTime > gracePeriodMs * 1000 ) ) // once interrupt has been called, don't wait until the timeout expires...// only wait until grace period expires
{
inputExpiryTime = millis() - 1; // Force the display of the interrupt call count
}
}
detachInterrupt( interrupt ); // detach the interrupt to keep from receiving signals while printing
switch (count) {
case 0: // Time ran out for operating switch
Serial.println( "Time expired! No input detected." );
break;
case 1: // No bounce detected
Serial.println( "No bounce detected! Is the grace period long enough?" );
break;
default:
Serial.print( "Start Time: ");
Serial.print( "\t" );
Serial.print( countStartTime ); // First interrupt call of this iteration
Serial.print( "\t" );
Serial.print( "End Time: " );
Serial.print( "\t" );
Serial.print( countEndTime ); // Last interrupt call of this iteration
Serial.println( "\t" );
Serial.print( "Total Time: " );
Serial.print( "\t" );
Serial.print( countEndTime - countStartTime ); // Time that switch bounced in this iteration
Serial.println( "us " );
Serial.print( "Count: " );
Serial.print( "\t" );
Serial.print( count ); // How many times the switch actuated interrupt mode
Serial.print( ":\t" );
Serial.print( "Initial activation and " );
Serial.print( count - 1 ); // Number of measured bounces per interrupt mode
if( count == 2 )
{
Serial.print( " bounce. " );
}
else
{
Serial.print( " bounces. " );
}
Serial.println( "\t" );
break;
}
}
void recordBounce()
{ // ISR to count actuation and subsequent bounces
count += 1;
if( count == 1 ) countStartTime = micros(); // first interrupt, start counter
countEndTime = micros(); // current time
}