Projects Research & Design Hub

Stepper Motor Emulator (Part 2)

Written by Miguel Sanchez

Motor Shaft Feedback

In Part 1, Miguel covered how to use closed-loop motors as a replacement for stepper motors. Here, in Part 2 he explains how to get feedback from a motor shaft and how the control loop should be tuned for proper operation.

In Part 1 of this article series, I detailed how stepper motors used in 3-D printers can be replaced by closed-loop DC motors to achieve more reliable prints. This month, I’ll start by introducing a way to sense shaft position to provide the feedback signal to the control loop. I’ll also cover motor drive and system tuning.


A popular way of calculating the number of cars that travel on a certain two-way, two-lane road is to place a couple of rubber tubes across the street. When a car drives by, each tube is pressed twice (assuming four wheel cars). Let’s focus on the first hit of each tube, assuming the tubes are just a few inches apart. The car’s front wheels press the first tube, let’s call it A, and moments later presses the second tube, B. A control box attached to the tubes registers each one of the hits. If it detects one hit on A and another on B, the counter increases by one. That happens a second time with the rear wheels, so each car causes two increases of the counter. Furthermore, the time between leading edges of pulse A and pulse B can be used to determine the car’s speed. But a car riding on the other lane, which is opposite our first example, will cause the firing of pulse B first and later of pulse A. That will act upon a different counter that measures the cars being driven in the other direction.

Incremental optical encoders use a slotted disk connected to the motor shaft and two phototransistors to detect the light of an LED source. The slots in the disk will block one, two, or none as the disk spins with the motor. What this detectors creates is a square wave of frequency proportional to the rotational speed of the motor. But the two signals are phase-shifted 90°, therefore the quadrature name (see Figure 1). These two signals from the detector are typically called A and B too. The sequence in which they evolve tell us which is the direction of motor motion, and the pulses are counted to know the exact angle of the motor at every moment.

Depending on our control logic, we can resolve as many different angles as there are slots in the optical disk. That is the simplest case we can call 1×. But we can double the resolution if we consider both the trailing and leading edge of signal A. That would be 2×. And if both edges of both signals A and B are accounted for, we can get four times the angular resolution or 4×.

If running short of interrupt signals, we can just use one interrupt signal associated with one encoder input and read the value of the other within the interrupt service routine and still get a very decent angular resolution. But there is another trick in the Atmel ATmega’s bag. It turns out that Atmel considered that certain applications may require more interrupt pins than the two external interrupts on the ATmega328. So they added a feature call Interrupt on Pin Change that can be extended to any I/O pin. This makes it possible for any pin to cause an interrupt, although there is a limit of one interrupt vector per output port, so a few pins have to share the same interrupt code. This feature helps ease the pain of needing three interrupts but only finding two. And, it opens the door for yet another cost-saving measure: What if a single controller could handle two motors instead of one? This way the cost of the controller may be split between the two-axis budget.


Using an H-bridge is the most common solution for controlling a DC motor that needs to rotate in both directions. There are several low-cost choices for small DC motors like the old STMicroelectronics L298 dual full-bridge driver that contains not one but two independent H-bridges. That’s beneficial because the drive electronics for powering two axes is less than $3. Another affordable choice is to use DMOS transistors instead of bipolar like a Toshiba TB6612FNG. After all, the motor maximum current is only 0.46 A.

Depending on the availability of output pins, I have followed two different approaches. The former uses two pins, one set to low level and the other operates as a PWM signal. The latter approach uses three pins for each motor output, using two outputs to set the bridge polarity (in1 and in2) while a third output is a PWM signal used to operate on the bridge enable signal.


Beyond the names, PID is a common solution that may require a degree in engineering to covert it in full detail. But let us focus only on the example of the speed of a car.

At any given moment, you see the car speed on the dashboard and you mentally compare it with the speed at which you want the car to be cruising. If current speed is too low, you accelerate. But if you notice speed is too fast, you brake. Pushing a pedal is the output action that happens after checking the current speed and comparing it with the desired speed. The pressure you put on a pedal depends on the difference between the actual speed and the desired speed. This is the idea of a proportional control. The output of the system is just a proportion of the error signal (the difference between actual and desired speed).

If the car speed is below the desired speed for a while, the trip time will increase. If we want the trip time to remain the same, we need to speed up the car even though maybe now it is running at the desired speed. This is the goal of the Integral action that accounts and compensates for errors that have happened in the past.

The last component, the derivative, has to do with the changes in the error signal. If there is an increment of the error signal, then the output will increase (braking or accelerating) to compensate faster for that change. While the derivative does not predict the future, it definitely acts much sooner than the Integral action when the error changes quickly. Too much derivative action will mean a driver with a very quick foot.

The main problem with PID controllers is finding the proper proportion for these three actions. If chosen properly, the car will arrive on time without speeding. But if we have them wrong, the system may become unstable and stop doing what we want.


Armed with an Arduino Pro Micro, an L298 dual H-bridge board, and a couple of Mabuchi 370 motors with built-in 448 PPR incremental encoders I started to write the code. On the Arduino site, I learned about the excellent PID library by Brett Beauregard, and while writing the code does not appear a difficult task, the devil is in the details, and thankfully Brett had those ironed out for us. Coding was quite simple, as it was mostly an endless loop where the encoder measurement is provided to the library and then the controller output is applied to the motor.

The simplest approach, which is what I used, is to use the PID output to drive a PWM signal directly to the H-bridge of the motor. Output signal polarity would select the H-bridge polarity too. A couple of approaches work. You can use three output pins—two for polarity selection and a third one for PWM. Alternatively, you can use just two outputs: while one remains low, the other works as a PWM signal and keeps the bridge always enabled. The latter approach uses fewer pins but is harder on the motor as it prevents motor coasting, switching from powering the motor to braking it, which may age it more quickly.

Together with the Arduino PID library I discovered the PIDAutotune library. But unfortunately my attempts of getting a controller to work with self-tuning capabilities did not succeed. So it is up to the user to figure out the tuning parameters for their motor controller.

Once I got the control loop running on two axes, I connected a couple of motors to my Prusa i3 printer and after tuning each motor I attempted a few test prints. I was pleasantly surprised that it worked, even more so when I purposely pushed the print head away from its location to see it returning to the next point correctly as soon as it was released. I published a short video on that quickly got more than 10,000 views (not bad for a video with no cats on it) and I published the code on So far, more than 9,000 people have downloaded the code.

FIGURE 1 The three modes of counting encoder pulses
The three modes of counting encoder pulses

While stepper motors require no special tuning (other than current setting), a closed-loop motor requires the adjustment of the different gains of the PID controller. It is just three positive values that when set right provide the desired type of response. But until they are properly adjusted, the motor behavior can be far away from desirable or correct.

I hope that with more time I will learn how to do it better. In fact, I already have some suggestions on YouTube I need to test to hopefully get the controller to tune itself. But in the meantime, I can provide you a few tips.

First of all, remember that you can use Arduino’s serial monitor to interact with the controller. The letter “H” will give you the list of available commands. Do not forget that lines need to be ended at least with linefeed character (0x0a). You can set P, I, and D values with just the letter followed by the number you want that gain to be set to.

You want to set the Proportional gain as high as possible, but not so high that the system oscillates around the target location. A little bit of derivative gain can help you reduce the ringing around target location, but more than that and you have your system oscillating too. And finally the Integral gain can help you to reduce the steady error.

I have a simple tool that causes a small step in the system reference, measures the system’s response, and generates a graphical representation (see Figure 2). It repeats endlessly while you can change the values by pressing the capital letters P, I, or D to raise these values or the lowercase letters p, d, or i to reduce them. Hopefully, that tool can help you get the work done sooner.

Figure 2 System response to a step input, where reference goes from 0 to 100.
Figure 2
System response to a step input, where reference goes from 0 to 100.

While the initial aim of the project was to keep the cost low, the position control puts a significant amount of stress on the small DC motors. Each time a new movement is done, high current is needed to start the motor and later to stop it, while relative less current is needed while coasting. Being the motor used to perform thousands of start-stop cycles per printed part seems to shorten the lifespan of motor brushes significantly. Therefore, it seemed obvious to wonder about other possible choices in the motor selection. After all, stepper motors are brushless themselves, so brush aging was not a problem for them, but it may be for brushed DC motors.

What other type of motors can be used? A relatively new invention, brushless DC motors first appeared in the early 1960s but became practical during the early 1980s due to the availability of permanent magnets. These motors have no brushes and coil commutation is handled by solid-state devices; therefore, there are no components to wear other than motor bearings, which puts them in a similar condition as stepper motors in terms of aging.

Brushless motors sound like a good solution, but that comes at a cost, which again puts in jeopardy the viability of a solution based on brushless motors. I discovered that many low-power brushless motors come with a built-in drive electronics. That is really good news. Although the brushless motor can be more expensive, by having the drive electronics built in, there is no need to have any additional electronics and the motor can be directly controlled by the PID controller with no further expenses. On the other hand, even if the brushless motor solution costs a bit more than that based on a brushed DC motor, it may still be cheaper in the long run, as brush failure in a small DC motor will require the entire motor to be replaced.


By publishing the code and details about the project, I get messages from people asking for help. They’re usually stuck on a simple detail like encoder counting in the opposite direction. I helped everyone I could and I got some feedback from people that succeeded controlling their own DC motors either for printers, CNC machines, or other applications.

Later, I received a kind offering from Printrbot CEO Brook Drumm, who wanted to help the project and donated a Printrbot Simple to serve as a test bed. Unfortunately, adapting the motors to that design gave me more than one headache. And while I managed to get it working, I did so without the printer having a working z-axis. I am working on a fix, but the thing is so compact that it’s a challenge to get it done.

Another unexpected input came from Italian reprapper Mauro Manco who kindly sent me a NodeMCU board with the tip that there was glue code for ESP8266 SoC being capable of running Arduino code. So, after a bit of testing, I managed to substitute the humble Arduino Pro Mini for a ESP12E, which brought 32-bit processing power plus Wi-Fi communications capability to my motor controller. Luckily, all the control code runs without a change, but unfortunately the EEPROM code serves no purpose as that SoC does not contain EEPROM storage. Still, the ESP12E carrier board can be had for less than $2, which I found impressive.

Moti project lead developer Nicholas Stedman showed me how a magnetic encoder was working great for his RC servos, so I requested some samples of the AMS AS5600 magnetic rotary sensor chip (see Photo 1). I have been surprised by how well this technology works. While the AS5600 is designed to replace the volume potentiometer of hi-fi equipment, it does a great job at providing a low-cost solution to obtain 12-bit angle measurement. And while it may not work at very high RPM (the manufacturer does not provide that figure), it seems to work perfectly for my position control project. And it does so below $2. What is best, the whole sensor is just a 3-D-printed shaft adapter for the magnet plus a small PCB for the SOIC-8 sensor. And being able to produce the encoder separated from the motor, many more choices open up to lower the cost of the motor.

Photo 1 AMS AS5600 magnetic rotary sensor chip
Photo 1
AMS AS5600 magnetic rotary sensor chip

One thing I wanted when I started was to keep the cost low and use widely available products. And when I found what I thought was a very interesting motor, I learned the motor was no longer available a few weeks later. So I set out to find a motor manufacturer with a suitable motor model that could be available for the long term. Fortunately, a former student referred me to Cheshire Electric Co. in Taiwan and we have been testing different combinations. So I want to thank Ping-Shih Wang, PhD, and his team for their valuable input and samples.


I am happy to report that the initial goals of the project have been met. Brushless motors seem the way of the future, but a cheap brushed DC motor can be used in a 3-D printer. The use of the step and direction interface is just a temporary solution. We can obtain better results if motion planning takes into account motors that require an array of position and speed values. If we couple that with the power of current 32-bit processors, we might see a single processor solution that controls the four axes with their PID loops plus 3-D printer command decoding. 

Read Part 1 Here

B. Beauregard, Arduino-PID-Library, Ver. 1.1.1,
———, “Improving the Beginner’s PID—Introduction,” 2011,
ESP8266 Community Forum, “ESP8266 Arduino,”
HomoFaciens, “Rotary Encoder: How to Build a Digital Servo Using an Arduino and Photo Sensors,”
Texas Instruments, “Stepper Motor Basics and Control—How It Works,”
Youmagine, “DC Motor Closed-Loop Control Software,”

AS50xx Magnetic Position Sensors
Arduino Pro Mini
Arduino |
ESP8266 Wi-Fi Chip
Expressif |


Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.

Note: We’ve made the Dec 2022 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article
+ posts

Miguel Sánchez (PhD, Computer Science) is an associate professor at the Polytechnic University of Valencia, Spain. He has worked in the Department of Computer Engineering since 1988.

Supporting Companies

Upcoming Events

Copyright © KCK Media Corp.
All Rights Reserved

Copyright © 2024 KCK Media Corp.

Stepper Motor Emulator (Part 2)

by Miguel Sanchez time to read: 12 min