Calculate the correct current limit for driver A4988

Im using the driver A4988 together with stepper 28byj-48. Ive read somewhere that the correct current limit on 28byj-48 is somewhere between 0.1-0.15 v. However if I feed it with 12 v there is a high frequence noise that wont go away untill I turn my powersupply down to around 9 v. However if I adjust the current limit to around 0.2 v the noise goes away. I wounder it this is to high value for my stepper. How do I know?

How can I calculate the correct value on the current limit?

Here is the specs for 28byj-48:

Voltage 5V
Current 0.26A

Do I need different current limits depending on how much voltage I feed to the driver? On 9 v the stepper sometimes fails to hold its position on high speed.

I have never used the 28byj-48 stepper motors with the A4988, but have used the A4988 with several NEMA17 motors.

To properly set the coil current on the A4988 drivers you first must know the value of the sense resistors on the board to insert into the formula Vref = 8 * Imax * Rcs where Vref is the desired reference voltage to set, Imax is the coil current and Rcs is the value of one current sense resistor.
The current sense resistors can be 0.05Ω, 0.068Ω (Pololu) or 0.100Ω (chinse) or ??, you need to look at what you have. The Pololu page on the A4988 explains how to locate the sense resistors and a detailed procedure for setting the current limits.

The noise is is coming from the motor windings and is a sign that the motor driver is actively limiting the current, and working as expected.

If it bothers you, don't use a current limiting stepper driver. There is no need to do so with that high impedance motor.

How did you connect the motor to the driver? Out of the box the 28byj-48 cannot be connected correctly to an A4988 as it is a 5 wire unipolar stepper with a common Vin for all coils. The A4988 needs a 4 wire bipolar stepper.

thanks. interesting. What is the alternatives? I have modified my 28byj-48 into bipolar stepper.

yes I know. It is modified into a bipolar stepper and works well together with a4988

You can use the ULN driver that is normally supplied with these steppers. Why do you want to drive it with a current driver?

For the modified 28-BYJ, any H-bridge motor driver chip like L293 or L298. They are inefficient but don't do current limiting, which causes the noise.

Since I need to save pins :slight_smile: 2 pins instead of 4

The Stepper library reference shows how to use a L293 with 2 pins to drive a bipolar motor.

Also a 2 wire circuit for a unipolar motor with a ULN2003 or ULN2004.

Ok. In what way are they inefficient? The most importen for me is that they are not producing noise and that I can drive a stepper with two pins instead of four. I cannot find any decent instruction telling me how to drive my stepper with L293 with only two pins from arduino. Is it possible? On a4988 im using step and dir. Can I use L293 in a similliar way?

Interesting. However I cant find anyone how documented that they actually succeded to drive the stepper with just two pins. Only with four pins like here

Any other suggestions that lets me drive a bipolar stepper (like the modded 28byj-48) with just two pins?

What's the problem with the links from @groundFungus ?
If you drive the stepper in full step and use 4 pins, then there are two pairs where one pin is always the inverted one of the other. You don't need an extra pin on the Arduino for that, you can do that with an inverter. And this is what can be seen in the links from @groundFungus.

The driver typically has a voltage drop of 2 to 4V and wastes a significant fraction of the supplied power as heat.

Hi,
This VERY basic circuit of the 293 may help.
When conducting current it has to flow through 2 BJTs.
They each drop a minimum of 1V across their Collector -Emitter, this is lost power.
l293d-clock-wise-direction-current-flow_orig

Tom... :grinning: :+1: :coffee: :australia:
Source;

I have now made the circuit @groundFungus suggested. I works fine running ULN2003 with only two pins.

The noise is gone when it is idle but the motor gets very hot!

However I have some problems with the changing of direction which is not relieable and only works 3 times out of 5. Any suggestions to improve the code?

And is it possible to run it with some library?

here is my code:

const int coilA = 2;
const int coilB =  3;
const int ms = 500;
int inc = 0;
bool changeDir = false;

void setup() {
  Serial.begin(9600);

  pinMode(coilA, OUTPUT);
  pinMode(coilB, OUTPUT);
  digitalWrite(coilA, LOW);
  digitalWrite(coilB, LOW);
}

void loop() {
  if (inc % 500 == 0) {
    changeDir = !changeDir;
    delay(100);
  }
  if (changeDir == 1) {
    cw();
  } else if (changeDir == 0) {
    ccw();
  }
  inc++;
}

void cw() {
  step1();
  step2();
  step3();
  step4();
}

void ccw() {
  step1b();
  step2b();
  step3b();
  step4b();
}

void step1b () {
  digitalWrite(coilB, LOW);
  delayMicroseconds(ms);
  digitalWrite(coilA, HIGH);
  delayMicroseconds(ms);
}

void step2b () {
  digitalWrite(coilB, HIGH);
  delayMicroseconds(ms);
  digitalWrite(coilA, HIGH);
  delayMicroseconds(ms);
}

void step3b () {
  digitalWrite(coilB, LOW);
  delayMicroseconds(ms);
  digitalWrite(coilA, HIGH);
  delayMicroseconds(ms);
}

void step4b () {
  digitalWrite(coilB, LOW);
  delayMicroseconds(ms);
  digitalWrite(coilA, LOW);
  delayMicroseconds(ms);
}

void step1 () {
  digitalWrite(coilA, LOW);
  delayMicroseconds(ms);
  digitalWrite(coilB, HIGH);
  delayMicroseconds(ms);
}

void step2 () {
  digitalWrite(coilA, HIGH);
  delayMicroseconds(ms);
  digitalWrite(coilB, HIGH);
  delayMicroseconds(ms);
}

void step3 () {
  digitalWrite(coilA, HIGH);
  delayMicroseconds(ms);
  digitalWrite(coilB, LOW);
  delayMicroseconds(ms);
}

void step4 () {
  digitalWrite(coilA, LOW);
  delayMicroseconds(ms);
  digitalWrite(coilB, LOW);
  delayMicroseconds(ms);
}

Your stepping is not correct. coilA and coilB should be driven like this:
00 -> stepdelay -> 01 -> stepdelay -> 11 -> stepdelay -> 10 -> stepdelay -> 00 ...
To change the direction of rotation, the coils must be driven in reverse order.

Which voltage do you apply to the coils? With the ULN driver this must not be more than 5..6 Volt.

The circuits came from the reference for the Stepper library.

Do you mean like this? In that case it wont work for me. It doesnt run at all. Just idle

const int coilA = 2;
const int coilB =  3;
const int ms = 800;
int inc = 0;
bool changeDir = false;

void setup() {
  Serial.begin(9600);

  pinMode(coilA, OUTPUT);
  pinMode(coilB, OUTPUT);
  digitalWrite(coilA, LOW);
  digitalWrite(coilB, LOW);
}

void loop() {
  if (inc % 500 == 0) {
    changeDir = !changeDir;
    delay(100);
  }
  if (changeDir == 1) {
    cw();
  } else if (changeDir == 0) {
    ccw();
  }
  inc++;
}

void cw() {
  step1();
  delayMicroseconds(ms);
  step2();
  delayMicroseconds(ms);
  step3();
  delayMicroseconds(ms);
  step4();
  delayMicroseconds(ms);
}

void ccw() {
  step4();
  delayMicroseconds(ms);
  step3();
  delayMicroseconds(ms);
  step2();
  delayMicroseconds(ms);
  step1();
  delayMicroseconds(ms);
}

void step1 () {
  digitalWrite(coilA, LOW);
  digitalWrite(coilB, HIGH);
}

void step2 () {
  digitalWrite(coilA, HIGH);
  digitalWrite(coilB, HIGH);
}

void step3 () {
  digitalWrite(coilA, HIGH);
  digitalWrite(coilB, LOW);
}

void step4 () {
  digitalWrite(coilA, LOW);
  digitalWrite(coilB, LOW);
}

This do work bot direction is still not reliable:

const int coilA = 2;
const int coilB =  3;
const int ms = 800;
int inc = 0;
bool changeDir = false;

void setup() {
  Serial.begin(9600);

  pinMode(coilA, OUTPUT);
  pinMode(coilB, OUTPUT);
  digitalWrite(coilA, LOW);
  digitalWrite(coilB, LOW);
}

void loop() {
  if (inc % 500 == 0) {
    changeDir = !changeDir;
    delay(100);
  }
  if (changeDir == 1) {
    cw();
  } else if (changeDir == 0) {
    ccw();
  }
  inc++;
}

void cw() {
  step1();
  step2();
  step3();
  step4();
}

void ccw() {
  step4();
  step3();
  step2();
  step1();
}

void step1 () {
  digitalWrite(coilA, LOW);
  delayMicroseconds(ms);
  digitalWrite(coilB, HIGH);
  delayMicroseconds(ms);
}

void step2 () {
  digitalWrite(coilA, HIGH);
  delayMicroseconds(ms);
  digitalWrite(coilB, HIGH);
  delayMicroseconds(ms);
}

void step3 () {
  digitalWrite(coilA, HIGH);
  delayMicroseconds(ms);
  digitalWrite(coilB, LOW);
  delayMicroseconds(ms);
}

void step4 () {
  digitalWrite(coilA, LOW);
  delayMicroseconds(ms);
  digitalWrite(coilB, LOW);
  delayMicroseconds(ms);
}