Stepper Motor IR Control 28BYJ-48

This is my first post so bear with me, I have set up a test stepper motor 28byj-48 with controller board which is working fine, I am using an IR with its remote, it goes forward and backward as I want, but I have two problems I hope someone can help me with.

Problem 1. I send it forward , it travels the expected steps, but if I press the forward command again by mistake it will go on again until it completes the set amount of steps, I have tried stopping the motor by IR command but it wont stop until it has completed. which leads me onto the Second problem.

Problem 2.

I need to be able to stop the motor by sending a signal/command which act as a break.

My code thus far.

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

/*----- Variables, Pins -----*/
#define STEPS  20 // Number of steps per revolution of Internal shaft
int  Steps2Take;  // 2048 = 1 Revolution
int receiver = 6; // 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

Stepper small_stepper(STEPS, 8, 10, 9, 11);
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)

    {
                //   break;
       case 0xD7E84B1B: //Press "OK" Turn off Motor
                     digitalWrite(8,LOW);
                     digitalWrite(9,LOW);
                     digitalWrite(10,LOW);
                     digitalWrite(11,LOW);  


      case 0xFF629D: // UP button pressed
                      small_stepper.setSpeed(400); //Max seems to be 700
                      Steps2Take  =  2048;  // Rotate CW
                      small_stepper.step(Steps2Take);
                     // delay(1000);                              
                     digitalWrite(8,LOW);
                     digitalWrite(9,LOW);
                     digitalWrite(10,LOW);
                     digitalWrite(11,LOW);              
                     break;
     
     case 0xFFA857: // DOWN button pressed case 0xA3C8EDDB:
     
                      small_stepper.setSpeed(400);
                      Steps2Take  =  - 2048;  // Rotate CCW
                      small_stepper.step(Steps2Take);
                     //delay(1000);
                     digitalWrite(8,LOW);
                     digitalWrite(9,LOW);
                     digitalWrite(10,LOW);
                     digitalWrite(11,LOW);  
                     break;                 
     


                       
                      break;
             
                      
    }
    
      irrecv.resume(); // receive the next value
  }  
  
}/* --end main loop -- */

Your program is doing exactly what you told it to do- when you press the down button it goes off and does the specified number of steps. Your program tells it to complete these steps before it ever reads the IR code again.

What your loop() needs to is read the IR code, decide which direction has been selected then do only 1 step in that direction before checking the IR code again. Your program keeps a counter of the number of steps to go so you dont keep going forever. That way you can cancel at any time.

This is called a finite state machine- its basically a list of rules that say “if the current state is X and the desired state is Y then do A,B & C”. You need to have a rule for each possible combination of present and desired states. In your case there 3 possible states (forward,reverse and stopped) and 3 possible inputs (UP button, DOWN button and STOP button) so you need a set of logic rules to determine what to do in each state for each input. You may find it easier to draw a grid on paper with states on the side and inputs up the top then fill in each square with what action is required for that combination.

Basics of moving it one step at a time

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

    // set value of Steps2Take depending on command
   };

   if (Steps2Take>0) {

      small_stepper.step(1);
      Steps2Take=Steps2Take-1;
   };
   if (Steps2Take<0) {

      small_stepper.step(-1);
      Steps2Take=Steps2Take+1;
   };
    if (Steps2Take == 0) {
     //stop motor
      
   };
   irrecv.resume(); // receive the next value

}

You will need to devise logic to determine how to respond to commands- for example if the servo is moving UP and you press DOWN does it stop or move down. If its moving UP and you press the UP again does it go another turn or just ignore. (Hint- you can use the value of Steps2Take to determine the current state)