Stepper running at slower rpm in reverse direction

@Robin2: Please help

I am using NEMA34 8.5Nm Stepper Motor with DM860T driver with 6amp current, 800 pulse/rev, 350W / 48V power supply.

Motor rpm in forward direction are 58 while in reverse it is 18.
a. Please let me know mistake which i am doing in programming.
b. I am not able increase rpm
Description

  1. I am controlling two stepper motors with remote having two joystick.
  2. Joystick are being used for manual control and to move on auto control drive speed is being read from analog pot
  3. One button for Auto movement and another for directional control (to chagne direction)
    c. I didn't tried it but will try.

My code is

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 10); // CE, CSN

int x , j1 , j2 , AM , AC , FR , AS;

int dir = 6;
int pul = 7;
int a[10] ;
int A[10] ;
int n = 10 ;
int sp1, sp2, as;

const byte Surf1_address[6] = {'1' , 'S' , '0' , '8' , '9'};

void setup()
{
  //  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, Surf1_address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening();
  pinMode(dir , OUTPUT);
  pinMode(pul , OUTPUT);


  for (int i = 0; i < n; i++)
  {
    a[i] = 0;
  }
}

void loop()
{
  Data_recieve(a, n);
  assign_values();
  joystick( &j1 , &j2 );
  auto_manual( &AM );
  manual_move();
  for_rev( &FR );

  if ( AM == 1 )
  {
    auto_move();
  }
  if (AM == 0)
  {
    manual_move();
  }
}

void Data_recieve(int x[], int n)
{
  int c = 0;
  while (c < n)
  {
    if (radio.available())
    {
      radio.read( A, sizeof(A));
      for (int i = 0; i < n; i++)
      {
        x[i] = A[i];
        Serial.print(" value at ");
        Serial.print(i);
        Serial.print(" : ");
        Serial.println(A[i]);
      }
      break;
    }
    Serial.println(sp1);
    Serial.println(sp2);
    //    Serial.println(as);
    break;
  }
}

void assign_values()
{
  for ( int i = 0 ; i < 1 ; i++ )
  {
    j1 = A[i];
    j2 = A[i + 1];
    AM = A[i + 4];
    AC = A[i + 5];
    FR = A[i + 6];
    AS = A[i + 3];
  }
}

void joystick(int* joy1, int* joy2)
{
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    *joy1 = A[i] ;
    *joy2 = A[i + 1] ;
  }
}

void auto_manual(int* Auto)
{
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    *Auto = A[i + 4] ;
  }
}

void for_rev( int* fr)
{
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    *fr = A[i + 6];
  }
}

void Auto_speed(int* as)
{
  int k;
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    k = A[i + 3];
  }
  *as = map(k , 0 , 1023 , 1 , 3600 );
}

void auto_move()
{
  for (int i = 0; i < 1; i++)
  {
    for_rev(&FR);
    if (FR == 0)
    {
      digitalWrite(dir, HIGH);
      Auto_speed(&as);
      digitalWrite(pul, HIGH);
      delayMicroseconds(as);
      digitalWrite(pul, LOW);
      delayMicroseconds(as);
    }
    else
    {
      digitalWrite(dir, LOW);
      Auto_speed(&as);
      digitalWrite(pul, HIGH);
      delayMicroseconds(as);
      digitalWrite(pul, LOW);
      delayMicroseconds(as);
    }
    auto_manual(&AM);
    if (AM == 0)
    {
      break;
    }
  }

  auto_manual(&AM);
  if (AM == 0)
  {
    manual_move();
  }
}


void manual_move()
{
  joystick(&j1, &j2);

  if (j2 > 500)
  {
    digitalWrite(dir, HIGH);
    Speed(&sp1);
    digitalWrite(pul, HIGH);
    delayMicroseconds(sp1);
    digitalWrite(pul, LOW);
    delayMicroseconds(sp1);
    joystick(&j1, &j2);

    if (j2 < 500)
    {
      exit;
    }
    auto_manual(&AM);
    if (AM == 1)
    {
      auto_move();
    }
  }
  if (j2 < 400)
  {
    digitalWrite(dir, LOW);
    Speed(&sp2);
    digitalWrite(pul, HIGH);
    delayMicroseconds(sp2);
    digitalWrite(pul, LOW);
    delayMicroseconds(sp2);
    joystick(&j1, &j2);
    if (j2 > 400)
    {
      exit;
    }
    auto_manual(&AM);
    if (AM == 1)
    {
      auto_move();
    }
  }
}

void Speed(int* sp)
{
  joystick(&j1, &j2);
  if (j2 > 500)
  {
    sp1 = map(j2, 500, 1023, 3600, 1);
  }
  if (j2 < 400)
  {
    sp2 = map(j2, 400, 0, 3600, 1);
  }
  if (j2 > 400 && j2 < 500)
  {
    sp1 = 0;
    sp2 = 0;
  }
}

How do you know that?

Please give a dramatically simplified version of your program that is understandable not only to you.

Did you consider to use a library like AccelStepper to overcome several known problems with stepper motors?

My guess is that this bit was copied from the "while (FR == 1)" loop but in the "while (FR == 0)" loop should be changed to:

      if (FR != 0)
      {
        break;
      }

Hi, @pankajsharma200
Have you written your code in stages?
If so you should have code that JUST controls the stepper.
If not then write some code that JUST controls the stepper, no NRF code.

Get the code to run your stepper fwd then rev with your control variables and see if the problem persists.
In other words prove your hardware before your code.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Hello John

Thanks for your responce. I corrected code but no luck.

Hello Dr Diettrich,

Thanks for your responce.

a. As motor is moving slowly, i counted it by stop-watch.
b.

  1. I am controlling two stepper motors with remote having two joystick.
  2. Joystick are being used for manual control and to move on auto control drive speed is being read from analog pot
  3. One button for Auto movement and another for directional control (to chagne direction)
    c. I didn't tried it but will try.

The "if (FR = 1)" will always be true. You probably meant "if (FR == 1)".

The "if (FR = 0)" will never be true. You probably meant "if (FR == 0)".

Hello John,

I corrected the same and reviewed multiple times but still no result.

Hello Tom,

Thanks for your message. I tried the same with basic stepper code with directional change by momentary button, it runs well.

Now will run with controls and will let you know.

Hello Dr,

As per your guidance, I utilised AccelStepper library and modified program. It works well at parameter except the "RPM". The rectified the short coming in program. Modified program is as below.
Requesting your help.

#include <AccelStepper.h>
#include <nRF24L01.h>
#include <RF24.h>
AccelStepper stepper(1, 7, 6); // direction Digital 6 (CCW), pulses Digital 7 (CLK)
RF24 radio(9, 10); // CE, CSN

int x , j1 , j2 , AM , AC , FR , AS;

int a[10] ;
int A[10] ;
int n = 10 ;
int sp1, sp2, as;

const byte Surf1_address[6] = {'1' , 'S' , '0' , '8' , '9'};

void setup()
{
  //  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, Surf1_address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening();
  stepper.setMaxSpeed(5000); //SPEED = Steps / second
  //  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2


  for (int i = 0; i < n; i++)
  {
    a[i] = 0;
  }
}

void loop()
{
  Data_recieve(a, n);
  assign_values();
  joystick( &j1 , &j2 );
  auto_manual( &AM );
  manual_move();
  for_rev( &FR );

  if ( AM == 1 )
  {
    auto_move();
  }
  if (AM == 0)
  {
    manual_move();
  }
}

void Data_recieve(int x[], int n)
{
  int c = 0;
  while (c < n)
  {
    if (radio.available())
    {
      radio.read( A, sizeof(A));
      for (int i = 0; i < n; i++)
      {
        x[i] = A[i];
        Serial.print(" value at ");
        Serial.print(i);
        Serial.print(" : ");
        Serial.println(A[i]);
      }
      break;
    }
    break;
  }
}

void assign_values()
{
  for ( int i = 0 ; i < 1 ; i++ )
  {
    j1 = A[i];
    j2 = A[i + 1];
    AM = A[i + 4];
    AC = A[i + 5];
    FR = A[i + 6];
    AS = A[i + 3];
  }
}

void joystick(int* joy1, int* joy2)
{
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    *joy1 = A[i] ;
    *joy2 = A[i + 1] ;
  }
}

void auto_manual(int* Auto)
{
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    *Auto = A[i + 4] ;
  }
}

void for_rev( int* fr)
{
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    *fr = A[i + 6];
  }
}

void Auto_speed(int* as)
{
  int k;
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    k = A[i + 3];
  }
  *as = map(k , 0 , 1023 , 1 , 3600 );
}

void auto_move()
{
  for (int i = 0; i < 1; i++)
  {
    for_rev(&FR);
    if (FR == 0)
    {
      Auto_speed(&as);
      stepper.setSpeed(as);
      stepper.runSpeed();
    }
    else
    {
      Auto_speed(&as);
      stepper.setSpeed(-as);
      stepper.runSpeed();
    }
    auto_manual(&AM);
    if (AM == 0)
    {
      break;
    }
  }

  auto_manual(&AM);
  if (AM == 0)
  {
    manual_move();
  }
}

void manual_move()
{
  joystick(&j1, &j2);

  if (j2 > 500)
  {
    Speed(&sp1);
    stepper.setSpeed(sp1);
    stepper.runSpeed();

    joystick(&j1, &j2);

    if (j2 < 500)
    {
      exit;
    }
    auto_manual(&AM);
    if (AM == 1)
    {
      auto_move();
    }
  }
  if (j2 < 400)
  {
    Speed(&sp1);
    stepper.setSpeed(-sp2);
    stepper.runSpeed();

    joystick(&j1, &j2);
    if (j2 > 400)
    {
      exit;
    }
    auto_manual(&AM);
    if (AM == 1)
    {
      auto_move();
    }
  }
}

void Speed(int* sp)
{
  joystick(&j1, &j2);
  if (j2 > 500)
  {
    sp1 = map(j2, 500, 1023, 1, 3600);
  }
  if (j2 < 400)
  {
    sp2 = map(j2, 400, 0, 1, 3600);
  }
  if (j2 > 400 && j2 < 500)
  {
    sp1 = 0;
    sp2 = 0;
  }
}

Hello John,

I corrected the code, had some short comings. But still problem persist. I am not able to get desired RPM or speed. I also created code Accel libraby. posted same.

Please help.

Thanks & Regards

The for loop is crap, i always is zero. Same for almost all for loops.

In manual_move() the motor runs at sp1 in one direction and sp2 in the other one. No wonder that the speeds can differ.

Your code is so horribly twisted that I don't wonder why you - and nobody else - can make it work. Rewrite it from scratch and justify why you call so many functions at all and why so often.

Thanks DrDiettrich,

You were right. It was crap. I modified program. Now, I am able to run motor at high speed.

Thanks & Regards

Thanks John for your kind support. Now Its running at desired speeds.

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