Infrared Remote: Interrupting a loop by pressing a button

Hello,

It's my first time using a forum, hope I do ok.

Ok, so my Arduino setup has 2 stepper motors which I am controlling with an infrared remote.

I've coded the motors in a loop so that one motor moves one step, then the 2nd moves another step, until both motors have made one full revolution, like so...

                     for (int i=0; i<2048; i++){ // Set loop for 2 motors each rotating 1 full circle clockwise
                        small_stepper1.setSpeed(500); //Max seems to be 700
                        small_stepper2.setSpeed(500); //Max seems to be 700
                        Steps2Take  =  1;  // Rotate CW
                        small_stepper1.step(Steps2Take);
                        small_stepper2.step(Steps2Take);
                        delay(1);
                      }

I've coded the motor's to revolve clockwise when I press one button and anti-clockwise when I press the another button.

I'm now trying and failing to insert a 3rd button press which stops the motors before the full rotation. For example, something like this...

                     for (int i=0; i<2048; i++){ // Set loop for 2 motors each rotating 1 full circle clockwise
                        small_stepper1.setSpeed(500); //Max seems to be 700
                        small_stepper2.setSpeed(500); //Max seems to be 700
                        Steps2Take  =  1;  // Rotate CW
                        small_stepper1.step(Steps2Take);
                        small_stepper2.step(Steps2Take);
                        delay(1);
                        irrecv.decode(&results);
                        if (results.value == 0xFF18E7) {
                          i = 2048;
                        }
                      }
                      break;

As you might be able to tell, I'm not that used to IR programming code at the mo! Hope one of you can help. Many thanks. Here's the full code...

#include "Stepper.h"
#include "IRremote.h"

/*----- Variables, Pins -----*/
#define STEPS  32   // Number of steps per revolution of Internal shaft
int  Steps2Take;  // 2048 = 1 Revolution
int receiver = 9; // Signal Pin of IR receiver to Arduino Digital Pin 6

/*-----( Declare objects )-----*/
// Setup of proper sequencing for Motor Driver Pins
// In1, In2, In3, In4 in the sequence 1-3-2-4
// In5, In6, In7, In7 in the sequence 5-7-6-8

Stepper small_stepper1(STEPS, 5, 7, 6, 8);
Stepper small_stepper2(STEPS, 1, 3, 2, 4);
IRrecv irrecv(receiver);    // create instance of 'irrecv'
decode_results results;     // create instance of 'decode_results'

void setup()
{ 
  irrecv.enableIRIn(); // Start the receiver
}

void loop()
{
if (irrecv.decode(&results)) // have we received an IR signal?

  {
    switch(results.value)

    {

      case 0xFF30CF: // Button 1 pressed
                      for (int i=0; i<2048; i++){ // Set loop for 2 motors each rotating 1 full circle clockwise
                        small_stepper1.setSpeed(500); //Max seems to be 700
                        small_stepper2.setSpeed(500); //Max seems to be 700
                        Steps2Take  =  1;  // Rotate CW
                        small_stepper1.step(Steps2Take);
                        small_stepper2.step(Steps2Take);
                        delay(1);
                      }
                      break;


      case 0xFF7A85: // Button 2 pressed
                      for (int i=0; i>-2048; i--){ // Set loop for 2 motors each rotating 1 full circle anti-clockwise
                      small_stepper1.setSpeed(500); //Max seems to be 700
                      small_stepper2.setSpeed(500); //Max seems to be 700
                      Steps2Take  =  -1;  // Rotate CCW
                      small_stepper1.step(Steps2Take);
                      small_stepper2.step(Steps2Take);
                      delay(1);
                      } 
                      break;
                      
    }
    
      irrecv.resume(); // receive the next value
  }  


}/* --end main loop -- */

That should really be:

                        if (irrecv.decode(&results) && results.value == 0xFF18E7) {
                         irrecv.resume(); 
                         break;  // Exit the 'for' loop
                        }

You would also need an "irrecv.resume();" before entering the 'for' loop. Decode() won't do anything until the input is resumed.

I feel like you should separate the reading of the IR remote from the timing and counting of steps. Perhaps something like this (compiles, not tested):

#include "Stepper.h"
#include "IRremote.h"

#define MSK_CW              0b00000001
#define MSK_CCW             0b00000010
#define MSK_STOP            0b00000100

#define K_STEP_CW           1
#define K_STEP_CCW          -1

#define TM_STEP_INTERVAL    1000ul      //# of microseconds between steps

byte
    bButtonFlag;

/*----- Variables, Pins -----*/
#define STEPS  32   // Number of steps per revolution of Internal shaft
int  Steps2Take;  // 2048 = 1 Revolution
int receiver = 9; // Signal Pin of IR receiver to Arduino Digital Pin 6

/*-----( Declare objects )-----*/
// Setup of proper sequencing for Motor Driver Pins
// In1, In2, In3, In4 in the sequence 1-3-2-4
// In5, In6, In7, In7 in the sequence 5-7-6-8

Stepper small_stepper1(STEPS, 5, 7, 6, 8);
Stepper small_stepper2(STEPS, 1, 3, 2, 4);

IRrecv irrecv(receiver);    // create instance of 'irrecv'
decode_results results;     // create instance of 'decode_results'

void setup()
{
    irrecv.enableIRIn(); // Start the receiver
    //set stepper speed
    small_stepper1.setSpeed(500); //Max seems to be 700
    small_stepper2.setSpeed(500); //Max seems to be 700
    bButtonFlag = 0;
    
}//setup

void loop()
{
    StepperStateMachine();

    if (irrecv.decode(&results)) // have we received an IR signal?
    {
        switch(results.value)
        {
            case    0xFF30CF: // Button 1 pressed
                //all we do when we get this code is set the CW button flag mask
                //but only if there's not a STOP flag set
                if( !(bButtonFlag & MSK_STOP ) )
                    bButtonFlag |= MSK_CW;
                                
            break;
            
            case    0xFF7A85: // Button 2 pressed
                //all we do when we get this code is set the CCW button flag mask
                //but only if there's not a STOP flag set
                if( !(bButtonFlag & MSK_STOP ) )
                    bButtonFlag |= MSK_CCW;
                
            break;

            case    0xFF18E7:
                //set the stop flag
                bButtonFlag |= MSK_STOP;            
                
            break;
            
        }//switch
    
        irrecv.resume(); // receive the next value
        
    }//if  

}//loop

// state names
#define WAIT_BUTTON         0
#define STEP_CW             1
#define STEP_CCW            2
//
void StepperStateMachine( void )
{
    static unsigned int
        nStepCount = 0;
    static unsigned long
        timeStepper = 0;
    unsigned long
        timeNow;
    static byte
        stateStep = WAIT_BUTTON;

    //is it time for a step?
    timeNow = micros();
    if( (timeNow - timeStepper) < TM_STEP_INTERVAL )
        return; //no, just return

    //yes; set up to time next step
    timeStepper = timeNow;

    //if a stop IR command was received...
    if( bButtonFlag & MSK_STOP )
    {
        //...clear the flag and set the state to wait for a button
        bButtonFlag &= ~MSK_STOP;
        stateStep = WAIT_BUTTON;
        
    }//if
    
    switch( stateStep )
    {
        case    WAIT_BUTTON:
            //if CW button was pressed...
            if( bButtonFlag & MSK_CW )
            {
                //clear the flag then set that state; steppers will start turning CW
                bButtonFlag &= ~MSK_CW;
                stateStep = STEP_CW;
                
            }//if
            else if( bButtonFlag & MSK_CCW )
            {
                //CCW pressed; clear the flag then set that state; steppers will start turning CCW
                bButtonFlag &= ~MSK_CCW;
                stateStep = STEP_CCW;
                
            }//else
            
        break;

        case    STEP_CW:
            //limit rotation to 2048 steps
            if( nStepCount < 2048 )
            {
                //one step CW
                small_stepper1.step( K_STEP_CW );
                small_stepper2.step( K_STEP_CW );

                //increment step counter
                nStepCount++;                
                
            }//if
            
        break;

        case    STEP_CCW:
            //limit rotation back to zero point
            if( nStepCount > 0 )
            {
                //one step CCW
                small_stepper1.step( K_STEP_CCW );
                small_stepper2.step( K_STEP_CCW );

                //decrement step counter
                nStepCount--;                
                
            }//if
            
        break;
        
    }//switch
    
}//StepperStateMachine

BlackFin, that's much more eloquent code than mine and... it works!

I need to now enter a kill switch (from a force sensor) and can see exactly where I need to make an amendment.

Thanks very much for the time you put in.

johnwasser, thank you for teaching me about the irrecv.ressume command. I couldn't quite get it to work though, I think I miss read what you were saying. This is how mine looked...

      case 0xFF30CF: // Button 1 pressed
                      irrecv.resume();
                      for (int i=0; i<2048; i++){ // Set loop for 2 motors each rotating 1 full circle clockwise
                        small_stepper1.setSpeed(500); //Max seems to be 700
                        small_stepper2.setSpeed(500); //Max seems to be 700
                        Steps2Take  =  1;  // Rotate CW
                        small_stepper1.step(Steps2Take);
                        small_stepper2.step(Steps2Take);
                        delay(1);
                        if (irrecv.decode(&results) && results.value == 0xFF18E7) {
                          irrecv.resume();
                          break; //Exit the loop
                        }
                      }
                      break;