Arm oscillation with Stepper Motor

I am using Arduino along with a driver CL860 along with 8.5N stepper motor. This motor is being utilised to drive an oscillating arm at desired speed and at desired angle (maximum 160 degree and minimum to 70 degree). Angle and Arm speed is being controlled by two different potentiometers of 10K.
The driver has input of pulse and direction which is given by Arduino. Motor should run from centre
a. Gradually accelerate to input speed then run at desired speed then deaccelerate to Zero speed,
b. Change direction, gradually accelerate to desired speed run at desired speed then deaccelerate to Zero speed
c. Change direction, gradually accelerate to desired speed run at desired speed
d. And continue to do this till exit command is given.
Problem Statement: Motor gives jerk while running at user input speed not while acceleration / deaccelerating.

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

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

int x , i , ang , spe , AM , TS , AC , j1 ;
int dirPin = 6;
int pulPin = 7;
int a[7] ;
int A[7] ;
int n = 7 ;
int sp1 , val ;

const byte address[6] = "00001";

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

  for (int i = 0; i < 7; i++)  // assigning values in array
  {
    a[i] = 0;
  }
}

void loop()
{
  Data_recieve(a, n);
  assign_values();
  knob( &ang , &spe );
  arm_control( &AC );
  temp_stop( &TS );
  arm_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 < 7; i++)
      {
        x[i] = A[i];
      }
      break;
    }
    break;
  }
}

void assign_values()
{
  for ( int i = 0 ; i < 1 ; i++ )
  {
    j1 = A[i];
    ang = A[i + 2];
    spe = A[i + 3];
    AM = A[i + 4];
    AC = A[i + 5];
    TS = A[i + 6];
  }
}

void knob(int* pot1, int* pot2)
{
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    *pot1 = A[i + 2] ;
    *pot2 = A[i + 3] ;
  }
}

void arm_control( int* arm)
{
  Data_recieve(a, n);
  for ( int i = 0 ; i < 1 ; i++ )
  {
    *arm = A[i + 5];
  }
}

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

void angle_speed( int* j , int* sp )
{
  knob( &ang , &spe );
  int k = map( ang , 0 , 1023 , 70 , 160 );
  *j = k * 44 ;
  *sp = map( spe , 0 , 1023 , 1000 , 250 );
}

void arm_move()
{
  if ( TS == 1 )
  {
    if ( AC == 1 )
    {
      int sp2 = 1000, j = 0;
      angle_speed( &val , &sp1 );
      //      delay(1000);
      digitalWrite( dirPin , HIGH );
      for ( i = 1 ; i <= val / 8 ; i++ ) // executing loop for half of one quarter duration of one oscillation
      {
        if (j >= val / 16)  // to accelarate for half duration of this loop
        {
          j = sp1 / 2;
        }
        sp2 = map(j, 0, val / 16, 1000, sp1 / 2); // calculating accelaration
        digitalWrite(pulPin , HIGH);
        delayMicroseconds(sp2);
        digitalWrite(pulPin , LOW);
        delayMicroseconds(sp2);
        j = j + 1;
      }
      for ( i = val / 8 ; i <= val / 4 ; i++ ) // executing loop for other half of one quarter (same) duration of one oscillation
      {
        sp2 = sp1;
        if (i >= 3 * val / 16)    // to deaccelarate for second half duration of this loop
        {
          sp2 = map(i, 3 * val / 16, val / 4, sp1 / 2, 1000); // calculating deaccelaration
        }
        digitalWrite(pulPin , HIGH);
        delayMicroseconds(sp2);
        digitalWrite(pulPin , LOW);
        delayMicroseconds(sp2);
      }
      temp_stop( &TS );
      arm_control( &AC );
      //      delay(1000);
      j = 0; sp2 = 1000;         
      digitalWrite( dirPin , LOW );
      for ( i = 1 ; i <= val / 4 ; i++ )
      {
        if (j >= val / 8)
        {
          j = sp1 / 2;
        }
        sp2 = map(j, 0, val / 8, 1000, sp1 / 2);
        digitalWrite(pulPin , HIGH);
        delayMicroseconds(sp2);
        digitalWrite(pulPin , LOW);
        delayMicroseconds(sp2);
        j = j + 1;
        temp_stop( &TS );
        arm_control( &AC );
      }
      for ( i = val / 4 ; i <= val / 2 ; i++ )
      {
        sp2 = sp1;
        if (i >= 3 * val / 4)
        {
          sp2 = map(i, 3 * val / 4, val / 2, sp1 / 2, 1000);
        }
        digitalWrite(pulPin , HIGH);
        delayMicroseconds(sp2);
        digitalWrite(pulPin , LOW);
        delayMicroseconds(sp2);
      }
      temp_stop( &TS );
      arm_control( &AC );
      //      delay(1000);
      j = 0; sp2 = 1000;
      digitalWrite( dirPin , HIGH );
      for ( i = 1 ; i <= val / 8 ; i++ )
      {
        if (j >= val / 16)
        {
          j = sp1 / 2;
        }
        sp2 = map(j, 0, val / 16, 1000, sp1 / 2);
        digitalWrite(pulPin , HIGH);
        delayMicroseconds(sp2);
        digitalWrite(pulPin , LOW);
        delayMicroseconds(sp2);
        j = j + 1;
      }
      for ( i = val / 8 ; i <= val / 4 ; i++ )
      {
        sp2 = sp1;
        if (i >= 3 * val / 16)
        {
          sp2 = map(i, 3 * val / 16, val / 4, sp1 / 2, 1000);
        }
        digitalWrite(pulPin , HIGH);
        delayMicroseconds(sp2);
        digitalWrite(pulPin , LOW);
        delayMicroseconds(sp2);
        temp_stop( &TS );
        arm_control( &AC );
      }
      temp_stop( &TS );
      arm_control( &AC );
      if (AC == 0)
      {
        exit;
      }
      if (TS == 0)
      {
        exit;
      }
    }
    temp_stop( &TS );
    arm_control( &AC );
  }
}

i saw negative sp2 values when simulating your code that may explain the behavior.

in general, suggest using sub-functions rather than copy&paste

i tested the following in simulation as a way to determine the pulse delay used to affect acceleration

    for (int pos = 0; pos <= posMax; pos += 50)  {
        posDelta = min(pos, posMax - pos);
        unsigned long sp = sp1;
        if (End > posDelta)
            sp = map(posDelta, 0, End, 3*sp1, sp1);

        step (sp, 0);
    }

the above could be used for both directions in a sub-function with a dir argument

where

void step (
    unsigned long sp2,
    int           dir )
{
    digitalWrite      (dirPin , dir);

    digitalWrite      (pulPin , HIGH);
    delayMicroseconds (sp2);
    digitalWrite      (pulPin , LOW);
    delayMicroseconds (sp2);
}

Thanks GCJR. We are able to solve it. Thanks for your help

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