I'm trying to Interrupt with a switch. Can I do this?

When would like to run a program in an interrupt (I think that’d be the proper way to do this anyways) but could I run this:

#include <Servo.h> 
 Servo myservo;  // create servo object to control a servo 
 
int pos = 0;    // variable to store the servo position 
 
void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
} 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
}

To turn the servo on when a switch gives say a HIGH signal to Pin 2?

I looked at the language reference and it looks like AttachInterrupt would be the method to use maybe if I define the above as a function:

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;
}

Why do you think you need an interrupt?

I have a couple of programs I'd like to be able to immediately get out of with the change of a switch. One is basically what you see in the Servo program above but with a lot more variation (read mess).

EDIT: btw, this seems like it'd be a fairly common requirement. If there's a good example on this forum I'd be glad to see that as well (I did a search).

People often imagine that interrupts are needed, when in reality, they are not. Servos and switches operate on timescales that appear glacial to a processor that executes an instruction in the time it takes a beam of light to travel 20metres or so.

I remember a book I read about embedded microprocessor design in the 1980s (when processors were a lot slower). It contained a quote which headed the chapter on interrupts, and read something like "Interrupts are difficult and dangerous; their use is to be avoided wherever possible"

You're absolutely correct regarding timing/speed. So what do you suggest? I need response time to be within 1 second if that helps narrow down my usual needs for switching via a users input.

Many times a program is several lines of instructions. So I would like to not have to execute all of them before checking a DigitalRead.

One second? Sixteen MILLION instructions?

Ok yes, so what do you recommend using? I don't mind using another method to get out of the program.

Polling usually does it for me. Look for a change of state, possibly with debounce.

Denounce? Same as Debounce I presume? I'll search out polling. If you have any good examples to point to, please do.

Beyond that, I got the attachInterrupt to do what I like (almost). Pretty simple actually. I just include this line in

void setup() attachInterrupt(0, MrServoMan, LOW);

MrServoMan is the arbitrarily named function I call up (the library's servo sweep example given in post 1) when Pin2 (interrupt input) is high. The only problem is that it does nothing "0" when the pin goes LOW. But I guess that's exactly what I told it to do, isn't it? ; )

Can I tell it to do something else when the pin is low? i.e. maybe another defined function?

I think you misunderstand what an interrupt is. It is like a little conditional function call after each and every machine instruction, with a "return" to the very next instruction. It does something simple and quick (and possibly unrelated to the main loop), and returns. How do you intend to use this mechanism to break out and do something different?

Sounds as if interrupt was the wrong approach. Hmm... so gathering what you've said, if I want to jump out of that function or block of code and go to another function, polling is what you'd choose?

Yes, it can be done, in a few different ways, depending on your requirement:

1) you can use an interrupt to detect a button push; 2) you can use an interrupt to time and advance the desired servo positions. 3) you can use an interrupt to advance the servo each and everytime a button is pushed. ...

If all you want is to start a servo turn, something like this would work:

volatile unsigned char servo_on = 0;  //servo indicator. 0=not on, and 1 = on
unsigned char pos=0; //servo position
unsigned char loop_counter = 0; //loop counter

//in key isr
ISR(whatever means you use to detect the key) {
  servo_on = 1;  //key pressed and servo is turned on
}

//process servo in your loop
void loop(void) {
  ...
  loop_counter += 1; //increment loop counter
  if (loop_counter >= MAX_LOOP) { //desired time has been reached
    loop_counter -= MAX_LOOP; //reset loop_counter
    pos+= (servo_on)? SERVO_STEP: 0; //advance pos
    if (pos >= 180) pos -= 180; //pos wraps around 180
    //go to that position
...

 }

Essentially, when the button hasn't been pushed, pos doesn't change. Once the button is pushed, pos is incremented by SERVO_STEP. You can design / alter the wrap-around mechanism to your liking.

MAX_LOOP determines how fast the servo is incremented.

If you want to be fancy, that part can be also included in a timer interrupt so the timing is not impacted by the loop timing.

Your real problem is here:

void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
}

Whether you use an interrupt or just test the switch, you are stuck in those delays most of the time. Try reading this:

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

More stuff about interrupts here:

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

Whether you use an interrupt or just test the switch, you are stuck in those delays most of the time. Try reading this:

That's why, I think, s/he wanted to use interrupt so the code can react to push buttons.

That will need some rewriting of the code for sure.

A rewrite is obvious.
Equally obvious should be that interrupts aren’t necessary.

Equally obvious should be that interrupts aren't necessary.

Whether that's necessary or not will depend on the particular application and approaches to solve that. I can think of quite a few valid reasons to use interrupts.

Given the maximum update rate of a servo is 50Hz, and the stated required latency is one second, I have to say interrupts do not spring to mind as a solution.

To bump the thread... I still don't really have what I'm looking for here. If I have the code given (that simple Servo example), how can I run that upon the activation of a switch (say a HIGH) and immediately exit out as the switch goes LOW?

I'm fairly experienced in electronics (what I studied in college) but I'm very inexperienced in programming. So any tips would be appreciated here.

If I have the code given (that simple Servo example), how can I run that upon the activation of a switch (say a HIGH) and immediately exit out as the switch goes LOW?

If you have the example as shown and you’re determined to use interrupts, then you need to add extra conditions to each of the “for” loops to examine the flag you set in your interrupt service routine, and if it is set, then the “for” will exit immediately. Don’t forget to qualify the flag with “volatile”

  for(pos = 0; pos < 180 && notAborted; pos += 1)  // goes from 0 degrees to 179 degrees if not interrupted

I’m not set on an Interrupt necessarily. I originally title the thread as such because that was one thing I considered based on other’s advice to achieve the goal. But if there’s a better way, I’d rather use it.