Stepper Motor not moving

Hi, I am trying to run a stepper motor to a given position from home position. First, the motor goes to the home position (I did this using a hall sensor, where at a specific point the sensor becomes LOW and the motor stops cause I set the speed(0) using the interrupt function. till here works fine. after when I enter values from 1 to 24 since I have limits and each value is equal to 200 steps. so if I give 3, 3 * 200 = 600 steps which is stored in destination variable. till here everything works fine. but the motor won't move. I don't know what to do. Can anyone help me? (Please feel free to ask me for more information about the setup or logic)

the code:

#include <AccelStepper.h> //accelstepper library

#define dirPin 4    // Direction pin
#define stepPin 3   // Pulse/Step pin
#define enPin 5     // Enable pin

const unsigned long event_1 = 10000;

const int hallPin = 2;
int countHP = 0;


const float stepAngle = 1.8;                      // Stepper motor step angle
const int stepsPerRevolution = 1600;              // Steps required for 360 degree rotation



bool homeposition = false; 



AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin, enPin);

void setup()
{
  pinMode(hallPin, INPUT_PULLUP); // internal pullup resistor (debouncing)
  
  attachInterrupt(digitalPinToInterrupt(hallPin), hallValueChanged, FALLING);   //do not change it to 'CHANGE' 
  
  Serial.begin(9600); //defining some baud rate
  //---------------------------------------------------------------------------

  stepper.setMaxSpeed(1500);   
  stepper.setAcceleration(1000);
  stepper.setSpeed(500);
  stepper.moveTo(50000);
  //---------------------------------------------------------------------------

}

void loop()
{
  if (homeposition)
  {
    if (homeposition) 
    {
      stepper.setCurrentPosition(0);
      Serial.println("Homing Completed");
      Serial.println("");
      while (Serial.available() > 0) 
      {
        int serialValue = Serial.parseInt();  // Read position from Serial Monitor
        Serial.print("got the value");
        moveToPosition(serialValue);
      }
    }
  }
  else
  {
    if (countHP == 0)
    {
      stepper.run(); 
      homePosition();
    }
  }  

}


void moveToPosition(int value) 
{
  int stepsPerLine = 200;
  int homeValue = 12;
  int currentPosition = homeValue;
  if (value)
  {
    if (value)
    {
      int testPosition = value;
      if (0 <= testPosition && testPosition <= 24)
      {
        Serial.print("HII");
        if (currentPosition < testPosition)
        {
          //direction = 0;
          Serial.print("Clockwise");
          int destination = testPosition - currentPosition;
          destination = destination * stepsPerLine;
          stepper.setMaxSpeed(1500);   
          stepper.setAcceleration(1000);
          stepper.setSpeed(500);
          stepper.moveTo(destination);
          
          currentPosition = testPosition;
        }
        if (currentPosition > testPosition)
        {
          //direction = 1;
          Serial.print("AntiClockwise");
          int destination = currentPosition - testPosition;
          destination = destination * stepsPerLine;
          stepper.setMaxSpeed(1500);   
          stepper.setAcceleration(1000);
          stepper.setSpeed(500);
          stepper.moveTo(-destination);
          
          currentPosition = testPosition;
        }
      }
    }
  }
}


void homePosition()
{
  if(homeposition == true && countHP == 0 )
  {    
    stepper.setSpeed(0);
    countHP = +1;
  }
}

void hallValueChanged()
{
  homeposition = true;
}

While the code will compile and run, it's better to avoid similar naming for variables and functions to reduce potential confusion and errors in future development or when others are reading the code. Consider renaming either the homeposition function or the homeposition variable for clarity.


homeposition (the variable - may be call it atHome) should be made volatile as you used it both in the interrupt and in the loop

why do you have this double check?

And why do you need this ISR, you could just poll the sensor as you call run() repeatedly

1 Like

Before there used to be a print function just to display a message. Now it was not required I removed the ELSE part, thought to remove IF as well, but since the code is present

I just left it that way cause it didnt effect anything.

and and I could you tell me more about the 'Poll'.

I want to read the value of the sensor all the time and I want the change of the sensor value of should effect the running of the code (which is running the motor). So I thought using ISR is the appropriate thing.

The ISR is not a bad idea in general but it just sets a flag and your loop does not do much, so instead of checking the flag in the loop, just check the pin status. That will make the code easier.

you might benefit from studying state machines. Here is a small introduction to the topic: Yet another Finite State Machine introduction

1 Like

Ok. I will try that. Thanks for you help.

Apart from the problems @J-M-L pointed out, there are some other big problems in your code, and you should study how Accelstepper works :wink:

  • When your hall sensor is aktivated, homeposition is set to true, but it is never reset to 'false'
  • The same is true for countHP. It is set to '1' in homePosition(), but never reset to 0.
  • This leads to the fact, that stepper.run() in loop() is never executed after the first activation of the hall sensor, so the motor cannot move after that.
int homeValue = 12;
int currentPosition = homeValue;

This means, currentPosition is always set to '12' - why? What does currentPosition mean - obviously not really the current position.

Regarding Accestepper:

  • Don't ever use stepper.setSpeed() if you are working with stepper.run(), because stepper.run() uses setSpeed internally.
  • This AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin, enPin); is strange, because you cannot set the enablePin in the constructor.