Interrupts - While not working.

It has been a year or two since I did my last project so I'm a bit rusty.

If some reason this program continually sends data. It is only supposed to when I press the button.

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
unsigned long start, finished, elapsed;
boolean pulseInp =  true;

// variables will change:
volatile int buttonState = 0;         // variable for reading the pushbutton status


void setup()
  {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  // Attach an interrupt to the ISR vector
  attachInterrupt(0, pin_ISR, CHANGE);
  Serial.begin(9600);  
}

void loop()
  {
  noInterrupts();
  finished=millis();
  elapsed=finished-start;
  Serial.print(elapsed);
  Serial.println();
  pulseInp = false;
  interrupts();
  while (pulseInp == false)
  {
  delay(100);
  }
}

void pin_ISR() 
  {
  start=millis();
  pulseInp = true;
}

Does the button have a pull up or pull down?

Btw, using a ISR is a bit overkill for this. Also, it just gives the time ellapsed between when the button is pressed and the delay is ended. Is that what you want? Also, you use start in the IRS so it should be volatile as well. But I would drop the whole interrupt part.

Why isn't "pulseInp" volatile, but "buttonState" (which you don't use) is?

Thanks for the replies. For some reason I'm not getting an email !!!

This is just part a timing sequence on a drum speed counter. Needs to be ISR

The button does work with other tests and I added a serial print line to check.

When I press a button I get 1234 but i don't get any serial data from the main function. Is the state of pulseInp global to all code ?

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
unsigned long start = 0;
unsigned long finished, elapsed;
boolean pulseInp =  true;
// variables will change:
volatile int buttonState = 0;         // variable for reading the pushbutton status


void setup()
  {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  // Attach an interrupt to the ISR vector
  attachInterrupt(0, pin_ISR, RISING);
  Serial.begin(9600);  
}

void loop()
  {
  noInterrupts();
  finished=micros() ;
  elapsed=finished-start;
  Serial.print(elapsed);
  Serial.println();
  delay(100);  
  pulseInp = false;
  interrupts();
  while (!pulseInp)
  {
  delay(100);
  }
}

void pin_ISR() 
  {
  start=millis();
  Serial.println(1234);
  pulseInp = false;
}

You still haven't addressed the problems pointed out by AWOL and septillion. ie Any variables that are modified within an ISR must be declared as 'volatile'. Both 'start' and 'pulseInp' fit that category. You can't continue testing and expect reliable results until you've taken care of that.

And 'buttonState' doesn't need to be declared 'volatile'. (AWOL mentioned this too, but you appear to have ignored everything that's been said.)

Also, you can't do this in an ISR:- ('Serial.println()' uses interrupts, which are disabled inside an ISR.)

Serial.println(1234);

Sorry my mistake.

I haven't used ISR before and the term volatile is new to me. So I guess with a bit of reading on volatile and I will be good.

Thanks for the help.

Marsheng: This is just part a timing sequence on a drum speed counter. Needs to be ISR

And you thought, no need to tell them this? It's not a button then, is it?

And besides all the stuff OldSteve mentioned, have you checked that the input/button/sensor isn't floating? Aka, has a pull up/down resistor or push-pulls?

And for volatile: Embed with Elliot: The volatile keyword ;)

Once pulseInp has been set to false it is never set to true again. Is that what you intended ?

This is just part a timing sequence on a drum speed counter. Needs to be ISR

It would be interesting to know why it needs to be an ISR.

septillion: And for volatile: Embed with Elliot: The volatile keyword ;)

That's a very good article. Thanks. I kept a link to it for future reference.

It was late when I copied and pasted the bits together. Poor excuse for my code. I see volatile is like the Delphi Global Variable.

I have tided it up and now it works.

const int buttonPin = 2;     // the number of the pushbutton pin
unsigned long finished;
// variables will change:
volatile unsigned long start = 0;
volatile boolean pulseInp =  true;

void setup()
  {
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  // Attach an interrupt to the ISR vector
  attachInterrupt(0, pin_ISR, RISING);
  Serial.begin(9600);  
}

void loop()
  {
  finished=micros() ;
  Serial.print(finished-start);
  Serial.println();
  pulseInp = false;
  // Debounce 
  delay(2000);  
  interrupts();
  while (!pulseInp){}
}

void pin_ISR() 
  {
  noInterrupts();    
  start=micros();
  pulseInp = true;
}

I am using micros() however the time sent to the PC varies quite a bit with each button press. Where are the possible delays ?

782736 829340 1215136 905184 1168904 1348000

I presume I can use noInterrupts(); in the interrupt routine.

Thanks Wallace

The code is to measure the rate of change of a disk's speed. The disk will be spinning at around 100 hz. The pickup is an opto-coupler.

Thanks Wallace.

presume I can use noInterrupts(); in the interrupt routine.

Yes, but why bother ? Interrupts are automatically disabled when in an ISR

septillion: And for volatile: Embed with Elliot: The volatile keyword ;)

It's a useful article, but you need to read and understand some of the comments, particularly the ones about atomic reads.

UKHeliBob: Interrupts are automatically disabled when in an ISR

It doesn't appear to be.

If i move the noInterrupts() to straight after the While, I often get 2 lines of serial data.

If I have the noInterrupts() as the first line in the ISR, I don't.

There appears to be another problem as well. It looks like the ISR is being executed while in the delay(2000) step but the ISR is only returning after the delay(2000) is finished, hence the large timing numbers. If i wait 2 or more seconds, I get a value in the order of 8 to 12 mictoseconds

void loop()
  {

  finished=micros() ;
  Serial.print(finished-start);
  Serial.println();
  pulseInp = false;  
  // Debounce 
  delay(2000);  
  interrupts();
  while (!pulseInp){}
   
}

void pin_ISR() 
  {
  noInterrupts();     
  start=micros();
  pulseInp = true;
}

8 8 27264 733284 722276 8 1833776 536452 8 1999852 207180 8 1999860

With a bit of experimenting and no other code changes, I moved the pulseInp = false to after the delay(2000) and now it all works correctly.

  // Debounce 
  delay(2000);  
  pulseInp = false;      
  interrupts();
  while (!pulseInp){}

12 8 12 8 8 8 8 8 8 8

A bit confused.

PS I have a pullup resistor.