Interrupt triggered once on startup?

Hi,

I am experimenting with PinInterrups on Duemilanove 328 using simple code.

It appears that the Interrupt service routine is triggered once on board startup.

What I want to do: - Startup --> pin13 LED Off - Ground pin2 (Interrupt 0) --> Toggle pin13 LED

My code

int pin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  digitalWrite(2, HIGH);
  attachInterrupt(0, blink, FALLING);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{
   state = !state;
}

Expected: After startup LED stays off

What happens: After startup LED turn on

How to fix: Change volatile int state = LOW; to volatile int state = HIGH;

Can anyone shed some light on this?

How are you externally causing a interrupt signal for pin 2 to happen (a high to low transition), with a switch?

Lefty

A simple wire plugged into 2, which I then touch to the housing of the USB connector.

But even if I do not connect anything to pin 2 the described happens. LED turns on on startup.

Once its started the simple wire described above will toggle the LED.

The board I have came yesterday, and its my first Arduino...

Do a little searching on 'contact bounce". I think you will find that digital input pins are very prone to this problem and when used as a interrupt signal, can cause multiple interrupts of random amount when you wish for just a single transition.

Lefty

Hi,

you were right, that was due to "bounce", even though i didnt have anything connected to the pin.

I solved it like this:

int pin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  digitalWrite(2, HIGH);
  attachInterrupt(0, blink, FALLING);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 200ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 200)
  {
  state = !state;
  }
  last_interrupt_time = interrupt_time;
  
}

Just a question: Is this the recommended way? Apparently millis() stops being updated while in ISR. But then again this is only relevant if you want to have an accurate clock...

Did you overlook this note that is with the 'attachInterrupt()' information?

[b]Note[/b]

[i]Inside the attached function, delay() won't work and the value returned by millis() will not increment. Serial data received while in the function may be lost. You should declare as volatile any variables that you modify within the attached function. [/i]

Don

Hi,

I've seen this note in the attachInterrupt() page, thats why I asked. Is the debounce of interrupts as I did the recommended way? Comparing a value to millis()? Or is there a "cleaner" or "more efficient" method?

They way you've listed is the way that I like to debounce... I.e. do nothing while the input state is changing quickly.

200ms should be an eternity for any decent electro-mechanical switch.