element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Experts, Learning and Guidance
  • Technologies
  • More
Experts, Learning and Guidance
Ask an Expert Forum Help with interrupt problem
  • Blog
  • Forum
  • Documents
  • Leaderboard
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Experts, Learning and Guidance to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 6 replies
  • Subscribers 304 subscribers
  • Views 771 views
  • Users 0 members are here
  • frontpage
Related
See a helpful answer?

Be sure to click 'more' and select 'suggest as answer'!

If you're the thread creator, be sure to click 'more' then 'Verify as Answer'!

Help with interrupt problem

Former Member
Former Member over 11 years ago

Hello,

I got this stepper motor running code and it works fine. However I am trying to write a code to enable me to pause it and turn on led on pin 13, when I press a button and then have it continue running where it left off when I release the button.

I tried by attaching an interrupt but it didn’t work. The modifications I made are in bold. Anyone know what I did wrong?

I’m using an Arduino mega 2560.

Here is the code below. Any help will be appreciated.

 

//////////////////////////////////////////////////////////////////

//Copyright2011 bildr

//Released under the MIT License - Please reuse change and share

//Using the easy stepper with your arduino

//use rotate and/or rotateDeg to controll stepper motor

//speed is any number from .01 -> 1 with 1 being fastest -

//Slower Speed == Stronger movement

/////////////////////////////////////////////////////////////////

#include <avr/interrupt.h>

 

# define LED_PIN 13

# define SWITCH_PIN 5      // pin 18 for interrupt on Arduino mega 2560

 

#define DIR_PIN 2

#define STEP_PIN 3

 

void setup() {

pinMode(DIR_PIN, OUTPUT);

pinMode(STEP_PIN, OUTPUT);

  pinMode(LED_PIN, OUTPUT);

  // switch input

  pinMode(18, INPUT);

  // attach the interrupt on pin 18

  attachInterrupt(SWITCH_PIN, light, LOW);

}

 

void light() {

  digitalWrite(LED_PIN, HIGH);

}

 

void loop(){

 

//rotate a specific number of degrees

rotateDeg(360, 1);

delay(1000);

 

rotateDeg(-360, .1);  //reverse

delay(1000);

 

 

//rotate a specific number of microsteps (8 microsteps per step)

//a 200 step stepper would take 1600 micro steps for one full revolution

rotate(1600, .5);

delay(1000);

 

rotate(-1600, .25); //reverse

delay(1000);

}

 

 

 

void rotate(int steps, float speed){

//rotate a specific number of microsteps (8 microsteps per step) - (negitive for reverse movement)

//speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger

int dir = (steps > 0)? HIGH:LOW;

steps = abs(steps);

 

digitalWrite(DIR_PIN,dir);

 

float usDelay = (1/speed) * 70;

 

for(int i=0; i < steps; i++){

digitalWrite(STEP_PIN, HIGH);

delayMicroseconds(usDelay);

 

digitalWrite(STEP_PIN, LOW);

delayMicroseconds(usDelay);

}

}

 

void rotateDeg(float deg, float speed){

//rotate a specific number of degrees (negitive for reverse movement)

//speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger

int dir = (deg > 0)? HIGH:LOW;

digitalWrite(DIR_PIN,dir);

 

int steps = abs(deg)*(1/0.225);

float usDelay = (1/speed) * 70;

 

for(int i=0; i < steps; i++){

digitalWrite(STEP_PIN, HIGH);

delayMicroseconds(usDelay);

 

digitalWrite(STEP_PIN, LOW);

delayMicroseconds(usDelay);

}

}

  • Sign in to reply
  • Cancel
  • Former Member
    Former Member over 11 years ago

    Hi,

     

    What behavior are you seeing with this code?  From looking at it, it looks like you turn the light on when pin 18 is low but never turn it off again.  Also, how have you got the switch wired to pin 18?

     

    Jeff.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • booran
    booran over 11 years ago

    You'll need to adjust your light() method to handle both turning on and off, for example, you can read the current state of the pin (or make a variable to toggle the state)

     

     

    void light() {

         // Check if pin is high

         if(digitalRead(LED_PIN))

         {

              digitalWrite(LED_PIN, LOW);

         }

         // Pin is low, so turn high

         else

         {

              digitalWrite(LED_PIN, HIGH);

         }

    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 11 years ago in reply to Former Member

    Thanks for your help. Yes, you are right, the light turns on when I turn on the switch 18 and never goes out when I release it. Also the motor only runs when the switch 18 is on and turns continuously very slowly when switch 18 is off.

     

    This is not the result I wanted. I needed the light to turn on and the motor to come to a complete stop when switch 18 is turned on, and the light to go off and the motor to turn when I release the switch.

     

    The switch is wired with one terminal connected to pin 18 and ground with a resistor. The other terminal is connected to the positive power supply.

     

    NB. Switch 18 is the one I'm using to turn on the interrupt for pin 18.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • booran
    booran over 11 years ago in reply to Former Member

    Just to draw a better picture.  Can you verify the description of your circuit here.

     

    You have VCC going to terminal 1 of a switch.  Terminal 2 of the switch is connected directly to pin 18.  Also connected to pin 18 is resister lead 1.  Resistor lead 2 is connected to ground.

     

    If this is the case i would re-visit the mode setting on your interrupt attachment.  When set to HIGH the interrupt will fire whenever the pin is high.  Meaning a long press could result in multiple firings.  I would suggest switching to either CHANGE/RISING/FALLING depending on how much more you want to add to the interrupt handler.  To stop the motor you will need to flag the main loop somehow.  I would recommend adding a boolean that you can set or clear in the interrupt.  Then you can check this boolean in the main loop. 

     

    I don't have the means to build and test this but it should function.  Another option is to setup more of an interrupt based loop so that you have more of an instantaneous start/stop.  The following example would require that you get to the end of the loop (which current looks like 4 seconds) to actually stop.

     

    Example:

     

    boolean runMotor = false;

     

    void setup() {

      pinMode(DIR_PIN, OUTPUT);

      pinMode(STEP_PIN, OUTPUT);

      pinMode(LED_PIN, OUTPUT);

      // switch input

      pinMode(18, INPUT);

      // attach the interrupt on pin 18

      attachInterrupt(SWITCH_PIN, light, CHANGE);

    }

     

    void light() {

      // Check if motor is running

      if(runMotor)

      {

      digitalWrite(LED_PIN, HIGH);

      runMotor = false

      }

      // Motor is not running, start it again

      else

      {

      digitalWrite(LED_PIN, LOW);

      runMotor = true;

      }

    }

     

    void loop(){

     

      if(runMotor)

      {

      //rotate a specific number of degrees

      rotateDeg(360, 1);

      delay(1000);

     

      rotateDeg(-360, .1);  //reverse

      delay(1000);

     

      //rotate a specific number of microsteps (8 microsteps per step)

      //a 200 step stepper would take 1600 micro steps for one full revolution

      rotate(1600, .5);

      delay(1000);

     

      rotate(-1600, .25); //reverse

      delay(1000);

      }

      else

      {

      delay(100);

      }

    }

     

     

    void rotate(int steps, float speed){

      //rotate a specific number of microsteps (8 microsteps per step) - (negitive for reverse movement)

      //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger

      int dir = (steps > 0)? HIGH:LOW;

      steps = abs(steps);

      digitalWrite(DIR_PIN,dir);

      float usDelay = (1/speed) * 70;

      for(int i=0; i < steps; i++){

      digitalWrite(STEP_PIN, HIGH);

      delayMicroseconds(usDelay);

     

      digitalWrite(STEP_PIN, LOW);

      delayMicroseconds(usDelay);

      }

    }

    void rotateDeg(float deg, float speed){

      //rotate a specific number of degrees (negitive for reverse movement)

      //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger

      int dir = (deg > 0)? HIGH:LOW;

      digitalWrite(DIR_PIN,dir);

     

     

      int steps = abs(deg)*(1/0.225);

      float usDelay = (1/speed) * 70;

     

     

      for(int i=0; i < steps; i++){

      digitalWrite(STEP_PIN, HIGH);

      delayMicroseconds(usDelay);

     

     

      digitalWrite(STEP_PIN, LOW);

      delayMicroseconds(usDelay);

      }

    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 11 years ago in reply to booran

    Thanks. I will test it and let you know how it goes.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • booran
    booran over 11 years ago in reply to Former Member

    Some other recommendations i can make (maybe once you get this part working) are

     

    1. Separate each of the rotate() methods and put an if( runMotor ) around each.  This would give you an easy way to lower the time between a button press and stopping the motors (to more like 1 second)

     

    2.  Look into timer interrupts.  You could set up a timer with an interrupt to fire and have that handle rotating the motor.  I would set it up with one rotate() method and just switch through the degrees and speeds you use.  Then you can control whether the timer is running or not when the button is pressed.

     

    3. Incorporate the runMotor variable into the rotate() method itself.  This could provide instantaneous response from a button press, but would require the runMotor variable to be somewhat global...

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube