LifeMotion ControlProjects

Moco Update: Stepper Motor Controller Complete

After a grueling semester, and before a month-long stint helping the SES research group, I’ve managed to complete the first phase of my motion-controlled photography rig: setting up a pair of bipolar stepper motor controllers. This is the most important non-mechanical part of the project, as without control of motors there can be no awesome-tastic motion. I went over some preliminary planning in my first MoCo-related post, but I’ll go through my list of materials again as well as the general process of building and operating the controller in this post. And if you need a refresher on stepper motors… well… blah.

To start out, I purchased an L298N dual full bridge motor driver. Another option would be to use an SN7544 H-Bridge, as demonstrated on the Arduino site. However, I couldn’t find a wiring schematic for that particular implementation that included back-EMF protection diodes. Regardless, both IC’s are designed to power inductive loads (like a motor) and allow you to do bi-directional rotation on a DC motor, or control a stepper motor. The only problem with the L298N is that it comes in a 15-lead Multiwatt package, aka something you can’t plug into a breadboard. Sparkfun sells a breakout board for $3 intended specifically for this IC… but that costs more than the chip itself, so I opted to skip it and work out my own ridiculous wiring methodology.

The L298N functions basically as such: It has 4 inputs and 4 outputs. Each input corresponds to an output, and by powering these pins in a specific sequence, you can advance a stepper motor (see Wikipedia picture below).

There are variations on the 1-2-3-4 stepping scheme, like 12-23-34-41, that increase torque by engaging more coils of the motor but they complicate the wiring and also the control. Apparently one drawback is that it does not guarantee absolute position as well as the 1-2-3-4 scheme does (do correct me if I’m wrong).

If you take a look at the L298 schematic for a stepper motor (see snippet above), you’ll notice a few other bits of analog fun, some capacitors, some resistors, and some diodes. I used 0.1uF 50V 105C radial electrolytic capacitors, which serve the purpose of power-conditioning your source voltage. Should there ever be a loss of cabin pressure a sudden spike in power consumption that a battery can’t keep up with (like if you power up the stepper motor), the capacitors will help you out until your power supply has steadied out (we’re talking no longer than a millisecond here). If you’re using a bench power supply, then the capacitors probably aren’t as essential.

1 OHM 1W 1% metal film resistors are for the express purpose of giving you a voltage drop to measure, should you desire to know how much current your motors are drawing. If you don’t care, then I’m pretty sure you can skip the resistors. It shouldn’t matter.

Lastly, 1N4937 600V 1A fast recovery diodes were used in order to keep the stepper motors from regurgitating electricity back into the L298N. For those of you that don’t know, inductors (or any coils of wire) act like pitchers or water. If you put a current through an inductor, it’s like stirring the pitcher with a spoon. If you suddenly stop, the water wants to keep moving. This behavior makes inductors potentially damaging to circuits if they are of sufficient size… er… inductance. Diodes are one-way-valves that prevent electricity from spilling back out of the stepper motors once you have ceased putting energy into its coils.

I purchased all of these parts from Tayda Electronics, and I mention this not to shamelessly promote them, but because they are much cheaper than Sparkfun and the like for “raw” materials. Even with shipping prices, which can be waived with a timely coupon code from their Facebook page, you can buy materials for 4 motor controllers for the price of one pre-built one. AND, you’ll learn something making it instead of buying pre-fab circuit boards…

Now, everything I mentioned above is pretty straightforward. It’s just a matter of reading the datasheet/schematic right. If you follow those instructions, you’ll be able to control a stepper motor using 4 pins from an Arduino. And in fact, the Arduino’s built in stepper motor library has functions made specifically designed to interface with a motor over 4 pins:

void stepper(int steps, int pin1, int pin2, int pin3, int pin4)

Since I planned on using at least 2 stepper motors, optimistically 4 or even 5, I devised a way to only use 2 digital I/O pins per motor on my Arduino. Otherwise I would run out of pins on the Arduino, which only has 12, unless I multiplexed the commands somehow. The solution should be rather simple to any veteran of a basic digital circuits class. There are 4 output patterns you desire, which can be represented by 2 binary bits. If you map these outputs to binary numbers 0 through 3, you will be able to command any of the 4 outputs using two digital pins. I used some AND gates and some inverters to accomplish this. So for example, to command the first “phase” of a stepper motor, an AND gate hooked up to Input 1 would look specifically for “NOT A, NOT B”, where A and B are the digital pins from the Arduino. I basically made a decoder from basic IC’s and saved myself about $0.25. Even more valuable though is that I can re-purpose those gates for anything else I would desire in the future instead of being stuck with a decoder. Me = stingy pragmatist.

For each motor controller, I needed one 74HCT08 7408 IC Quad 2 Input Positive AND Gate and half (really one sixth) of a 74LS04 Hex Inverter IC. In case you weren’t doing the math for everything else, you’ll also need 2 capacitors, 2 resistors, and 8 diodes per motor controller.

… And that about covers it. The performance of the controller using 5 Volts as my source voltage is about 3 RPS, 180 RPM. I am able to command 1 motor step every 7 ms (48 steps per revolution), any faster and the stepper motor just vibrates uselessly. If you up the voltage (my motors are rated for 12V) you can force the motor to step faster, thus allowing you to command more steps per second. But I didn’t feel like testing that out, my goal is to run the system at between 5-9V, so it can be battery powered. I’ll attach a video clip of the controller in action, and will make another post in a little bit about the Arduino Code to run it. And yes, I am using my homemade lab bench power supply for these tests.

3 thoughts on “Moco Update: Stepper Motor Controller Complete

  1. Unfortunately I don’t have anything compiled for 8051, just the Arduino PDE.

    It’s actually quite poorly coded, in hindsight, but since I’m not using any libraries, perhaps you can take something away from it.

    /*
    Stepper Motor Test _ 2 Wire to Bipolar
    Written by: Winston Moy
    */

    int up = 1;
    int cycle = 1;

    void setup() {
    // initialize the digital pin(s) as an output.
    // Pin 13 has an LED connected on most Arduino boards:
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(13, OUTPUT); // For LED
    Serial.begin(57600); // For debugging statement stream
    }

    void loop() {
    if (up==1){ // Counter-clockwise
    if (cycle >= 5)
    cycle = 1;
    write2Bits(cycle, 2, 3);
    write2Bits(cycle, 4, 5);
    Serial.print("Cycle: ");
    Serial.println(cycle);
    cycle++;
    }
    else{ // Clockwise
    if (cycle < = 0) cycle = 4; write2Bits(cycle, 2, 3); write2Bits(cycle, 4, 5); Serial.print("Cycle: "); Serial.println(cycle); cycle--; } // DEBUGGING STUFF: Flash LED as motor rotates. if (cycle<3){ digitalWrite(13, HIGH); // set the LED on delay(9); } else { digitalWrite(13, LOW); // set the LED off delay(9); // wait for a second } } void write2Bits(int num, int lowerPin, int upperPin){ switch (num) { case 4: digitalWrite(lowerPin, LOW); digitalWrite(upperPin, LOW); break; case 2: digitalWrite(lowerPin, HIGH); digitalWrite(upperPin, LOW); break; case 3: digitalWrite(lowerPin, LOW); digitalWrite(upperPin, HIGH); break; case 1: digitalWrite(lowerPin, HIGH); digitalWrite(upperPin, HIGH); break; } }

    The output in on two pins. I'm basically writing 0 through 3 in binary, but you can break that out to 4 discrete pins for better compatibility with a normal stepper motor controller.

Leave a Reply