AttachInterupt example program doesn't work on UNO

I tried to run the following program and the led doesn't blink.

int pin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}

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

void blink()
{
  state = !state;
}

I got the example here: http://arduino.cc/en/Reference/attachInterrupt

I have a jumper from from pin 13 to pin 2 (per the "pin" info at above link) What am I doing wrong ?

I have a jumper from from pin 13 to pin 2 (per the "pin" info at above link)

Where does it say to do that?

The interrupt fires if the pin changes. It won't change if it is attached to another pin like that.

I can see your logic in connecting the two pins but nothing sets it off. Anyway what speed do you think it will blink at? It will be bringing at at least a MHz, can you see a thing blinking that fast? Well it is rhetoricle, you can't.

Where does it say to do that?

Board int.0 int.1 int.2 int.3 int.4 int.5
Uno, Ethernet 2

Some examples give wiring illustrations. This one simply lists the interrupt pin number.
How is this example supposed to be helpful ?
Does it say anywhere what the point of the example is ?
With an ISR name like ‘Blink’ , what do expect me to expect ?
If you can point to what the ‘point’ (purpose) of the example is then please do so because people like
you would not be reading that example in the first place, now would they ?
If I knew what you are telling me would it make sense for me toI be reading the above example in the first place?

If you are trying to be helpful, show me what I ‘missed’ when I read it in the first place, please.

The following program works, and illustrates (visibly) as opposed to ‘invisably’ an ISR:
i find this example helpful. It is a modification of one I found online that uses a pushbutton.
I replaced the pushbutton with a digitalWrite from another pin because I am trying to
solve the problem described here (the ISR code doesn’t work):

volatile boolean setflag=false;
// int myInterruptVar;
const int intISR = 0;

volatile boolean newKey = false;
volatile int Ledpin=6;
volatile int SimInt=3;

void setup()
{
   attachInterrupt(intISR,readEncoder , CHANGE);
  
 
    pinMode(Ledpin, OUTPUT);
    pinMode(SimInt, OUTPUT);
    Serial.begin(9600);

}

void loop()
{
  Serial.println("Waiting for interrupt= ");
  delay(300);
  digitalWrite(Ledpin,LOW);
  delay(300);
  
  digitalWrite(SimInt,HIGH);
  delay(300);



}
  void readEncoder() 
{
 
 
 newKey = true;

  digitalWrite(Ledpin,HIGH);
  delay(300);
  digitalWrite(SimInt,LOW);
  delay(300);
  Serial.println("ISR Service Completed ");
  delay(300);
}

I tried to implement the ISR into the program that is currently working using an 'if statement.
I replaced the whole keypad circuit with a led and a jumper wire to figure out why the
attachInterrupt doesn’t work in the keypad program attached.

Matrix_4x3_12_key_keypad_to_74c922_encoder_ic_ISR_NOT_WORKING.ino (1.14 KB)

Some examples give wiring illustrations. This one simply lists the interrupt pin number.

So why fly off the handle if some one asks you where it said connect the wires if the link you provided does not show that wiring?

if you are trying to be helpful, show me what I 'missed'

You missed being polite.

We did not write that example, so don't get shirty. That page was a reference page showing you how things work. If you put an oscilloscope on the LED you will indeed see it is blinking.

I think you are mixing up reference with tutorial.

You missed the part where I said"please"... Can you PLEASE show me what the point of the example is or what I missed ?

I apologize if I came off 'testy' Grumpy Mike. Please pardon my rudeness. I shall endeavor to be more courteous in the future. Do you think you could find it in your heart to forgive me so we can move on to establishing a better rapport or is that out of the question? Robert

raschemmel: You missed the part where I said"please"... Can you PLEASE show me what the point of the example is or what I missed ?

When the interrupt is triggered by a switch input, the example makes sense. The way you have got it set up now, each interrupt immediately triggers another interrupt. Bearing in mind that the processor is running at 16 MHz or so, this means it will be triggering interrupts and toggling the LED output state at a frequency thousands of times too high for you to see it with the naked eye. If you want to demonstrate interrupt handlers, I suggest you remove the jumper wire and connect a switch instead. You'll also need a pull-up / pull-down resistor, and I suggest using the internal pull-up. There are several standard examples showing how to read a switch input and I suggest you run those to confirm you've got the switch wired correctly and working before you move on to using it to trigger an interrupt.

Let me explain it like this. If you connect the wires together like you did, in the event that a change occurred, the interrupt would change it back. A bit like this:

http://www.youtube.com/watch?v=Z86V_ICUCD4

So either no change occurs at all, or as Mike said earlier it would change back (and forwards) extremely quickly.

I was hoping my question would prompt you to think along those lines. If you simply cause a change by connecting the interrupt pin to (say) ground and 5v alternately, then the LED should follow (however taking into account floating inputs and bouncing.

More reading:

http://www.gammon.com.au/interrupts

http://www.gammon.com.au/switches

How is this example supposed to be helpful ?

It was helpful enough, you just added your own ideas to it by connecting the output to the input, effectively creating a feedback loop.

Thank you for the clarification. I'll have to read the tutorials tonight. Let me explain why I connected the wires. When I posted this: http://forum.arduino.cc/index.php?topic=203396.msg1502382#msg1502382

I was trying to use an interupt for the keypad program. The 74c922 16-key encoder ic has a DATA_AV output on pin-12. Originally I used that for my 'if' statement while trying to debug the ISR problem. Eventually I decided that what I needed to do was take the keypad circuit out of the equation entirely and simulate the DATA_AV with a digitalWrite from another pin. Since the encoder ic toggles the DATA_AV (low to high, then high to low) I needed to add something to the simulator to make the waveform on the simpin mimic the keypad encoder Obviously I could have used a 555 monostable but it would have defeated the goal of understanding how software works. By setting the simpin HIGH at the beginning of the main loop and clearing it inside the ISR, The result was supposed to simulate a keypress generating the pulse on DATA_AV and then the data is read inside the ISR followed by the simpin set to low. The part that was suppose to prevent a 'runaway' condition like I think you were referring to was the delay after the digitalWrite(simpin,LOW); at the end of the ISR. However , I did notice that in the Reference on AttachInterrupt it said:

Note

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. See the section on ISRs below for more information.

And this may be the source of my problem. I have a scope I can put on the pins (ch-1=>pin-2, ch-2=>simpin) to troubleshoot it. The ISR is supposed to be triggered by the DATA_AV by a jumper from DATA_AV to UNO-pin-2, and then the ISR should read the encoder send the data out the serial port , clear the newKey flag, and change the simpin back to LOW.

If I understand you correctly , that won't work,, right ? What is the correct way to do it ?

Can you post this sketch?

... then the ISR should read the encoder send the data out the serial port ...

You can't do serial sends inside an ISR (successfully).

http://www.gammon.com.au/interrupts

It's attached to Reply #3 today here: (right after Mike asked "Where does it say to do that ?") http://forum.arduino.cc/index.php?topic=204259.msg1503945#msg1503945

The program pasted in the window is the the simulator I created that actually does loop through turning on and off the led (visably). The file attachment is not a simulator. It is the actually keypad program that is not working correctly.

And Mike. Now that I know what to expect, I WILL put a scope on it tonight. Thanks for pointing that out. It didn't occur to me at the time.

 attachInterrupt(intISR,readEncoder , CHANGE); 

...

 void readEncoder() 
{

      digitalWrite(Ledpin,HIGH);
      delay(300);
      total = PIND >> 4; 
       Serial.print("total(BIN)=  ");
       Serial.print(total,BIN);
       Serial.println(" ");
       Serial.print("total=  ");
       Serial.println(total);
       Key = totVals[total];
       digitalWrite(Ledpin,HIGH);
       delay(300); 
       Serial.print("key=  ");
       Serial.println(Key);
       Serial.println("ISR Service Completed ");
       newKey = true;
       delay(300);
       
}

Don't do delays inside an ISR. Don't do serial prints.

http://www.gammon.com.au/interrupts

It also mentions that on the page you linked:

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. See the section on ISRs below for more information.

There is also a link to my page there.

OK. Thanks, I'll redo it tonight.

I can see your logic in connecting the two pins but nothing sets it off.
Anyway what speed do you think it will blink at? It will be bringing at at least a MHz, can you see a thing blinking that fast? Well it is rhetoricle, you can’t.

Mike,
I put a scope on the AttachInterupt Example and there was no change.(with nothing connected
to UNO , pin-2).
So I connected a jumper from pin-2 to the led at the same place as the jumper from pin-13 and the
there was still no change (led still off). If I connected the jumper (from pin-2) to +5V the led turned on.
If I connected the pin -2 jumper to a pullup resistor and used a switch to short it to ground the light
stayed off while pressing the switch. So, as you said, “nothing sets it off”. I think the example
would have been more useful if they added the switch, like in Nick’s Interrupt Tutorial.
Bottom line, I retract my statement in the title of this post. The Attach Interrupt example does work.

Nick, You said I can't use serial sends in an ISR. So how can I save data acquired inside an ISR so it is accessible outside the ISR ? Is there some Volatile or Non-Volatile memory available to the user for storing data obtained in an ISR ?

You can store whatever you want from the ISR in global variables (declare them volatile so the compiler knows they may change unexpectedly).

Normally you would store various things (eg. the time stuff happens) and then set a "changed" flag. The main loop notices the changed flag is set, accesses the variables and does stuff (like serial prints) and then clears the changed flag.

DONE.
(see attached)

Matrix_4x3_12_key_keypad_to_74c922_encoder_ic_ISR_WORKING.ino (853 Bytes)

Nick,
I’m reading your tutorial on interrupts and in the Watchdog Timer interrupt I can’t find the
ISR where you do what they call “petting the dog”. Is it there ?

#include <avr/sleep.h>
#include <avr/wdt.h>

#define LED 13

// interrupt service routine for when button pressed
void wake ()                            
{
  wdt_disable();  // disable watchdog
}  // end of wake

// watchdog interrupt
ISR (WDT_vect) 
{
  wake ();
}  // end of WDT_vect

void myWatchdogEnable (const byte interval) 
{ 
  MCUSR = 0;                          // reset various flags
  WDTCSR |= 0b00011000;               // see docs, set WDCE, WDE
  WDTCSR =  0b01000000 | interval;    // set WDIE, and appropriate delay
  wdt_reset();
  
  byte adcsra_save = ADCSRA;
  byte prr_save = PRR;

  ADCSRA = 0;  // disable ADC
  PRR = 0xFF; // turn off various modules
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
  attachInterrupt (0, wake, LOW);   // allow grounding pin 2 to wake us
  sleep_mode ();            // now goes to Sleep and waits for the interrupt
  detachInterrupt (0);      // stop LOW interrupt
  
  ADCSRA = adcsra_save; // stop power reduction
  PRR = prr_save;
}  // end of myWatchdogEnable

void setup ()
{
  digitalWrite (2, HIGH);    // pull-up on button
}  // end of setup

void loop()
{
  pinMode (LED, OUTPUT);
  digitalWrite (LED, HIGH);
  delay (5000);
  digitalWrite (LED, LOW);
  delay (5000);

  // sleep bit patterns:
  //  1 second:  0b000110
  //  2 seconds: 0b000111
  //  4 seconds: 0b100000
  //  8 seconds: 0b100001

  // sleep for 8 seconds
  myWatchdogEnable (0b100001);  // 8 seconds

}  // end of loop