Debouncing, or problem with my code?
I have a page about using switches but since I don't want to give a link-only answer I'll summarize here.



Detect switch changes

What is needed is to detect a transition. That is, either:


It was closed and is now open.


Or:


It was open and is now closed.


To do that you need to "remember" the previous state of the switch and detect a change, like this:

const byte switchPin = 8;
byte oldSwitchState = HIGH;  // assume switch open because of pull-up resistor

void setup ()
  {
  Serial.begin (115200);
  pinMode (switchPin, INPUT_PULLUP);
  }  // end of setup

void loop ()
  {
  // see if switch is open or closed
  byte switchState = digitalRead (switchPin);

  // has it changed since last time?
  if (switchState != oldSwitchState)
    {
    oldSwitchState =  switchState;  // remember for next time 
    if (switchState == LOW)
       {
       Serial.println ("Switch closed.");
       }  // end if switchState is LOW
    else
       {
       Serial.println ("Switch opened.");
       }  // end if switchState is HIGH
    }  // end of state change

  // other code here ...

  }  // end of loop


This code looks for changes, and only displays something when the switch changes.



By the way, you should be doing neither delay nor Serial.print inside an interrupt, as both of the rely upon interrupts being active, and interrupts are not active inside an ISR.



Debouncing

A simple technique is just to build in a short delay, for example 10 milliseconds (ms). For example:

const byte switchPin = 8;
byte oldSwitchState = HIGH;  // assume switch open because of pull-up resistor
const unsigned long debounceTime = 10;  // milliseconds

void setup ()
  {
  Serial.begin (115200);
  pinMode (switchPin, INPUT_PULLUP);
  }  // end of setup

void loop ()
  {
  // see if switch is open or closed
  byte switchState = digitalRead (switchPin);

  // has it changed since last time?
  if (switchState != oldSwitchState)
    {
    oldSwitchState =  switchState;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchState == LOW)
       {
       Serial.println ("Switch closed.");
       }  // end if switchState is LOW
    else
       {
       Serial.println ("Switch opened.");
       }  // end if switchState is HIGH
    }  // end of state change

  // other code here ...

  }  // end of loop


In the above code the delay is inside loop (where it is OK to use it) and causes a short pause to allow the switch to stop bouncing.



Debouncing without delay

The above code is fine in simple applications, and if you test it, you should find that the message "Switch closed." and "Switch opened." should only occur once per switch press. But, there's a problem. If you hang around the Arduino forums for a little while you will probably see people telling you "don't use delay". There are various reasons for this, not the least is which that using delay stops your code from doing anything else useful (like testing sensors, controlling motors, flashing LEDs, etc.).

The code below does not use delay, but rather checks for the time that has elapsed after you hit the switch, and sees if the "debounceTime" (in this case 10 ms) has elapsed. If not, it ignores the transition.

const byte switchPin = 8;
byte oldSwitchState = HIGH;  // assume switch open because of pull-up resistor
const unsigned long debounceTime = 10;  // milliseconds
unsigned long switchPressTime;  // when the switch last changed state

void setup ()
  {
  Serial.begin (115200);
  pinMode (switchPin, INPUT_PULLUP);
  }  // end of setup

void loop ()
  {
  // see if switch is open or closed
  byte switchState = digitalRead (switchPin);

  // has it changed since last time?
  if (switchState != oldSwitchState)
    {
    // debounce
    if (millis () - switchPressTime &gt;= debounceTime)
       {
       switchPressTime = millis ();  // when we closed the switch 
       oldSwitchState =  switchState;  // remember for next time 
       if (switchState == LOW)
          {
          Serial.println ("Switch closed.");
          }  // end if switchState is LOW
       else
          {
          Serial.println ("Switch opened.");
          }  // end if switchState is HIGH

       }  // end if debounce time up

    }  // end of state change

  // other code here ...

  }  // end of loop


More information on the Arduino site: http://arduino.cc/en/Tutorial/Debounce 




  It is essential for me to use an interrupt, because I need to be able to pause my entire program, at the push of a button, then resume it when the button is pushed again. I heard from other people that I cannot use any type of delay in the interrupt, is this true? 


You don't really pause a program with delay, it is now just doing something else (waiting for a timer to reach a certain time). Timers depend on interrupts to update counters as the hardware timer will overflow (roll over) very rapidly.

I suggest a redesign. In your main loop, for example, you could detect the switch press, and then not do anything until it is pressed again. For example, where I had "other code here" in my example:

static bool switchWasPressed;

if (switchWasPressed)
  {
  // do nothing
  }
else
  {
  // do what you want to do continuously
  }


Now, in the code which detects switch presses you toggle switchWasPressed. So instead of:

Serial.println ("Switch closed.");


You put:

switchWasPressed = !switchWasPressed;  // toggle switch press state