Accelstepper for Window Roller Blinds

Hello,
I have the following code supposed to move window roller blinds using two stepper motors. Using three states are which are Fold, unfold, and stop. which are not working properly

But the issue is when I press the fold. it moves forward successfully. then I pressed the stop in the middle of the moving forward. it actually stops

if I pressed the unfold it moves in the folding direction for a while then it unfolds then stops

can you detect where is the issue

// Include the AccelStepper library, which provides high-level features for controlling stepper motors
#include <AccelStepper.h>

// Define the pin connections for the first stepper motor
#define MOTOR1_PIN1 3
#define MOTOR1_PIN2 4

// Define the pin connections for the second stepper motor
#define MOTOR2_PIN1 5
#define MOTOR2_PIN2 6

// Define the pins for the fold, unfold, and stop buttons
#define FOLD_BUTTON_PIN 2
#define UNFOLD_BUTTON_PIN 18
#define STOP_BUTTON_PIN 19

#define FULL_COVERAGE_STEPS 1200

// Create instances of the AccelStepper class for each stepper motor.
// The first parameter (1) indicates we're using a driver, which means step and direction are controlled by two pins.
// The next two parameters are the pins for step and direction respectively.
AccelStepper stepper1(1, MOTOR1_PIN1, MOTOR1_PIN2);
AccelStepper stepper2(1, MOTOR2_PIN1, MOTOR2_PIN2);

// Define an enumeration (enum) to hold the different states that the system can be in
enum State {
  IDLE_SYS,  // The system is idle and waiting for a command
  FOLDING,   // The system is in the process of folding
  UNFOLDING  // The system is in the process of unfolding
};

// Create a variable to hold the current state of the system, and initialize it to IDLE_SYS
State currentState = IDLE_SYS;
long currentPosition1 = 0;
long currentPosition2 = 0;

void setup() {
  // Begin serial communication at a baud rate of 9600 for debugging and interaction with the serial monitor
  Serial.begin(9600);

  // Set the initial position of the stepper motor
  stepper1.setCurrentPosition(0);
  stepper2.setCurrentPosition(0);

  // Set the maximum speed (steps per second) and acceleration (steps per second per second) for each stepper motor
  stepper1.setMaxSpeed(1000.0);
  stepper1.setAcceleration(500.0);
  stepper2.setMaxSpeed(1000.0);
  stepper2.setAcceleration(500.0);

  // Set the mode of the fold, unfold, and stop button pins to INPUT so that the state of the pins can be read
  pinMode(FOLD_BUTTON_PIN, INPUT);
  pinMode(UNFOLD_BUTTON_PIN, INPUT);
  pinMode(STOP_BUTTON_PIN, INPUT);
}

void loop() {
  // Use a switch statement to do different things depending on the current state of the system
  switch (currentState) {
    case IDLE_SYS:
      // Check if the fold button is pressed
      if (digitalRead(FOLD_BUTTON_PIN) == HIGH) {
        // Stop any previous movements and prepare to move the stepper motors three full rotations (600 steps)
        stepper1.stop();
        stepper2.stop();

        // If the fold button is pressed, move the stepper motors three full rotations (600 steps) in the same direction
        stepper1.moveTo(FULL_COVERAGE_STEPS - currentPosition1);
        stepper2.moveTo(FULL_COVERAGE_STEPS - currentPosition2);

        // Update the current state to FOLDING
        currentState = FOLDING;

        // Print a message to the serial monitor indicating that the folding process has started
        Serial.println("Folding started...");
      }
      // Check if the unfold button is pressed
      else if (digitalRead(UNFOLD_BUTTON_PIN) == HIGH) {
        // Stop any previous movements and prepare to move the stepper motors three full rotations in the reverse direction (-600 steps)
        stepper1.stop();
        stepper2.stop();

        // If the unfold button is pressed, move the stepper motors three full rotations (600 steps) in the opposite direction
        stepper1.moveTo(0 - currentPosition1);
        stepper2.moveTo(0 - currentPosition2);

        // Update the current state to UNFOLDING
        currentState = UNFOLDING;

        // Print a message to the serial monitor indicating that the unfolding process has started
        Serial.println("Unfolding started...");
      }
      break;

    case FOLDING:
      // If the system is currently folding, run the stepper motors in the same direction
      if ((stepper1.distanceToGo() != 0 && stepper2.distanceToGo() != 0) ||
          (digitalRead(STOP_BUTTON_PIN) != HIGH)) {
        stepper1.run();
        stepper2.run();
      } else {
        // If the folding process is complete, update the current state to IDLE_SYS
        currentState = IDLE_SYS;

        // Print a message to the serial monitor indicating that the folding process has been completed
        Serial.println("Folding completed...");
      }

      // Check if the stop button is pressed
      if (digitalRead(STOP_BUTTON_PIN) == HIGH) {
        currentPosition1 = stepper1.currentPosition();
        currentPosition2 = stepper2.currentPosition();

        // If the stop button is pressed, stop the stepper motors
        stepper1.stop();
        stepper2.stop();

        // Update the current state to IDLE_SYS
        currentState = IDLE_SYS;

        // Print a message to the serial monitor indicating that the operation has been stopped by the user
        Serial.println("Operation stopped by user...");
      }
      break;

    case UNFOLDING:
      // If the system is currently unfolding, run the stepper motors in the opposite direction
      if ((stepper1.distanceToGo() != 0 && stepper2.distanceToGo() != 0) ||
           ( digitalRead(STOP_BUTTON_PIN) != HIGH)) {
        stepper1.run();
        stepper2.run();
      } else {
        // If the unfolding process is complete, update the current state to IDLE_SYS
        currentState = IDLE_SYS;

        // Print a message to the serial monitor indicating that the unfolding process has been completed
        Serial.println("Unfolding completed...");
      }

      // Check if the stop button is pressed
      if (digitalRead(STOP_BUTTON_PIN) == HIGH) {
        currentPosition1 = stepper1.currentPosition();
        currentPosition2 = stepper2.currentPosition();

        // If the stop button is pressed, stop the stepper motors
        stepper1.stop();
        stepper2.stop();

        // Update the current state to IDLE_SYS
        currentState = IDLE_SYS;

        // Print a message to the serial monitor indicating that the operation has been stopped by the user
        Serial.println("Operation stopped by user...");
      }
      break;
  }
}

Time for debugging. You can use the combination of Serial.print placed in strategic places, printing key variables, and serial monitor. That way You can discover what the code is actually doing.
That technic was used during my entire career and served me well.
Dry reading code is a time consuming way having not much to go for.

I have been struggling for a week now, trying to figure out what's wrong
read the documentation multiple times

I feel like I am missing something

Your post adds no useful information and no responce to post #2.

[edit]
Any button you push more than one time will act as folding, unfolding and stop (they need a debounce). Each button needs to have a flag... "if unfold was pressed then unfold, but do not stop and do not fold and do not unfold again"

Thanks a lot for your reply.
I am afraid it's not the case. As I handled the debounce and the issue still exists

I found solution
The issue was that the stop() function. is not actually stopping the motors behind the scenes.
it still saves the steps and draws current.

The solution is just to set my new position as my current position inside the stop function for folding and unfolding

I hope this helps

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.