IRremote to control stepper motor

Hi everyone! I have been relentlessly trying to get this code to work. I probably have 35 hours invested and still have not been able to produce the desired results. If anybody can offer advice, or even criticisms I would greatly appreciate it!

I am wanting to control a stepper motor using an IR remote. I have figured out how to rotate the motor CW and CCW, but have not been able to figure out how to control the speed or rotation while it's in a loop. The way it is now, it will change speed and rotation only after the loop is complete. I want to be able to have control over those adjustments while it's in the loop.

Ultimately I'd like to have it in a "while" loop so that it continues to run until I press the "Mode" button or "Power" button. The names of the functions are named after the icons on the remote I'm using (just a random remote I had laying around).

Also, I'm new to C++ language so any criticisms are greatly appreciated. Thanks in advance!



#include <IRremote.hpp>
#include "BasicStepperDriver.h"


// STEPPER MOTOR
const int STEP_PIN   = 3;    // How many steps to make
const int DIR_PIN    = 4;    // CW or CCW
const int SLEEP      = 5;    // Enable & Disable
const int TONE_PIN   = 6;    // Buzzer


const int MOTOR_STEPS = 200;
const int RPM         = 100;
const int LIM_SWITCH  = 9;
int SPEED_ADJUST      = 0; 
float STROKE_ADJUST   = 1.0; 
 
int MODE              = 1;      
const int MICROSTEPS  = 1;
bool POWER_STATE      = false;  // Has power button been pressed?
const int NOTE_1      = 262;    // Buzzer note

const int IR_RECEIVE_PIN = 2;  // Receive IR signals

// Delay
const int POWER_DELAY            = 1000; // Has the power button been pressed already 
unsigned long PREV_MILLIS        = 0;    // Hold previous millis value
unsigned long PREV_MILLIS_2      = 0;    // Hold previous millis value
const unsigned long DELAY_1      = 1000; // Delay for 1 second
const unsigned long DELAY_2      = 2000; // Delay for 2 seconds
const unsigned long DELAY_3      = 3000; // Delay for 3 seconds
const unsigned long LED_DELAY    = 6000; // Turn on LED for 6 seconds

BasicStepperDriver stepper(MOTOR_STEPS, DIR_PIN, STEP_PIN, SLEEP);

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

void setup() {
 
  stepper.begin(RPM, MICROSTEPS);
  stepper.setEnableActiveState(LOW);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  pinMode(SLEEP, OUTPUT);
  pinMode(TONE_PIN, OUTPUT);
  pinMode(LIM_SWITCH, INPUT_PULLUP);

  Serial.begin(115200);
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
}

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

void loop() {

  if (IrReceiver.decode()) {
    SwitchCase();
  }  
  LimitSwitch();
  
}

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


void SwitchCase() {
  
  switch (IrReceiver.decodedIRData.command) {

    case 0xC:
      Power();
      break;
        
    case 0x8:
      HL();
      break;
        
    case 0x7:
      TwoArrows();
      break;
        
    case 0x6:
      Clock();
      break;
        
    case 0x1C:
      VolumeUp();
      break;
        
    case 0x15:
      VolumeDown();
      break;        
  }
  IrReceiver.resume(); // Enable receiving of the next value 
}

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

void Power() {
  
  if (millis() - PREV_MILLIS >= POWER_DELAY) {
    if (POWER_STATE == 1) {
      POWER_STATE = 0;               
      Serial.println("Off");
    }
    else {    
      POWER_STATE = 1;                
      Serial.println("On");
    }
    PREV_MILLIS = millis();           
  }
}    
    
///////////////////////////////////////////////////////////////

void HL() {
  
  if (POWER_STATE == 1) {
    ChangeMode();
  }   
}

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

void TwoArrows() {
  
  if (POWER_STATE == 1) {
    SPEED_ADJUST += 5;    
    if ( SPEED_ADJUST >= 200 ) {    
      SPEED_ADJUST = 200;
      IrReceiver.stop();
      tone(TONE_PIN, NOTE_1, 100);
      delay(100);
      IrReceiver.start(100000);
    }
  }
  Serial.print("SPEED_ADJUST = "); 
  Serial.println(SPEED_ADJUST); 
}

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

void Clock() {
  
  if (POWER_STATE == 1) {
    SPEED_ADJUST -= 5;    
    if ( SPEED_ADJUST <= 0 ) {    
      SPEED_ADJUST = 0;
      IrReceiver.stop();
      tone(TONE_PIN, NOTE_1, 100);
      delay(100);
      IrReceiver.start(100000);
    } 
  }
  Serial.print("SPEED_ADJUST = ");    
  Serial.println(SPEED_ADJUST);       
}

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

void VolumeUp() {
  
  if (POWER_STATE == 1) {
    STROKE_ADJUST += 0.05;          
    if ( STROKE_ADJUST >= 2.0 ) {    
      STROKE_ADJUST = 2.0;
      IrReceiver.stop();
      tone(TONE_PIN, NOTE_1, 100);
      delay(100);
      IrReceiver.start(100000);
    } 
  }
  Serial.print("STROKE_ADJUST = ");
  Serial.println(STROKE_ADJUST);
}

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

void VolumeDown() {
  
  if (POWER_STATE == 1) {   
    STROKE_ADJUST -= .05;     
    if ( STROKE_ADJUST <= 0.05 ) {    
      STROKE_ADJUST = .05;
      IrReceiver.stop();
      tone(TONE_PIN, NOTE_1, 100);
      delay(100);
      IrReceiver.start(100000);
    }
    Serial.print("STROKE_ADJUST = ");      
    Serial.println(STROKE_ADJUST);
  }  
}

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

void ChangeMode() {
  
  IrReceiver.resume();
  
  if (MODE == 1) {
    for (int i = 0; i < 5; i ++) {       
      PREV_MILLIS_2 = millis() + DELAY_1;
      while (millis() < PREV_MILLIS_2) {
        stepper.disable();
      } 
      if (IrReceiver.decode()) {
        if (POWER_STATE == 1) {
          if (IrReceiver.decodedIRData.command == 0x8) {
            Serial.print("Change Mode ");
          }
          if (IrReceiver.decodedIRData.command == 0x7) { 
             Serial.println("Speed Adjust UP");         
            SPEED_ADJUST += 5;    
            if ( SPEED_ADJUST >= 200 ) {    
              SPEED_ADJUST = 200;
            }
          }
          if (IrReceiver.decodedIRData.command == 0x6) {    
            Serial.println("Speed Adjust DOWN");     
            SPEED_ADJUST -= 5;    
            if ( SPEED_ADJUST <= 0 ) {    
              SPEED_ADJUST = 0;
            } 
          }
        }
        IrReceiver.resume();
      }
      
      // CW Rotation // 
      stepper.enable();
      stepper.setRPM(SPEED_ADJUST);
      Serial.print("SPEED ADJUST = ");
      Serial.println(SPEED_ADJUST);                       
      stepper.rotate(150 + STROKE_ADJUST); 
                
      // CCW Rotation //
      PREV_MILLIS_2 = millis() + DELAY_1;
      while (millis() < PREV_MILLIS_2) {
        stepper.disable();
      }    
      stepper.enable();
      stepper.setRPM(SPEED_ADJUST); 
      Serial.print("SPEED ADJUST = ");
      Serial.println(SPEED_ADJUST); 
      stepper.rotate(140 + STROKE_ADJUST);
      stepper.disable();
    }
  }


  if (MODE == 2) {
    Serial.println(""); 
    Serial.print("MODE = "); 
    Serial.println(MODE);     
    for (int i = 0; i < 5; i ++) {
      PREV_MILLIS_2 = millis() + DELAY_1;
      while (millis() < PREV_MILLIS_2) {
        stepper.disable();
      }      
      // CCW Rotation  
      stepper.enable();        
      stepper.setRPM(SPEED_ADJUST);                 
      stepper.rotate(-125 * STROKE_ADJUST);
      
      // CW Rotation 
      PREV_MILLIS_2 = millis() + DELAY_1;
      while (millis() < PREV_MILLIS_2) {
        stepper.disable();
      }
      stepper.enable();
      stepper.setRPM(SPEED_ADJUST);                 
      stepper.rotate(100 * STROKE_ADJUST);
      
      // CW Rotation 
      PREV_MILLIS_2 = millis() + DELAY_1;
      while (millis() < PREV_MILLIS_2) {
        stepper.disable();
      }
      stepper.enable();
      stepper.setRPM(SPEED_ADJUST);                
      stepper.rotate(140 * STROKE_ADJUST);
      stepper.disable();
    }
  }
  if (MODE == 2) {
    MODE = 0;
  } 
  MODE ++;
}


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

void LimitSwitch() {
  
  if (digitalRead(LIM_SWITCH) == LOW) {
    digitalWrite(SLEEP, HIGH);
    Serial.println("*** LIMIT SWITCH ACTIVATED ***");
    for (int i = 0; i < 10; i ++) {
      IrReceiver.stop();
      tone(TONE_PIN, NOTE_1, 1000);
      delay(1000);
      IrReceiver.start(100000);
    }
    delay(30000);
  }
}

You have a loop() function that loops continuously. Why not use it?

Hi you nead to remove yours delay in your program we know
When delay cmd exucite ardune stack this time
So you use counter delay
Like
Int k=0
K++
If(k=1000){
Do som thing
}

You have protus to run this file

I'm trying to keep the code as organized as possible, as long as it makes sense. It still goes through the actual "void loop()" function repeatedly.

So instead of millis() use a variable instead? Is the "(k=1000)" the equivalent of 1 second (like millis())? If I'm not mistaken, I reviewed the pins that are affected by specific timers (as I understand on a arduino nano there are 3) and chose pins for my DRV8825 stepper driver that were not on the same pins affected by "millis()".

Again, I've tried so many different things that I could have inadvertently changed it. The millis() seems to work properly in the code (verified with Serial.print(millis())).

You use protus ?
When program is for loop his complte loop and than next
Limi swith you define in void loop
So if limt swith low your remote wass not working almost 40send and your remote not wokring so you just one time skipp limmit swith function and run again and check

Like little bit example

Ir ricve on

If ir recve ==1
Led on

If ir rcve ==2
Led of

If button press

For i =0 i<10 i++
So you use here 1 send delay
So when i is not equl to 10 your progerm here run
Not got if ir ricve
I hope you under stand

Ok, yes I understand what you are saying. You are still referring to removing the millis() function and using a "for" loop instead and having it countdown the milliseconds until it will run the next block of code.

Are you suggesting that the millis() delay is somehow conflicting with something else which is causing the code not to work as expected? Or are you suggesting that it's best to do it that way in general?

Thanks for your replies!