Stepper Motors with Activity Board and H-Bridge

Hello, I'm not sure where this discussion should go so I defaulted to the general chat. Anyway. I am trying to drive a stepper motor via an Activity Board and a H-Bridge using C as my language for programming. My question is where to find any libraries to actually simplify running this stepper or just simply how to do it. I'm using a Bipolar Stepper and have no experience working with steppers. Any help is appreciated thanks. P.S. I'm not entirely sure on how the communication even works between the board and the stepper in terms of signals and what not. I'm very new to steppers as a whole and can't really find much major help on the software side of it. Any resources on steppers as a whole would help too.

Comments

I use a small board from Pololu with an A4988 driver on it, made specifically for driving small bipolar steppers up to about 1.5 Amps per coil. All I have to do is tell it which direction and pulse the step input. I can also select full step and microstepping down to 1/16. Coil current is controlled by setting a reference voltage with an on board pot. It really simplifies operating a stepper.

Since this is your first experience with steppers, please take Hal's advice, and purchase a premade driver from Pololu, because it will greatly simplify a variety of issues.

Most bipolar stepper drivers have three main input pins, which are: Step, Direction, and Enable. However, most bipolar stepper drivers can have the Enable input bypassed, to help reduce IO requirements.

The Direction pin can also be bypassed, if you only need your stepper motor to rotate in one particular direction.

The main input pin for a stepper driver is the Step input pin. This Step pin requires a high signal for the stepper motor to make a step and this high signal will have a specified duration, being dependent upon the IC chip being used by the driver.

I use a small board from Pololu with an A4988 driver on it, made specifically for driving small bipolar steppers up to about 1.5 Amps per coil. All I have to do is tell it which direction and pulse the step input. I can also select full step and microstepping down to 1/16. Coil current is controlled by setting a reference voltage with an on board pot. It really simplifies operating a stepper.

Hello, and thank's for the comments. Here are the links to the specifications pages of the hardware I am using. The hardware of the solution isn't necessarily a problem although what you guys have linked me does shed light on some questions I had hardware wise. My problem is the programming with it. The pseudo code Bruce quickly jotted down was what my general idea of it would be after reading some articles on the issue. I guess it was a matter of what pins got which issues so I guess it would be both hardware and software. Thanks.

Bruce,
I do actually need the stepper motors to rotate in 2 directions, +x and -x. I am going to use the same technique for the other two axis. This is not for any CNC or Printer of any sort so it is going to be controlled manually via directional buttons or pots.

These drivers will allow you 1.5A per phase, without a heat sink or forced air flow, however they are rated for 2.2A with additional cooling. These drivers are about the best bang for your buck, to get the most out of your 2.0A per phase steppers. With additional cooling, you can run your steppers at full current, otherwise you will have to adjust the pot.

That h-bridge (L298) is quite capable of driving a stepper motor, although that board most likely will not do it, but to make life easier, the L298 should be paired with a L297 step translator (st.com/en/motor-drivers/l297.html).

I have a couple of the same driver that I recommended, so if you get these drivers, I can help you with the code to make your steppers sing.

It's not hard to drive a stepper. You need two H-bridges, each of which will have two control inputs, one for direction and one to energize. (Rolling your own and separately controlling the four transistors is not recommended, as the probability of a software bug shorting out the power supply is very high.)

You need to be aware of the drive waveform and the output patterns you need to form each step of the waveform with your H-bridge controller. I generally load the waveform steps into an array, and to step the motor I either increment or decrement the pointer and output the new pattern to the output port. You don't have to be too concerned with the pointer's actual value as long as you wrap it around forward and backward, which is really easy if you're using a four or eight step waveform because you can just bitwise AND the pointer with the appropriate mask after inc/dec.

So I got the driver you suggested Bruce. I really haven't gotten into the nitty gritty of it but how would I go about programming this thing in C/C++? If you're willing to tell me or point to a library I mean. I don't mean to be super needy if that's how I'm coming off.

localroger,
I am simply wanting to run the stepper like a motor in a linear actuator and control it via a variable pot so I can control the position manually. It's not meant to automated so I don't know if I really need to keep track of the steps it takes if I'm just wanting it to rotate until I tell it not to. I don't know if this makes any sense but hopefully it does. I will possibly upload a picture of what I'm wanting to do if I get the thing built before I figure out the programming but it is just a 3 axis mount for a laser vibrometer that would be moved using these steppers. I don't need to worry about the vibration of the motors because it will be stationary with the motors only holding the vibrometer in place when I'm taking measurements.

Oh and I was wondering with the programming how I would actually be able to set up a relationship between the "Height" of the table being elevated and the angle of the POT I am using. The variables I would think that would impact this would the threads per inch of the threaded rod I'm using, the max angle of the POT, and then the whole steps of the stepper. I'm wanting to see if I can relate steps to angle of POT. If I remember right then 1 step is 1 complete 360 turn of the pole (or whatever the terminology for the center metal pole protruding out the top of the stepper is).

I just don't know enough about how steppers work to actually be able to think about how I would even go about applying these ideas. I feel like once I/we get it figured out I will be able to do almost anything I want to. This is actually quite exciting to me because I've always wanted to do this but never actually got around to it or had the funds to do it.

I am simply wanting to run the stepper like a motor in a linear actuator and control it via a variable pot so I can control the position manually.

Is the idea for your design set in stone?

Controlling the position of linear actuator with a pot, sounds a little complicated. It's more like shooting from the hip, so to speak. If you are not attempting any kind of automation, then may I suggest the use of pushbuttons, instead of a pot. With pushbuttons, you could have two pushbuttons for each stepper, with one button rotating the motor clockwise and the other, rotating it counter-clockwise. Going back to pseudo code, it would look something like this:

Additionally, if you have access to keep it tied to a computer, you could issue positions serially. X100 Y200 Z300

Oh and I was wondering with the programming how I would actually be able to set up a relationship between the "Height" of the table being elevated and the angle of the POT I am using. The variables I would think that would impact this would the threads per inch of the threaded rod I'm using, the max angle of the POT, and then the whole steps of the stepper. I'm wanting to see if I can relate steps to angle of POT. If I remember right then 1 step is 1 complete 360 turn of the pole (or whatever the terminology for the center metal pole protruding out the top of the stepper is).

I think it is best to handle all of this in baby steps, otherwise you may become overwhelmed with information.

Stepper motors rotate in degrees, and the number of degrees per step, is referred to as the step angle. The stepper motor that you linked to above, has a step angle of 1.8 degrees. That means, with the stepper driver set to "full step mode", the motor will rotate 1.8 degrees, with every high pulse that it receives. The direction of motor rotation, of this 1.8 degree angle movement, will be determined by whether the direction pin is held high or low. With a 1.8 degree step angle, you must send 200 high pulses to the stepper driver, to get one full rotation of the motor in "full step mode".

If you are using screw driven linear actuators, as compared to belt driven actuators, the math is actually quite simple. Let's use 1/4-20 thread as an example. 1/4-20 thread has 20 threads per inch, so one full rotation of the thread will move you 1/20th of an inch and with 20 rotations, you will have moved a complete inch. Now to equate this to high pulses sent to the stepper driver, in "full step mode", you would simply send 200 pulses to move 1/20th of an inch or 20 * 200 pulses to move a complete inch.

YES!!!! This was another concept I had for the project early on. I figured the POT would be easier to control but I was just going to use buttons originally. This concept would work great though. I'm just confused now on the whole set up of the steps and how they are dealt with and the wiring involved with it. I have the steppers, the drivers, and the microcontroller, and will soon have the actual mount done as well, I just don't know how to go about applying the pseudo code you have provided as well as my ideas into an actual working code. The logistics of the code are pretty straight forward it is just the actual syntax and the wires to send them across that I am unsure of. But yes, your concept with buttons would work great!

Okay, so if I'm understanding this correctly if the rod is 20 threads per inch and it is 10 inches and 200 steps is 1 inch then I need to have 2000 steps to reach the top? And further more the programming would be pretty much (in C/C++ using the simpleIDE libraries)
loop (however many times I want)
high(pin number)
end loop
Or would I need a combination of pins being set to high or low like the pseudo code you originally gave me further up in the comments? I'm just wondering if this would be the correct idea or if I'm way off.

Unless you require some sort of absolute or relative position feedback, you could use Bruce's math and a couple of switches. Use the switches as end limits of travel. Then step one way until the switch opens, then drive the other way while counting the number of steps to the other limit switch. Dividing the distance traveled by the number of steps taken will give you the distance per step. Use his math to back check your results and convert desired distances into steps to turn. The step value can be used to drive a display readout as well. As an alternate, if you can long term store values, you can move to a start point and then an end point to "characterize" the distance of travel and use the switches as mechanical (emergency) stop limit switches.

Bruce,
Wow, I feel stupid now haha. And I am currently building and playing with motors. I know the design I want and have been prototyping with ways to build it for a few weeks now and I also know where I want the motors to be placed and what kind of placement I would like for the interface and what not but I am not putting them in place until I get the motor situation figured out thus not to create anymore confusion. So as a short answer I'm doing both separately.

Frank,
That sounds like a good idea and all but I figured I could use a method including two micro switches that are activated when the apparatus being moved hits one of the upper or lower limits of the bed kind of how some 3D-Printers work with their limits for the movement of the nozzle and heated bed or however they may be set up. I figure either way works and they are pretty similar so I don't think either way will be an issue.

I am currently working on C code for synchronizing four axes of motion, utilizing stepper motors, so I cannot set aside too much time for specialized code pertaining to your project, but I am still willing to help.

At this time, let's concentrate on getting one motor to run.

First thing I need to know is the required high pulse width.

Secondly, I need the IO pin number that you will be using for direction rotation.

Thirdly, I need the IO pin number that you will be using for providing the step pulses.

Bruce,
Honestly your helping a bunch just by correcting my mistakes and showing me the ropes so to speak. And what do you mean by the required high pulse width? And also I only need help with one motor. The rest will come naturally after I know how to use one. The pin for the step is 15 and the pin for the direction is 14. You honestly just need to show me the code for the steps and directions. I can do the buttons and interface and the other logistics involved. A simple example really is all I think I would need to get my stepper going on this hardware. Either way thank you guys SO MUCH for taking time out of your own projects and helping me out on this one! I really do appreciate it!

Okay, I have slapped together some code for you, but it is untested, however I think it should work with some possible minor modifications. You will most definitely have to adjust the overcome_inertia variable, and the high_pulse_width variable may need adjustment, depending upon the DRV8825 specifications. The high_pulse_width variable cannot be adjusted lower, but only higher.

Additionally, this driver was written for a single speed operation. Once the moment of inertia has been overcome, speed can be increased. This increase in speed is called ramping, and it is achieved by altering the overcome_inertia variable during the looping process, until the maximum or desired speed is obtained.

#include "simpletools.h"
int main()
{
// Set the desired number of steps
uint32_t required_steps = 40000;
// Set the desired direction of rotation.
// This variable can only be set to a
// value of 0 or 1. A value of 0 will
// turn the motor either clockwise or
// counter-clockwise, dependant upon how the
// motor coils are attached to the stepper
//driver, and a value of 1 will turn it in
//the opposite direction of 0.
uint8_t direction_of_rotation = 0;
// Establish the IO pin being used to communicate
// with the direction pin of the stepper driver.
uint8_t direction_pin = 14;
// Establish the IO pin being used to communicate
// with the step pin of the stepper driver.
uint8_t step_pin = 15;
// Depending upon inertia of the motor and/or
// the load attached to the motor, you should be
// able to vary the running speed of the motor
// by adjusting this variable. If the duration
// is too short, the motor will either wine, vibrate,
// and not move, or it will miss steps during runtime,
// and if the duration is too long, it will take
// forever to get from point A to point B, You will
// have to experiment with this variable, depending
// upon your motor, load, desired speed, etc...
uint32_t overcome_inertia = CLKFREQ / 5714;
// This variable must result in a value equal to
// or higher than 381, otherwise the system clock
// will roll over and cause unwanted delays.
// Additionally, the stepper driver IC (being the
// DRV8825 in your specific case) may require a longer
// high pulse width. Check the IC manufacturers
// specifications for the required pulse width.
uint32_t high_pulse_width = CLKFREQ / 209500; // 381
// Set the DIRA register of the direction_pin as an output.
DIRA |= 1 << direction_pin;
// Set the DIRA register of the step_pin as an output.
DIRA |= 1 << step_pin;
// Set the OUTA register of the direction_pin to match
//the desired direction of rotation.
if(direction_of_rotation == 0)
{
OUTA &= (~1 << direction_pin);
}
else
{
OUTA |= 1 << direction_pin;
}
// Spin the motor
while(required_steps != 0)
{
// At this location, drive the step pin high
// for the required high pulse width
OUTA |= 1 << step_pin;
waitcnt(high_pulse_width + CNT);
// At this location, drive the step pin low
// long enough to overcome the inertia of the
// motor or the load attached to the motor
OUTA &= (~1 << step_pin);
waitcnt(overcome_inertia + CNT );
// Decrement required_steps
required_steps--;
}
}

As mentioned, it is untested, but if it doesn't work, it is very close to what you need. You can also use the Propeller counters to drive stepper motors, which will result in a much higher running speed, because they don't require 381 cycles for the waitcnt to register. I learned that today by the way :)

Bruce,
"The timing requirements for minimum pulse durations on the STEP pin are different for the two drivers. With the DRV8825, the high and low STEP pulses must each be at least 1.9 us; they can be as short as 1 us when using the A4988."
Is this what you meant by High Pulse Width? I'm still a bit hazy on what you mean by that. I looked through the specs for it and couldn't really find anything similar except for this unless I just missed it.
Here is a link to the specs of the board: https://www.pololu.com/product/2133