problem with using interrupt

i'm new to arduino pls help me..

volatile boolean state=false;

void setup() {pinMode(13,OUTPUT); pinMode(2,INPUT); pinMode(12,OUTPUT); attachInterrupt(0,light,RISING);

}

void loop() { if(state==true) { digitalWrite(12,HIGH); digitalWrite(13,LOW); }

if(state==false) {digitalWrite(13,HIGH); digitalWrite(12,LOW); } }

void light () {if (state==false) state=true; else state= false;

}

from the above coding i expect first pin 13 have to provide 5v and pin12 have to provide 0 v after the interrupt occur pin 12 have to provide 5v and pin 13 have to provide 0v but in simulation first pin 12 provide the 5v and after interrupt pin 13 provide 5v i'm very confused is there any wrong with this code pls help me anyone

void light ()
{if (state==false)
state=true;
else
state= false;

}

would be so much simpler as:

void light ()
{
    state = !sate;
}

And, notice how much better it looks with nothing following the { AND properly indented.

Now, you need to tell us what is providing the external interrupt, and what the code actually does.

Interrupt 0 is the external interrupt connected to pin 2. What do you have connected to pin 2 that will cause a low to high transition on that pin?

i have connect the push button to pin 2

actually i need to control 2 motors using switches so i try to make me better with interrupt so i try this code for a trail

actually i need to control 2 motors using switches so i try to make me better with interrupt so i try this code for a trail

You need to explain why interrupts are needed. It sounds like polling is going to be much simpler. Just don't write blocking code. Then, you can poll often enough.

How is the button wired? Do you have a pull down resistor? Are you debouncing the button? Without debounce the button will generate several interrupts with each press. Try the circuit below for your button. It is the accepted way to wire a button. You need to modify your code to look for a high to low transition. That said, you would be better off not using interrupts for your program. Polling the state of the button each time through loop() would read it plenty fast.

alternatively, you could software debounce the interrupt, like this:

volatile boolean state=false;

void setup()
{
  pinMode(13,OUTPUT);
  pinMode(2,INPUT);
  pinMode(12,OUTPUT);
  attachInterrupt(0,light,RISING);

}

void loop()
{
  if(state==true)
  {
    digitalWrite(12,HIGH);
    digitalWrite(13,LOW);
  }
  if(state==false)
  {
    digitalWrite(13,HIGH);
    digitalWrite(12,LOW);
  }
}
void light()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  if (interrupt_time - last_interrupt_time > 200)
  {
    state = !state;
  }
  last_interrupt_time = interrupt_time;
}

ya my push buttons also connected same as your diagram but one think before the pin i connect a inverting schmittriger . my problem is normally ISR(in my case void light()) is executed only after any interrupt occur but in my case i think when the code is start to execute one time it execute the ISR and after that it execute the void loop() function is there any possibilities to happen like this

The interrupt, once exccuted, will return the program to the point where it was, prior to the interrupt event.

is there any possibilities to happen like this

If you write the code correctly, yes. On the other hand, if you write the code correctly to begin with, you don’t need interrupts.

Of course, writing the code correctly means not writing any blocking code, especially avoiding delay() like the plague.

kandee: before the pin i connect a inverting schmittriger .

Why would you add hardware to invert s signal when you can do it with less trouble and for free with software?

...R

Using millis() timer software debounce within an interrupt service routing is not correct.

void light()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  if (interrupt_time - last_interrupt_time > 200)
  {
    state = !state;
  }
  last_interrupt_time = interrupt_time;
}

From http://arduino.cc/en/Reference/AttachInterrupt

About Interrupt Service Routines

ISRs are special kinds of functions that have some unique limitations most other functions do not have. An ISR cannot have any parameters, and they shouldn't return anything. Generally, an ISR should be as short and fast as possible. If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be ignored (turned off) until the current one is finished. as delay() and millis() both rely on interrupts, they will not work while an ISR is running. delayMicroseconds(), which does not rely on interrupts, will work as expected. Typically global variables are used to pass data between an ISR and the main program. To make sure variables used in an ISR are updated correctly, declare them as volatile. For more information on interrupts, see Nick Gammon's notes.

Polling with debounce is a much better approach with mechanical buttons.

cattledog: Using millis() timer software debounce within an interrupt service routing is not correct.

void light()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  if (interrupt_time - last_interrupt_time > 200)
  {
    state = !state;
  }y
  last_interrupt_time = interrupt_time;
}

From http://arduino.cc/en/Reference/AttachInterrupt

About Interrupt Service Routines

ISRs are special kinds of functions that have some unique limitations most other functions do not have. An ISR cannot have any parameters, and they shouldn't return anything. Generally, an ISR should be as short and fast as possible. If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be ignored (turned off) until the current one is finished. as delay() and millis() both rely on interrupts, they will not work while an ISR is running. delayMicroseconds(), which does not rely on interrupts, will work as expected. Typically global variables are used to pass data between an ISR and the main program. To make sure variables used in an ISR are updated correctly, declare them as volatile. For more information on interrupts, see Nick Gammon's notes.

Cattledog, you are not correct here.

This approach uses the return of millis() which ,while not progressing, and not useful for a timer function, will certainly return the moment that the program ceded to the interrupt.

And... It works.