Pages: [1]   Go Down
Author Topic: Setting Up an Interrupt using switches  (Read 314 times)
0 Members and 1 Guest are viewing this topic.
NYC
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey everyone, here's the issue I'm having:

I've attempted to setup an interrupt that is able to determine which external switch has been hit, then respond accordingly. I'm relatively new to this, so bear with me.

Here's the current code:

Code:
#include <SOSS.h>
#include <AIT.h>

void setup()
{
  configArduino ();
  void motor1 ();
  void motor2 ();
  attachInterrupt (0, rightInterrupt, LOW); //for pin D2
  attachInterrupt (1, leftInterrupt, LOW); //for pin D3
}

void rightInterrupt ()
{
pause (5);
if (readInput (2) ==1 && readInput (3) ==1) return;
motor1 ('o', 0);
motor2 ('o', 0);
pause (50);
return;

if (readInput (2) ==1 || readInput (3)==0)
{
motor1 ('b', 80);
motor2 ('b', 80);
pause (500);
motor1 ('b', 80);
motor2 ('a', 80);
pause (750);
return;
}
return;
}


void leftInterrupt ()
{
pause (5);
if (readInput (2) ==1 && readInput (3) ==1) return;
motor1 ('o', 0);
motor2 ('o', 0);
pause (50);
while (readInput (2) ==0 || readInput (3)==1)
{
motor1 ('o', 0);
motor2 ('o', 0);
pause (50);
motor1 ('b', 80);
motor2 ('b', 80);
pause (500);
motor1 ('b', 80);
motor2 ('a', 80);
pause (750);
}
return;
}
void loop()
{

motor1 ('a', 40);
motor2 ('a', 40);
void leftInterrupt();
void rightInterrupt();
}

What it's supposed to do:

When a the interrupt is triggered by the external switch, I want to have the motors first shut off ('o') , then go in reverse ('b'), then turn (one motor off while the other turns).

Currently what happens is that when one of the switches is pressed, it does what Is written in the code, but it never exits the interrupt function, it just continues to perform what is in the interrupt function.

So the question is, what have I done wrong?

Thanks in advance.
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4336
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It would be extremely helpful to see all of your code, not just a part of it.

A first comment though.  Why are those while loops inside the ISR ?
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

United Kingdom
Offline Offline
Tesla Member
***
Karma: 227
Posts: 6637
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You are trying to do far too much in the interrupt service routines. In fact, this application would be better implemented without using interrupts at all. Poll the switches instead.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50331
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

LOW is the wrong value to be using in the attachInterrupt() routine.

Using interrupts at all seems to be the wrong approach. Getting rid of the pause() function altogether IS the right approach.
Logged

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

It would be extremely helpful to see all of your code, not just a part of it.

A first comment though.  Why are those while loops inside the ISR ?

This is all of my code for now. I just have it so the motors are going straight at the same speed until a bumper is being hit.

You are trying to do far too much in the interrupt service routines. In fact, this application would be better implemented without using interrupts at all. Poll the switches instead.

I decided to use interrupts because later on, the main code is going to have light sensors that determines how the machine will move. Once a bumper is triggered, I want it to do a set of certain actions, then continue on the main code once the interrupt has been completed. The problem with polling is that It wouldn't happen instantly, whereas the interrupt would. Is there a better way of doing this?
« Last Edit: October 21, 2013, 08:08:26 am by murrgh » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50331
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Once a bumper is triggered, I want it to do a set of certain actions, then continue on the main code once the interrupt has been completed. Is there a better way of doing this?
Yes. Polling the bumpers is a much easier choice. An interrupt is like a doorbell ringing, with a politician on the doorstep. You can't wait to get rid of the doorbell ringer. You do not perform a bunch of actions in the ISR, like inviting the politician in, making coffee, etc. You set a flag, noting that the interrupt happened.

Then, later (in loop()), you see that the interrupt happened (because the flag is set), and you deal with that fact then.

Of course, this means that you can not have delay() anywhere in your code (and shouldn't anyway). A state machine is what you are trying to develop.
Logged

Offline Offline
God Member
*****
Karma: 17
Posts: 522
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Then, later (in loop()), you see that the interrupt happened (because the flag is set), and you deal with that fact then.

Here's a code snippet that does this:

Code:
volatile boolean triggered = false;

void setup()
{
  attachInterrupt(0, interruptHandler, CHANGE);
}

void loop()
{
  if (triggered)
  {
    // respond to interrupt occurring here
   
    triggered = false; // reset the interrupt
  }
}

void interruptHandler()
{
  triggered = true;
}

You may want to add some additional logic in whether you trigger in response to the interrupt, and under what circumstances you decide to reset the "triggered" flag, but this is the gist of it. Put as little logic as possible in your ISR and leave most of the logic in the main loop. That way the ISR returns as fast as possible.

Keeping logic outside of your ISR is also useful because debugging an ISR is harder, because you can't use Serial.print() from within an ISR. So if you intend to debug an ISR, you can only do it by lighting an LED or maybe writing to an LCD screen, if your project has one.
Logged

Pages: [1]   Go Up
Jump to: