Simple speed control for bipolar stepper motor

I would like to drive a generic bipolar stepper motor using a L298 H-bridge. The application is a magnetic stir plate so I have no use for control of angle, step count, direction etc. I do however need to be able to control the rotation speed.

The stepping sequence seem quite simple and straight forward.

Assuming I would like to drive my motor without any stepper library, would it be possible to make a simple program loop that basically sets the outputs to phase sequence 1, pulls the enable pins HIGH for x microseconds (depends on the voltage and motor specs), pulls the enable pins LOW, waits for a variable delay time that will decide the actual motor speed, sets phase sequence 2, and so on?

BipolarPhases.jpg

You may find some inspiration here

Ken

What you want will be more complicated with the L298 than if you were using a specialized stepper driver (for example a Pololu A4988).

The L298 requires the Arduino to control the sequencing of pulses whereas the specialized drivers just need step and direction signals from the Arduino.

A h-bridge is a poor choice for driving a stepper and if you wish to use one I suggest you use one of the stepper libraries to simplify the programming. But if you know how to produce the correct pulse sequence for the L298 then there is no need for a library.

The Thread stepper motor basics may have some useful background info.

...R

First of all I want to thank you both for your input. I have made some tests with the stepper example code (stepper_oneRevolution) and it works like a charm when I use 5V as motor input voltage to my L298N.

I KNOW the L298 H-bridge isn’t the best way to drive my stepper, but I like it and I am fairly certain it will suffice for me.

I have borrowed a logic analyzer to better understand the original, working code.

From the printout I can see that the original example sequence (wich works for me) is:

PIN 8 9 10 11

SEQ1 H L L H

SEQ2 H L H L

SEQ3 L H H L

SEQ4 L H L H

I will give this a try and take from there. The original code does not make use of the enable-inputs so these are the only pins used.

But why not use a library? Then you don't have to manage all that stuff in your code.

First of all I wanted to learn a bit more about stepper motors.

And second, my application is somewhat unusual for a stepper motor. I want to regulate the speed with a potentiometer and get it up to a fairly high speed and keep it there for maybe 48 hours or more. Not exactly what one would normally use a stepper for. Hence all libraries and drivers are not optimal, even though some are probably useful anyway.

When I raised the motor voltage on the L298 from 5 to 12V I could reach a delay time of just over 900 us. I have a shunt resistor to be able to measure the current through one of the coils of my motor, and on the oscilloscope it looks like the current goes down with increased speed just as I was expecting. Also when I run it at the highest speed my setup will allow, nothing gets hot as it used to with 5V and low speed.

Here is the current code, should anyone be interested. I intend to document this project in case anyone is interested or has a similar problem.

int input1a = 8;
int input1b = 9;
int input2a = 10;
int input2b = 11;
int enable1 = 6;
int enable2 = 7;
int rpm = A0;
int enable = 5000;
int stepdelay = 1;

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

  pinMode(input1a, OUTPUT);
  pinMode(input1b, OUTPUT);
  pinMode(input2a, OUTPUT);
  pinMode(input2b, OUTPUT);
  pinMode(enable1, OUTPUT);
  pinMode(enable2, OUTPUT);

  digitalWrite(input1a, LOW);
  digitalWrite(input1b, LOW);
  digitalWrite(input2a, LOW);
  digitalWrite(input2b, LOW);
  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);

  delay(1000);

}

void loop() {
  
  rpm = analogRead(A0);
  enable = map(rpm, 0, 1023, 2500, 890);
  
  // Step 1
  digitalWrite(input1a, HIGH);
  digitalWrite(input1b, LOW);
  digitalWrite(input2a, LOW);
  digitalWrite(input2b, HIGH);
  digitalWrite(enable1, HIGH);
  digitalWrite(enable2, HIGH);

  delayMicroseconds(enable);

  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);

  delayMicroseconds(stepdelay);

  // Step 2
  digitalWrite(input1a, HIGH);
  digitalWrite(input1b, LOW);
  digitalWrite(input2a, HIGH);
  digitalWrite(input2b, LOW);
  digitalWrite(enable1, HIGH);
  digitalWrite(enable2, HIGH);

  delayMicroseconds(enable);

  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);

  delayMicroseconds(stepdelay);
  
  // Step 3
  digitalWrite(input1a, LOW);
  digitalWrite(input1b, HIGH);
  digitalWrite(input2a, HIGH);
  digitalWrite(input2b, LOW);
  digitalWrite(enable1, HIGH);
  digitalWrite(enable2, HIGH);

  delayMicroseconds(enable);

  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);

  delayMicroseconds(stepdelay);

  // Step 4
  digitalWrite(input1a, LOW);
  digitalWrite(input1b, HIGH);
  digitalWrite(input2a, LOW);
  digitalWrite(input2b, HIGH);
  digitalWrite(enable1, HIGH);
  digitalWrite(enable2, HIGH);

  delayMicroseconds(enable);

  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);

  delayMicroseconds(stepdelay);
  
    Serial.println(enable);
}

stepper_mk1.ino (1.92 KB)

No such thing as a "generic" bipolar stepper.

Perhaps you coud give full details of the actual motor if you want a useful reply?

I KNOW the L298 H-bridge isn'tthe best way to drive my stepper, but I likeit and I am fairly certain it will suffice for me.

If you KNOW that then you have a low impedance bipolar and it won't work without
drastic compromise and a low voltage supply. You won't get any kind of speed from it.

The motor is a 17PM-K036-G4ST Bipolar stepper motor with 1.8 degree stepp angle and 0.8A coil current rating. Coil inductance is either 11.3 mH or 8.9 mH depending on whether it is ferrite or neodymium magnets and I have not been able to determine if G4ST is fe or neo. Coil DC resistance is 5.1 Ohm.

From what I can gather I am driving the motor to it's limits with the given parameters so if I want more speed I have to raise the driving voltage and keep a close look at the voltage drop over my shunt resistor.

Anyhow I can't see how using a library or a better motor driver could give much more speed with just 12V driving voltage.

kamelryttarn:
so if I want more speed I have to raise the driving voltage and keep a close look at the voltage drop over

That does not make sense to me. If you have a resistor to limit the current in the motor raising the voltage will just raise the current and (presumably) cause overheating. If you increase the resistance you defeat the purpose of the higher voltage.

However if you use a specialized stepper driver (such as a Pololu A4988) you can use a high voltage because the driver is designed to limit the maximum current.

Stepper motors need high voltages because the current is provided in short pulses. The inductance and back-emf conspire to slow the rise-time of the current from zero to its permitted max. As the motor runs faster the slow rise time means the current never has time to reach its maximum. A higher voltage will help to get a quicker rise time but may also result in a too-high current unless the driver can measure and limit the current.

...R

The resistor is only used as a current shunt so I can connect my oscilloscope and calculate the current running through the coils. The resistor I use is only 20mOhm so the drop across it is only a few mV, but enough for the oscilloscope.

kamelryttarn:
The resistor is only used as a current shunt so I can connect my oscilloscope and calculate the current running through the coils. The resistor I use is only 20mOhm so the drop across it is only a few mV, but enough for the oscilloscope.

I had not realized it was just for measuring current.

I think you will still have a problem because the motor will be able to accept a higher voltage at higher speeds - or, more correctly, the voltage that is suitable at high speed will cause overheating when the motor is stationary and the coils are just simple resitances.

...R

kamelryttarn:
The motor is a 17PM-K036-G4ST Bipolar stepper motor with 1.8 degree stepp angle and 0.8A coil current rating. Coil inductance is either 11.3 mH or 8.9 mH depending on whether it is ferrite or neodymium magnets and I have not been able to determine if G4ST is fe or neo. Coil DC resistance is 5.1 Ohm.

5 ohms is in the wilderness between low and high impedance bipolars - neither designed for
current control or for voltage control reallly.... It does make it possible to operate from a single
LiPo via MOSFET H-bridges though.

900us is 1100 pulses/second or about 330rpm - I know a low impedance motor
can get to 3600rpm at 20V, so I'd expect 2000rpm at 12V (though usable
torque might only be available to 1000rpm or so).

Chopper drive + low impedance motor will always run rings round the alternatives,
especially as you get microstepping and much less resonance (usually the limit
to performance).

I believe my code is written in a way that actually means I am getting close to 150 rpm and not 300. I have treated the entire sequence as 4 separate steps when in fact it is only two, meaning that the actual speed is only half what you might think. I tried to alter the code so that the coil isn't switched off unless the polarity changes but that gave me worse performance so I kept the code as it is for now. I will continue to test and measure different voltages and delay times.

According to the datasheet, that is a 6-wire motor. How have you got it wired at the moment?

Hi,
Kamelryttarn, I like your approach to get your stepper to work as you need it.
The simple sketch lets you see exactly what terminals you are controlling, and adjust all the timing variables.

Keep it up, as I see you are learning a lot from it.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

Tom.... :slight_smile:

I’ll do my best to provide pictures and explanations to my wiring setup. I have soldered the L298N to a prototype shield and put the diodes on a separate piece of PCB.

Here are pictures of the stepper motor to confirm mine only has 4 wires.

17pm_2.png

Here are some pics of the setup. Pins 8 through 11 are the yellow wires that goes to the 4 inputs of the L298N chip. Pins 6 and 7 are connected to the enable inputs of the L298N, but for those who only wants to test the example code provided in the Arduino IDE installation these enable inputs should be directly connected to the 5V rail (logic HIGH) otherwise the motor will now turn.

The white wires are sense-connections on the L298N where I had my shunt resistor connected. I have replaced it with a wire for now.

The setup is pretty straight forward and the L298N is pretty easy to understand as well as connect and solder yourself, unlike a lot of the “better suited” stepper motor drivers that are SMD.

A few more pics. I put a large connector where I could attach motors or what-not but I ended up connecting my stepper in the header I soldered close to the L298N instead

Here is the diode board and the connections to the motor.