Microprocessors Design Project
Professor Dr. Wahid
Due 01 12 2009
Submitted By Johnson, Keagan
Student # 10397530
Variable Speed Stepper Motor with Liquid Crystal Display
The project that we chose was to display the revolutions per minute of a stepper motor on a
liquid crystal display. The motor’s speed is controlled by a variable pot while the direction of rotation
is setup with a momentary switch. The LCD shows the RPM as well as its direction of rotation.
Liquid Crystal Display
DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 E RW RS
Motor Sharp IR Sensor
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
MCLR RA5 RA4 RA3 RA2 RA1 RA0
Duel Red LED
Main and Stop
Full Green LED
Key Features in Design
Some of the key features may not be obvious from the outside, but upon power-up the system
goes into stand-by mode. This has the motor stopped, direction in positive mode and the LCD
displaying RPM. Once the Start/Stop button is pressed the motor will start revolving and the LCD will
display the current RPM. The speed of the stepper motor can be adjusted by rotating a potentiometer
from its minimum to maximum. The direction can be changed by depressing the direction button. The
direction of rotation is displayed on the LCD as + for positive angular rotation and – for negative
The inside features really shine when examining the code. It has been developed for ease of
reusability and adaptability. Functionality is versatile in moving blocks, accessing subroutines and
making use of a look-up table. Altering specifications or including additional features would be
straightforward as only simple modifications to the code would be required to utilize more features. As
an example take programming a special function for turning 100 steps forward, 10 steps backward, etc.
This can be done by calling subroutines in a certain order. This device could easily be made to track a
location by changing the sensor followed by adding a tracking subroutine.
The code has been written to maximize the use of timers as well as the speed of the program.
Timers and interrupts are used rather than having items fire off after various delay’s that would
influence the whole program running time. These are triggered events such as the pulsing of the stepper
motor. Different start times can be set for different tasks. The buttons are setup as interrupts so
persistent poling is not necessary to check their status. The display can be setup to cycle only when a
change in status is detected. If more functions were added this would become advantageous to have
faster cycling time overall.
The code has been formatted with different areas to keep the code organized, simple and clear.
The initialization area is located first in the code. The initialization area only occurs at the master clear
activation and is only processed once when the program starts running. There are two main program
areas. Each is used by two different programmers. Careful attention was given to prevent interference
from one programmer to the other in the same file. With this, blocks can be added from either
programmer in their reserved sections with minimal adjustments. Memory locations and variable
names have to be coordinated, along with port use. Outside of the main program areas are subroutines
and look up table sections that can be called from the main functions. Some subroutines were made to
eliminate bulk in the main program for a more compact and clear code. These two sections will not be
cycled through unless called. Each programmer has their respective areas in order to maintain
separation for their contributions.
Pressing buttons can be troublesome. De-bouncing signals may be necessary in order to
minimize the error of the signal being on or off. The code can easily be set with a skip counter in order
for the button to remain inactive until it can be used again. The counter would simply increment every
time the timer overflows until a desired amount, then the button would be active again. This prevents
double activation in the place of a single intent. Currently the shortest delay from one cycle of the
program is more than 18ms. The comparator flag is checked once every program cycle. This helps
with de-bouncing. Making use of the delay from the program cycle ensures no extra delays are added
and keeps the overall program running faster. Holding the button down for longer periods will not
trigger more start/stop events. The button has to be released before it can be ready for triggering
another Start/Stop. A stuck button when the motor is in operation will not allow the user to start/stop
the motor. For safety, the system can be stopped by hitting reset. This will stop the motor in case of a
stuck start/stop button.
Rationale of choosing MCU
Initially, the PIC16F886 was to be used. Since we had a PIC16F876A readily available and it
had all the features required, it was chosen for the project. The key features needed to complete the
project were to have A/D converters, comparator modules, capture compare capabilities, two timers
and multiple outputs. There is also plenty of memory for the program we intended to implement. This
chip is ideal for learning purposes. It would not be used for production because microchip does not
recommend this chip for new projects.
Description of Major Units:
Stepper Motor (inc. H Bridge)
A stepper motor was taken out of a scraped photocopier. It has 6 leads. Two leads are common
and the other 4 leads connect to 4 separate systems in order to control steps. The systems are labeled
1A,1B,2A,2B. The simplest way to drive the motor is to pulse one system at a time in sequence. The
sequence is 1A,2A,1B,2B,1A, and so on. In order to reverse the direction of rotation this sequence is
simply reversed. The duration of each pulse determines the speed of the stepper. During testing, a
reliable maximum speed was attained at 5ms pulses. The stepper motor has 48 steps and was confirmed
by driving it with 48 pulses to get one rotation. The stepper motor and H-Bridge can be run at twenty
four volts direct current, but for this project it will be driven by a six volt battery, through an H bridge,
to achieve the higher power requirement than the MCU can provide.
Direction Control Switch
A momentary push button is used to control the direction of rotation of the stepper motor. The
direction will change immediately when the button is pushed. If the button is held down, no other
changes will be present. The button needs to be released in order to change the direction again. The
direction switch also changes the direction symbol on the LCD to its current rotation.
Start/Stop Control Switch
A momentary push button is used to control the stopping and starting of the stepper motor. The
state of the motor will change instantly on the pushing of the button. If the button is held down, no
other changes will be present. The button has to be released in order to be ready for the next start/ stop
activation. The Start/Stop also lights up the red light for stop and the green light for start. In industrial
machines, green indicates stopped and red is for running. The code could easily be changed to comply
with these standards.
The encoder sensor is used to measure the time between steps in the encoding disk. It activates
a timer reset on CCP1. The capture compare runs a timer that overflows, which is used to increment a
counter to see how long it takes. This number then gets converted to a more convenient RPM value to
be displayed on the LCD. The encoder is not setup to detect if the stepper is forced manually to turn in
reverse of it current state of rotation direction. It does however have the ability to detect missed steps to
an accuracy of 1/28 per turn, but this feature is not implemented at this time in this design. There were
problems getting the sensor to work due to a lack of data sheets for it, so we stuck with numerical
calculation we had been using.
The liquid crystal display that we used was a Hitachi HD44780. This display is a twenty-four
character by two line panel and can operate with either 4-bit or 8-bit protocol. There are enough pins
available from the MCU to make use of 8-bit mode. This made clocking in information faster and
simpler as there is no need to send the four most significant bits followed by the four least significant
bits after several instructions. The second line of the display was disabled for our use since the space
was not needed. After the LCD parameters were initialized, the characters RPM followed by a space
were placed in the display. These characters do not change and therefore were not included in the
character refreshing loop. The refreshing of the LCD includes the direction of rotation symbol as well
the numerical RPM value. There is no visible delay present on the screen when the motor changes
speed, direction, or if stopped.
A master reset switch is used to reset the board. If something happens that causes an error to be
present like the motor jams up or a switch fails, the board can be reset to the initial conditions. A failed
switch will not allow the board to start the motor after a reset. The master reset also is setup to clear the
LCD screen on reset.
There are two power supplies for the board. One supply is for the driving of the stepper motor
and the other is for running the board electronics. This is to ensure that the power draw from the
stepper motor will not affect the reliability of the PIC Microcontroller. Fluctuations in voltage to the
PIC MCU could mean a change in the reference voltage for the A/D converter and could result in a
altered RPM. The other benefit is that the motor can be run on a higher voltage than the board. Both
power supplies use the same zero potential.
Design challenges? How did you overcome it?
We remade connecters from old parts to use with our project. This created a problem for the
LCD screen. If the cable was bumped something would cross. This resulted in the LCD displaying
things we did not desire and in a different format than we had initialized the LCD to have. This
challenge was overcome by writing a reset for the display. It can also be reset by the external reset
button for the system. A new cable was also made with new parts to resolve the problem.
Careful planning was made to be able to use a twenty-eight pin PIC and still be able to have all
the options desired. To have the switches on interrupts and have the programming convenience of all
the 8 LCD data/address pins on port B made MCU selection tricky. An A/D converter and
Capture/Compare were also needed for the potentiometer and encoder sensor. Port A has the ability to
have 5 analog inputs. The inputs A0 to A3 have the ability to connect analog comparator modules with
interrupt capability. This is useful for the switches in the design. The problem was to get the two
switches working and the A/D converter working while keeping the last 3 pins available for digital
output. Initially, it seemed easy, but then we found that pin RA4 does not output anything when it is
implemented as digital out. It simply connects the output to ground. This meant a small change in
circuitry. Also, by connecting RA4 to ground on stop, it interfered with RA2 and RA5. This problem
still needs to be sorted.
Timing is the key. A large design challenge was to have the stepper motor run at a constant rate.
That is, to have each pulse be the same length in order to have a constant period. The pulse width
modulator was not an option because it generates a single pulse when we needed four separate pulses.
Also, if there would have been four pulses then it would not have been possible to stagger the pulses
easily. Lastly, the frequency would not have been possible to fine tune. To generate proper pulses with
variable frequency, a timer and interrupt were used to increment the sequence of the stepper motor.
This would bring the accuracy of frequency in steps to within a few cycles. The cycles are due to
interrupt service routine run time and execution of the step increment function. These cycles were
unavoidable, but considering the coarse resolution of the steps compared to the fine cycles, it was
considered insignificant. Since the Timer0 just keeps overflowing in the background, and generating
overflow flags and interrupts, the times for a pulse activation are always the same, and the cycles for
generating the pulse are always the same. Therefore, we have attained consistent pulse widths and
periods with no interference from the program running cycling time. The only variation is the time
required to exit the complete the current instruction before entering the Interrupt Service Routine. By
using this method, it allowed the pulses to be independent of the time required for varying loop lengths
in the main program.
Design shortcomings? How to make improvements on the design?
We had wanted to use a rotating arrow to show the rotation of the motor in either clockwise or
counter-clockwise direction on the LCD. Unfortunately two of the four arrows we needed were only
found on the European version of the character ROM for our display. The display does have the ability
to create custom characters and an attempt was made to develop the necessary arrows. The decision
was made to use +/- instead to show rotation. The rotating arrow would be an improvement of the
We could have used a more complicated algorithm for the stepper control to get finer resolution
of the steps, called half stepping. The encoder may also have been made to detect direction change.
This would have helped to show if the motor was being turned against its will, especially when dealing
with micro-steppers with much finer step resolution. The finer encoder resolution would have displayed
the result of a step.
The original plan was to use an infrared sensor to detect the steps of the stepper motor, but at
the last minute started encountering problems in getting it to work properly. Little was known about the
sensor and the voltage being used to operate it was in question. The sensor was taken from an old
photocopier. More time to experiment with the sensor and find useful information would allow us to
improve its functionality. The other option would be to get a new sensor where we know all of its
In choosing the PIC16F876A we had a lot of space in memory compared to what we actually
needed. The program for this design did not even use up the ninety-six bytes of general purpose
registers located within Bank0. This is not a problem, but a chip with less memory would cost less. The
current price of the PIC16F876A is $1.49 US. A comparable chip to the one we had on hand would be
the PIC16F882 which costs $1.16 US. For our design project this downgrade was not worth it as it
would cost more to ship than the difference in price. This would be an improvement though especially
if millions of copies of the project are produced and sold.
Program code with explanation (as comments)
See attached code.
Breakdown of tasks accomplished by each member
Daniel Lambert – Focused on stepper motor and inputs to MCU
Keagan Johnson – Focused on LCD display
Remaining work was completed together.