Pages: 1 [2]   Go Down
Author Topic: goto statement in ISR?  (Read 1676 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What does this "long" function do? Can you post it? Is it long in physical lines of code, or long in that it does something that takes a long time?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

yes it takes long time
i want to explain my code but i'm working autonomous robot, when collosion detect, robot stop motors 100ms then goback very short distance and turnleft ===> this is my long function
robot use switch sensor to detect collisons, some of my tests show that sometimes more than one crash happen in long function ends, i used interrupt, but this time i'm get stuck in ISR,
i want to when switch interrupts, start long function again.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45985
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
i want to when switch interrupts, start long function again.
What long function? I think it is time you told us about this long function.

It is also likely that you need to re-write this long function so that it doesn't take so long.
Logged

0
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3418
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Then you would need to rewind the stack and ensure that all non atomic variable accesses are either cleaned up or do not cause any strange side effects. Rewinding the stack is never achieved with goto.
Logged

Check out my experiments http://blog.blinkenlight.net

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
 
void ISR() {
  goStop();
  delay(100);
  goBackward();   
  delay(100);
  goStop();
  delay(100);
  goLeft();
  delay(100);
  goStop();
  delay(100);
  digitalWrite(redledPin,HIGH);
  delay(100);
}
this my ISR code...
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45985
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
this my ISR code...
Of course, you are aware that delay() doesn't work in an interrupt handler.
Logged

Portugal
Offline Offline
God Member
*****
Karma: 5
Posts: 962
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You NEVER use delays inside an ISR.
An ISR must be short and clean!
And delay relies on interrupts and when you are inside and ISR all the other interrupts are disabled so delay, and milis doesn't works.
If you want to do that, just set a flag in your ISR and then read that flag in the main and do what you want.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

this my ISR code...

Words elude me a little bit, but I suppose I see what you are doing...

When the button is pressed you want to do all that stuff, and if it is pressed again, do it again from the start?

Time for a restructure:

Code:
volatile boolean pressed;

void ISR ()
 {
 pressed = true;
}  // end of ISR


void loop ()
  {
  if (pressed)
    move_the_robot ();
  }  // end of loop

void move_the_robot ()
  {
  pressed = false;

  goStop();

  if (pressed)
    return;
  else
    delay(100);

  goBackward();    

  if (pressed)
    return;
  else
    delay(100);

  goStop();

  if (pressed)
    return;
  else
    delay(100);

  goLeft();

  if (pressed)
    return;
  else
    delay(100);

  goStop();

  if (pressed)
    return;
  else
    delay(100);

  digitalWrite(redledPin,HIGH);

  if (pressed)
    return;
  else
    delay(100);

  }  // end of move_the_robot

« Last Edit: August 14, 2011, 04:12:34 pm by Nick Gammon » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24308
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@OP:
I think you have the concept of interrupts a bit confused.
Interrupts are signals to the processor that something has happened, and if you don't do something about it pretty soon, bad things will occur.
Such an event might signal the arrival of a character in the UART receive buffer, and if you don't read it within the next few hundred microseconds, it will be overwritten by the next character.
It would be inconvenient to litter your code with tests for "serial-in available", so an interrupt can divert the processor after every single machine instruction (not line of C code) to go off and handle that event.

As far as just about anything mechanical is concerned, this is not operating on the same sort of timescales as the processor.
A "bump" event is quite different to the actions that must occur to respond to the event, and you must handle them separately.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think the problem lies in the architecture of the long function, and the fact that a long-running, linear function is at odds with the asynchronously-resettable requirement of the external stimuus (i.e an interrupt in this case).

I would break down the long function into smaller, faster states and build a resettable state machine that can always start from the initial state. Something like this:

Code:
int state = 0;

void ISR()
{
  state = 0;
}

void loop()
{
  switch (state)
  {
    case 0:
      calcuateThis();
      state = 1;
      break;
    case 1:
      calcuateThat();
      state = 2;
    case 2:
      computeResults();
      state = 0;
      break;
  }
}

You get the idea. Of course, it makes the system harder to build and debug, and the system must survive the state reset in any previous state, but it sure beats trying to unwind the program stack and stuff.

Just my 2 cents' worth from a backseat programmer.   :-)
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I agree with primate that a state machine would be even neater. I was trying to show the original code revamped a bit. But something like this would be nicer:

Code:
volatile boolean pressed;
int state = 0;

void isr ()
 {
 pressed = true;
 }  // end of isr
 
void loop ()
  {

  // when button pressed start doing things
  if (pressed)
    {
    pressed = false;
    state = 1;
    }
   
  switch (state)
    {
    case 0:   return;  // no action on state 0
    case 1:   goStop(); break;
    case 2:   goBackward(); break;
    case 3:   goStop(); break;
    case 4:   goLeft(); break;
    case 5:   goStop(); break;
    case 6:   digitalWrite(redledPin,HIGH); break;
    default:  state = 0; return;
    }  // end of switch
 
  // onto next state
  state++;
  delay(100);

  }  // end of loop
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks everyone it works...
Logged

Pages: 1 [2]   Go Up
Jump to: