Stepper motor not making the desired degree of rotation

hi gurus, I'm trying to control the stepper motor(step angle setting 1.8 degree) to rotate back and forth 180 degree at 30rpm, I observed that the motor is not making the full 180 degree move (around 160 degree). Appreciate your suggestion.

#define Pulse 9
#define dir_pin 8
#define home_switch 3
const int STEPS_PER_REV = 200;


void setup() {
  pinMode(Pulse,OUTPUT);
  pinMode(dir_pin,OUTPUT);
  pinMode(home_switch, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Started !");
}


void loop() {
  
  if (Serial.available()) {
    String data_from_display = "";
    delay(30);
    while(Serial.available()) {
      data_from_display += char(Serial.read());
    }
    sendData(data_from_display);
  }
}

void Start() {
  Serial.println("START invert");
  for (int x = 1; x<=30 ; x++)
  {
  // Set motor direction clockwise
    digitalWrite(dir_pin,LOW); 
    
    // Spin motor one rotation slowly
    for(int i = 0; i < (STEPS_PER_REV/2); i++) {
      digitalWrite(Pulse,HIGH); 
      delayMicroseconds(5000); 
      digitalWrite(Pulse,LOW); 
      delayMicroseconds(5000); 
    }
    
    // Set motor direction counterclockwise
    digitalWrite(dir_pin,HIGH);
    
    // Spin motor two rotations quickly
    for(int i = 0; i < (STEPS_PER_REV/2); i++) {
      digitalWrite(Pulse,HIGH);
      delayMicroseconds(5000);
      digitalWrite(Pulse,LOW);
      delayMicroseconds(5000);
    }
    Serial.println(x);
    if (Serial.available()) {
      String data_from_display = "";
      //delay(30);
      while(Serial.available()) {
        data_from_display += char(Serial.read());
      }
      if (data_from_display=="S")
        return;
    }
  }
    
}
void Homing() {
  while (digitalRead(home_switch))
    {  // Do this until the switch is activated   
     digitalWrite(dir_pin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
     digitalWrite(Pulse,HIGH); 
     delayMicroseconds(5000); 
     digitalWrite(Pulse,LOW); 
     delayMicroseconds(5000);   
   }
  while (!digitalRead(home_switch)) 
  { // Do this until the switch is not activated
     for (int i =0; i<5; i++)
     {
      digitalWrite(dir_pin, LOW);  // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(Pulse,HIGH); 
      delayMicroseconds(5000); 
      digitalWrite(Pulse,LOW); 
      delayMicroseconds(5000);
      }
   }  
}

void sendData(String data_from_display) {
  if (data_from_display == "START") {
    Start();
  }
  if (data_from_display == "HOMING") {
    Homing();
  }
}

You have several functions that are NEVER called, so the compiler discards them. Why did you bother if you are not going to use the functions?

When changing from one direction to the other, good technique suggests you should slow the mechanical elements to stop moving before jumping the other direction.

The likely outcome will be skipped steps.

This also applies to the mass of the attached mechanism.

The first approach to address this is using an s-curve to ease in and out of the transitions.

The other might be to ensure that the chosen step interval is physically possible,

What happens when you try and do that a lot slower than 30RPM? Do you still get an incomplete amount of movement?

Why are you using

And not ?

delay (5);

That is way too fast anyway.

Classic mistake. If you have something in the buffer then read it all. This will fail because the loop function will run much faster than data can be read in, especially as slow as 9600 Bauds.

Are you using a proper regulating stepping motor driver? If so you can increase the speed of the motor by supplying it with a higher voltage like 24V. The extra voltage allows the current to get into the motor coils quicker than it would with a lower voltage.

thanks for your advise. The requirement is to invert the test tube 30 times per minute. How do I use the s-curve?

Use a library like ACCELSTEPPER that allows you to set a basic acceleration and deceleration profile.

Or if you’re keen, and know what you’re doing- it’s not too hard to write t your own custom speed profile.

Can I use the library you mentioned with this stepper driver?

image

Almost any stepper driver wil work with AccelStepper, it’s configurable when you create the driver ‘instance’ to support most methods.
Your use of STEP-DIR pins is very standard,

The only ‘real’ limitation to look out for is the maximum step rate on lower clock speed processors.

1 Like

Which functions do you think are never called? I don't see any ...

30rpm are 100 steps/sec - that's what @by42 does with two delays of 5000µs for each step. Usually that's no problem for a stepper - even without acceleration / deceleration.

@by42 Please tell a little bit more about your setup - Which board, which stepper. And is the stepper loaded? Your driver let me assume a bigger stepper. Things may be different then.
Insert a short delay when changing direction ( e.g. 100ms).

Below is the motor specs. Could it due to motor undersize? the test tube is containing max 200ml water. The setup is illustrated in the CAD drawing. Thank you @MicroBahner


image
image

It was late and hot and the AC quit working!