28BYj-48 motor on A4988 returns to int setting

Hi,
First of all, lng time I checked this forum, sorry for that :slight_smile: Reason for thet is that at that time I checked in together with my son who was studying at the time and me showing interest in what he was doing :slight_smile:
I have a question about the 28BYJ-48 stepper motor on an A4988 driver
As I have changed the motor to a bi-polar one I am using it on the A4988 driver board.

I have found a site that will let me connect a Nema17 motor https://www.brainy-bits.com/post/control-a-stepper-motor-using-a-joystick-and-an-arduino

And I changed some to get it working on the 28BYj-48.

What happens now is:
If I connect the SLEEP to SLP on the driver board it does not work
When I connect the SLEEP to RST on the driver board it works ? BUTT
the motor returns to the point it started when powered, at the setpoint of the INT STEPS variable.

How can I get the SLEEP (brake) to work properly ?

It's been so long you must've forgotten this:

OKay, let's see if I understand what you're saying :slight_smile:

Hardware:
Arduino UNO v3 clone
28BYJ-48 stepper motor
A4988 driver board
and some joystick module for arduino from amazon

#define step_pin 3  // Pin 3 connected to Steps pin on EasyDriver
#define dir_pin 2   // Pin 2 connected to Direction pin
#define MS1 5       // Pin 5 connected to MS1 pin
#define MS2 4       // Pin 4 connected to MS2 pin
#define SLEEP 7     // Pin 7 connected to SLEEP pin
#define X_pin A0    // Pin A0 connected to joystick x axis

int direction;    // Variable to set Rotation (CW-CCW) of the motor
int steps = 1025; // Assumes the belt clip is in the Middle

void setup() {
   pinMode(MS1, OUTPUT);
   pinMode(MS2, OUTPUT);
   pinMode(dir_pin, OUTPUT);
   pinMode(step_pin, OUTPUT);
   pinMode(SLEEP, OUTPUT);
   
   digitalWrite(SLEEP, HIGH);  // Wake up EasyDriver
   delay(5);  // Wait for EasyDriver wake up
   

/* Configure type of Steps on EasyDriver:
// MS1 MS2
//
// LOW LOW = Full Step //
// HIGH LOW = Half Step //
// LOW HIGH = A quarter of Step //
// HIGH HIGH = An eighth of Step //
*/

   digitalWrite(MS1, LOW);      // Configures to Full Steps
   digitalWrite(MS2, LOW);    // Configures to Full Steps
   
}

void loop() {
  while (analogRead(X_pin) >= 0 && analogRead(X_pin) <= 100) {
    if (steps > 0) {
      digitalWrite(dir_pin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(step_pin, HIGH);
      delay(1);
      digitalWrite(step_pin, LOW);
      delay(1);
      steps--;
    }      
  }
  
    while (analogRead(X_pin) > 100 && analogRead(X_pin) <= 400) {
      if (steps < 512) {
        digitalWrite(dir_pin, LOW);  // (HIGH = anti-clockwise / LOW = clockwise)
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps++;
      }    
      if (steps > 512) {
        digitalWrite(dir_pin, HIGH);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps--;
      }
    }    
      
    while (analogRead(X_pin) > 401 && analogRead(X_pin) <= 600) {
      if (steps < 1025) {
        digitalWrite(dir_pin, LOW);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps++;
      }    
      if (steps > 1025) {
        digitalWrite(dir_pin, HIGH);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps--;
      } 
    } 

    while (analogRead(X_pin) > 601 && analogRead(X_pin) <= 900) {
      if (steps < 1535) {
        digitalWrite(dir_pin, LOW);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps++;
      }    
      if (steps > 1535) {
        digitalWrite(dir_pin, HIGH);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps--;
      }    
    }   
   
    while (analogRead(X_pin) > 900 && analogRead(X_pin) <= 1024) {
      if (steps < 2050) {
        digitalWrite(dir_pin, LOW);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps++;
      }
    }
}

Hope you have enough info to see what I mean

RST needs a pull-up resistor to VDD or you can connect it to another GPIO pin and set it as OUTPUT HIGH
Then you can connect SLEEP to SLP

Does the joystick return to a "zero" position when released?

I tried to simulate your setup here

https://wokwi.com/projects/361087900171194369

image

and if the slide potentiometer is not in the middle position the stepper moves. If I position it in the middle there is no movement after restart ...

If you want to disable the driver you can connect to pin ENABLE

see here for a demo:

https://wokwi.com/projects/361088149508953089

Sketch and setup
#define step_pin 3  // Pin 3 connected to Steps pin on EasyDriver
#define dir_pin 2   // Pin 2 connected to Direction pin
#define MS1 5       // Pin 5 connected to MS1 pin
#define MS2 4       // Pin 4 connected to MS2 pin
#define ENABLE 7     // Pin 7 connected to ENABLE pin (active LOW)
#define X_pin A0    // Pin A0 connected to joystick x axis

int direction;    // Variable to set Rotation (CW-CCW) of the motor
int steps = 1025; // Assumes the belt clip is in the Middle

void setup() {
   Serial.begin(115200);
   pinMode(MS1, OUTPUT);
   pinMode(MS2, OUTPUT);
   pinMode(dir_pin, OUTPUT);
   pinMode(step_pin, OUTPUT);
   pinMode(ENABLE, OUTPUT);
 
   digitalWrite(ENABLE, HIGH);  // Disable A4988
   Serial.println("Disabled!");
 
   delay(5);  // Wait for EasyDriver wake up
   

/* Configure type of Steps on EasyDriver:
// MS1 MS2
//
// LOW LOW = Full Step //
// HIGH LOW = Half Step //
// LOW HIGH = A quarter of Step //
// HIGH HIGH = An eighth of Step //
*/

   digitalWrite(MS1, LOW);      // Configures to Full Steps
   digitalWrite(MS2, LOW);    // Configures to Full Steps

   delay(3000);
   digitalWrite(ENABLE, LOW);  // Enable A4988
   Serial.println("Enabled!");
   
}

void loop() {
  while (analogRead(X_pin) >= 0 && analogRead(X_pin) <= 100) {
    if (steps > 0) {
      digitalWrite(dir_pin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(step_pin, HIGH);
      delay(1);
      digitalWrite(step_pin, LOW);
      delay(1);
      steps--;
    }      
  }
  
    while (analogRead(X_pin) > 100 && analogRead(X_pin) <= 400) {
      if (steps < 512) {
        digitalWrite(dir_pin, LOW);  // (HIGH = anti-clockwise / LOW = clockwise)
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps++;
      }    
      if (steps > 512) {
        digitalWrite(dir_pin, HIGH);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps--;
      }
    }    
      
    while (analogRead(X_pin) > 401 && analogRead(X_pin) <= 600) {
      if (steps < 1025) {
        digitalWrite(dir_pin, LOW);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps++;
      }    
      if (steps > 1025) {
        digitalWrite(dir_pin, HIGH);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps--;
      } 
    } 

    while (analogRead(X_pin) > 601 && analogRead(X_pin) <= 900) {
      if (steps < 1535) {
        digitalWrite(dir_pin, LOW);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps++;
      }    
      if (steps > 1535) {
        digitalWrite(dir_pin, HIGH);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps--;
      }    
    }   
   
    while (analogRead(X_pin) > 900 && analogRead(X_pin) <= 1024) {
      if (steps < 2050) {
        digitalWrite(dir_pin, LOW);
        digitalWrite(step_pin, HIGH);
        delay(1);
         digitalWrite(step_pin, LOW);
        delay(1);
        steps++;
      }
    }
}

Dieser Text wird ausgeblendet

:wink: Darn, that slipped my mind, the joystick returns to the middle after release. and its an analog joystick now I understand.

How can I stop the motor from returning to the setpoint ?

I tried your link and used your code to test but the motor still returns to the middle point/setpoint

Hi :slight_smile:

I am a complete noob to this so what do you mean ? can your provide a sample or something to show it ?

That's clear, my code just delays the start to demo the use of the enable pin...

What you can do:

  • Measure the value of the middle position
  • Use that position as your "zero" value

Add this code:

// Add this in your define section
#define RESET 8 // Pin 8 connected to RST pin

// Add this to setup
pinMode(RESET, OUTPUT);
digitalWrite(RESET, HIGH);

Connect a wire from pin 8 to RST on the A4988 driver board

I have reduced your code a little bit (there is more that can be done as you may see but I think it is better to advance in certain steps...):

//#define WOKWI  // If this is defined the data are in accordance with the WOKWI stepper (200 steps/revolution)

#define step_pin 3  // Pin 3 connected to Steps pin on EasyDriver
#define dir_pin 2   // Pin 2 connected to Direction pin
#define MS1 5       // Pin 5 connected to MS1 pin
#define MS2 4       // Pin 4 connected to MS2 pin
#define ENABLE 7     // Pin 7 connected to ENABLE pin (active LOW)
#define X_pin A0    // Pin A0 connected to joystick x axis

int direction;    // Variable to set Rotation (CW-CCW) of the motor
#ifdef WOKWI
  int steps = 100; // Assumes the belt clip is in the Middle
  int Positions[5] = {50,75, 100, 125, 150};
#else
  int steps = 1025; // Assumes the belt clip is in the Middle
  int Positions[5] = {0,512, 1015, 1535, 2050};
#endif

int Thresholds[6] = {0,100,400,600,900,1024};

void setup() {
   Serial.begin(115200);
   pinMode(MS1, OUTPUT);
   pinMode(MS2, OUTPUT);
   pinMode(dir_pin, OUTPUT);
   pinMode(step_pin, OUTPUT); 
   pinMode(ENABLE, OUTPUT);
   digitalWrite(ENABLE, LOW);  // Enable A4988
   Serial.println("Enabled!");
   delay(5);  // Wait for EasyDriver wake up
   

/* Configure type of Steps on EasyDriver:
// MS1 MS2
//
// LOW LOW = Full Step //
// HIGH LOW = Half Step //
// LOW HIGH = A quarter of Step //
// HIGH HIGH = An eighth of Step //
*/

   digitalWrite(MS1, LOW);      // Configures to Full Steps
   digitalWrite(MS2, LOW);    // Configures to Full Steps

   
}

void loop() {
  IfWithinThresholdsStepTo(Positions[0],  Thresholds[0] ,   Thresholds[1]);
  IfWithinThresholdsStepTo(Positions[1],  Thresholds[1]+1,  Thresholds[2]);
  IfWithinThresholdsStepTo(Positions[2],  Thresholds[2]+1,  Thresholds[3]);
  IfWithinThresholdsStepTo(Positions[3],  Thresholds[3]+1,  Thresholds[4]);
  IfWithinThresholdsStepTo(Positions[4],  Thresholds[4]+1,  Thresholds[5]);
}


void IfWithinThresholdsStepTo(uint16_t Position,int lowMargin, int highMargin){
     while (analogRead(X_pin) > lowMargin && analogRead(X_pin) <= highMargin) {
        if (steps < Position) {
            digitalWrite(dir_pin, LOW);
            digitalWrite(step_pin, HIGH);
            delay(1);
            digitalWrite(step_pin, LOW);
            delay(1);
            steps++;
          }    
          if (steps > Position) {
            digitalWrite(dir_pin, HIGH);
            digitalWrite(step_pin, HIGH);
            delay(1);
            digitalWrite(step_pin, LOW);
            delay(1);
            steps--;
          }    
     }    
}  

I added a #define so that it works also with the Wokwi stepper which has 200 steps/revolution.
This line is already disabled in the sketch above.

See here https://wokwi.com/projects/361241142721306625

Actually the driver board does know nothing about the position of your stepper motor axis nor does your software know it. (It is different with Wokwi as the simulator resets the stepper axis to 0.0Β° with every restart. That usually does not happen in reality. The axis is where it stands at power up unless someone uses sensors to identify the angular position.)

If your stepper moves when you start the sketch the joystick must deliver a value that is not within the center range (401 to 600).

You may check the value of your joystick in setup() and make sure that it is in the center position before you go to loop().

This is a version that waits until you have centered the joystick:

Ask to center Joystick
#define WOKWI  // If this is defined the data are in accordance with the WOKWI stepper (200 steps/revolution)

#define step_pin 3  // Pin 3 connected to Steps pin on EasyDriver
#define dir_pin 2   // Pin 2 connected to Direction pin
#define MS1 5       // Pin 5 connected to MS1 pin
#define MS2 4       // Pin 4 connected to MS2 pin
#define ENABLE 7     // Pin 7 connected to ENABLE pin (active LOW)
#define X_pin A0    // Pin A0 connected to joystick x axis

int direction;    // Variable to set Rotation (CW-CCW) of the motor
#ifdef WOKWI
  int steps = 100; // Assumes the belt clip is in the Middle
  int Positions[5] = {50,75, 100, 125, 150};
#else
  int steps = 1025; // Assumes the belt clip is in the Middle
  int Positions[5] = {0,512, 1015, 1535, 2050};
#endif

int Thresholds[6] = {0,100,400,600,900,1023};

void setup() {
   Serial.begin(115200);
   pinMode(MS1, OUTPUT);
   pinMode(MS2, OUTPUT);
   pinMode(dir_pin, OUTPUT);
   pinMode(step_pin, OUTPUT); 
   pinMode(ENABLE, OUTPUT);
   digitalWrite(ENABLE, LOW);  // Enable A4988
   Serial.println("Enabled!");
   delay(5);  // Wait for EasyDriver wake up
   

/* Configure type of Steps on EasyDriver:
// MS1 MS2
//
// LOW LOW = Full Step //
// HIGH LOW = Half Step //
// LOW HIGH = A quarter of Step //
// HIGH HIGH = An eighth of Step //
*/

   digitalWrite(MS1, LOW);      // Configures to Full Steps
   digitalWrite(MS2, LOW);    // Configures to Full Steps
  Serial.println("Please center Joystick!");  
  while (!(analogRead(X_pin) > Thresholds[2]+1 && analogRead(X_pin) <= Thresholds[3])){  // if not centered
   Serial.print(".");
   delay(1000);
  }
  Serial.println("\nJoystick is centered!"); 
   
}

void loop() {
  IfWithinThresholdsStepTo(Positions[0],  Thresholds[0] ,   Thresholds[1]);
  IfWithinThresholdsStepTo(Positions[1],  Thresholds[1]+1,  Thresholds[2]);
  IfWithinThresholdsStepTo(Positions[2],  Thresholds[2]+1,  Thresholds[3]);
  IfWithinThresholdsStepTo(Positions[3],  Thresholds[3]+1,  Thresholds[4]);
  IfWithinThresholdsStepTo(Positions[4],  Thresholds[4]+1,  Thresholds[5]);
}


void IfWithinThresholdsStepTo(uint16_t Position,int lowMargin, int highMargin){
     while (analogRead(X_pin) > lowMargin && analogRead(X_pin) <= highMargin) {
        if (steps < Position) {
            digitalWrite(dir_pin, LOW);
            digitalWrite(step_pin, HIGH);
            delay(1);
            digitalWrite(step_pin, LOW);
            delay(1);
            steps++;
          }    
          if (steps > Position) {
            digitalWrite(dir_pin, HIGH);
            digitalWrite(step_pin, HIGH);
            delay(1);
            digitalWrite(step_pin, LOW);
            delay(1);
            steps--;
          }    
     }    
}  

See https://wokwi.com/projects/361248704150318081

For further information on the driver board you may download this

A4988 datasheet

Hi @jim-p,

The datasheet says



so you are perfectly right concerning the use of Reset Input and Sleep Mode!

However I think the problem lays more in the use of the joystick than the A4988 board.

Would you mind checking my assumptions?

I may be wrong and would appreciate your view!

Regards
ec2021

Until the OP makes the correct connections to the driver board, it really doesn't matter what the code does.

1 Like

Hi, thanks for your help, give me some time to chck this out and wire up an arduino board to test all of this.

I'll be back soon, as I am not very smart on this and need to let it all sink in it can take a few days :slight_smile:
Old geesers tend to crawl like snails :slight_smile:

Hi jim-p

would you be so kind to tell me where I did the wrong connections ?

See post 4

Hi :slight_smile:
Is this what you mean ?

Or is this what you mean ?

I need to be honest saying that I am working on a few projects at once to try and accomplish waht I want/need.

As I already recieve help from a great guy named Maverick I like to try and complete that project first because its practically the same but then with servo motors.

If and when I find spare time I will work on this project, but for the time beeing the servo project has my priority>

I even think that that project is way better then my attempt here and I get the idea I can better try to adapt that project for use with steppers, replacing the servo motors with steppers in due time.

However I will stay working on this but in a slower tempo.

Thanks to everyone who has en keeps helping me out :slight_smile:

What don't you understand about post 4?

I didn't understand because I was too tired to read well enough.

I hope I got it right in this example: