Sie sind auf Seite 1von 103

12/11/2015 E-Bike Motor

and Controller
ECE 480 Team 9

Tyler Borysiak | Myles Moore | Alex Sklar | Stephen Dunn | Joshua Lamb
MICHIGAN STATE UNIVERSITY COLLEGE OF ENGINEERING
ECE 480 SENIOR CAPSTONE DESIGN COURSE
Executive Summary 
 
In a novel entrepreneurial enterprise, Dr. Pauliah and his sister Ms. Pauliah of the Sunrise 
Orphanage in Bobbili, India, are seeking a product that can be manufactured and sold to 
help support the orphanage and add a low­cost medical clinic to the existing facility.   
 
The product they are seeking is an electric tricycle, which is in high demand in India and 
around the world. Typically, electric vehicles are powered through the use of a costly DC 
motor. To combat this problem, ECE 480 Team 9 utilized an inexpensive automotive 
alternator that replaced the DC motor, providing high efficiency and increased torque at 
wider ranges of speed.  
 
Team 9 has developed and integrated a novel motor­controller circuit, consisting of a 
high­speed sensor and a microprocessor into the novel alternator design. The high­speed 
sensor measures the magnetic field produced by a uniquely polarized magnet mounted on 
the rotor shaft of the alternator. This sensor sends precise angle information to a 
microprocessor. With this data, the microprocessor increases the efficiency of the electric 
motor by applying precise power pulses at optimal angles within the motor as it rotates. 
Efficiency is further maximized by automatically controlling the magnetic field in the 
rotor. Having the ability to control the rotor field made it possible to significantly 
improve stopping performance with the use of regenerative braking. 
 
After running multiple design tests, it was proven that the use of the automotive 
alternator and the motor controller circuit did in fact increase efficiency, provide wide 
ranges of speed, and apply regenerative braking to improve stopping performance. 
 

Page 1​
 of 103 

 
Not only will this design be used to power an electric vehicle, it also has the potential for 
use in other applications that require electric motors. These applications include electric 
wheelchairs, industrial forklifts, and numerous industrial applications. 

 
Acknowledgment 
 
The completion of this design would not have been possible without the assistance of the 
Team 9 facilitator Professor Virginia M. Ayres, Ph.D., Team 9 sponsor Mr. Stephen 
Blosser, Assistive Technology Specialist for the Resource Center for Persons with 
Disabilities (RCPD), Piotr Pasik for helping the team gather a suitable tricycle for a 
design, Professor Timothy Grotjohn, Professor Lalita Udpa,  the guest speakers in class, 
Roxanne Peacock, and all of the assistance from the MSU College of Engineering ECE 
Shop. 
 
Throughout the design process, Professor Ayres has met with Team 9 frequently and 
offered suggestions and guidance in order to successfully complete the project and the 
deliverables. She has been a great mentor and has helped the team stay on track with the 
design process and has helped the team produce quality work. 
 
The team’s sponsor, Stephen Blosser, was always available to offer guidance to the team. 
He has helped the team gather parts, discuss design specifications and deliverables, and 
bring new ideas and innovations into consideration. 
 
This project would not have been possible without all of the help that was provided. 
Team 9 is very grateful and honored to have worked with such a great group of people. 
 
 

Page 2​
 of 103 

 
Table of Contents 
 
1 Introduction and Background…………………………………………………...05 
2 Strategic Goals and Design Requirements……………………………………...08 
2.1 Customer Requirements Analysis………………………………………08 
2.2 Budget…………………………………………………………………..15 
2.3 Initial Project Management Plan………………………………………..18 
3 Technical Description…………………………………………………………...22 
3.1 Hardware Design………………………………………………………..22 
3.1.1 Automotive Alternator…………………………………………..22 
3.1.2 MOSFET Switching Circuit…………………………………….25 
3.1.3 Battery Connections and Protection…………………………….38 
3.1.4 Problems and Adjustments……………………………………...40 
3.2 Microcontroller and Software Design…………………………………..45 
3.2.1 Microcontroller…………………………………….……...…....45 
3.2.2 AMS Sensor…………………………………………………….48 
3.2.3 Throttle………………………………………………………….53 
3.2.4 Software Algorithm……………………………………………..54 
3.2.4­A    Core Design Principles…………………………….....54 
3.2.4­B    Details of the Algorithm……………………………...56 
4 Data Testing…………………………………………………………………......62 
4.1 Revolutions Per Minute………………………………………………....62 
4.2 Input Power……………………………………………………………...64 
4.3 Torque…………………………………………………………………...66 
4.4 Efficiency……………………………………………………………......68 
4.5 Scope Measurements………………………………………………….....69 
4.5.1 Common MOSFET Gate Pulses………………………………...69 

Page 3​
 of 103 

 
4.5.2 Rotor Gate Pulses……………………………………………….71 
4.6 Design Specification Achievements………………………………….....72 
5 Design Issues…………………………………………………………………....73 
6 Final Cost, Summary, and Conclusions………………………………………...75 
Appendix 1 Technical Roles, Responsibilities, and Work Accomplished…………..78 
Appendix 2 References……………………………………………………………....84 
Appendix 3 Software Reference Code…………………………………………….....85 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Page 4​
 of 103 

 
Chapter 1 ­ Introduction and Background 
 
Michigan State University is affiliated with the Sunrise Orphanage and its future clinic 
through Asian Aid USA, a Christian nonprofit organization that is committed to making a 
difference in the lives of children and people in poverty. Asian Aid High School students 
in Jaipur, India learn electronic circuit design from Stephen Blosser, an Assistive 
Technology Specialist at the Resource Center for Persons with Disabilities. Mr. Blosser is 
an honorary ambassador volunteer with orphanages in the area and helps choose 
technology for the orphanage members to work with. He has designed an electric tricycle, 
which is in high demand in India and around the world. This tricycle could be 
manufactured by student employees such as those residing at the orphanage. Students at 
the orphanage sponsored by Asian Aid will benefit from the learning experience that the 
manufacture and sale of these tricycles 
can provide, as well as benefitting from 
the part­time employment.   
 
Mr. Blosser’s original design included 
the use of a DC motor to power the 
tricycle. The DC motor performed well, 
but it was too expensive to be viable for 
the proposed application. This motivated 
a search for an effective cost­saving 
measure.  

It has been previously demonstrated that an automotive alternator can be converted to a 
motor and used in place of a standard DC motor. Most alternator conversions apply a 
constant current to the rotor within the alternator to create the rotor fields, but by having 

Page 5​
 of 103 

 
to manually supply current to the rotor, the design efficiency is limited. A design that can 
automatically control the field current to the rotor only when necessary would maximize 
the motor efficiency.  
 
Typically, automotive alternators are used to convert a vehicle’s mechanical energy into 
electrical energy that can be used to power the electrical devices in the automobile. This 
eliminates the need to stop and charge the battery. The normal application is executed by 
applying a constant DC field current to the rotor shaft which then produces a magnetic 
field around the core. This magnetic field couples to the set of stator coils fixed to the 
shell of the alternator. This coupling produces AC current in the windings. These 
windings are placed 120 degrees apart, therefore producing three separate phases. In 
order for this current to be used by the electrical devices in the car, it needs to be 
converted into DC current. This is done by the diode rectifier circuit. Diode rectification 
produces a pulsed DC voltage that can be used to supply the devices in the vehicle. Some 
of the more critical automotive components have internal filtering circuits to further 
smooth out the pulsed DC voltage. Figure 2 below shows a circuit diagram of an 
alternator circuit with a 6 diode rectifier for full­wave rectification. 

Figure 2: Automotive Alternator Schematic 

Page 6​
 of 103 

 
 
The automotive alternator application described above is for an alternator acting as a 
generator in order to supply electrical devices in a vehicle. For this project, the goal was 
to convert this automotive alternator into a motor in order to drive an electric vehicle. In 
order to achieve this, both the rotor and the stator need to be pulsed at the optimal angles. 
This requires the development of more complex hardware and software in order to drive 
the unusual motor configuration.   
 
The Team 9 design makes use of a high­speed sensor that measures the magnetic field 
produced by a uniquely polarized magnet. This sensor holds the potential to increase 
efficiency of the motor by sensing the exact location of the rotor shaft which updates the 
microcontroller and applies precise power pulses for a short period of time at the most 
optimal angles. In order to apply pulses to the stator coils at specific times, a stator 
switching circuit is needed to act as a motor controller. P­channel and n­channel power 
MOSFETs are used to turn on and off stator coils when directed by microcontroller logic. 
The same circuitry is needed for the rotor in order to apply field current to the rotor shaft 
at optimal angles. In order for pulses to be initiated, an external Hall­effect throttle is 
needed to control the amount of pulses applied to the stator and rotor, which will then 
increase the revolutions per minute.  
 
Team 9 proved to be very successful designing a motor and a controller circuit that meets 
the sponsor requirements and specifications outlined in Chapter 2 below. This design has 
the capability to revolutionize personal electric transportation globally and make a 
difference in the lives of many people. Additionally, it has been proven to be a low­cost, 
reasonably efficient, and rugged alternative to an expensive DC motor. Through the 
eventual production of this design, funding will be generated for the medical clinic as 
well, helping to support Asian Aid and improved healthcare. 

 
Page 7​
 of 103 

 
Chapter 2 ­ Strategic Goals and Design Requirements 
 
2.1 Customer Requirements Analysis  
 
The first step taken during the product planning phase was the analysis and evaluation of 
the project requirements given by the customer or sponsor. To effectively plan goals and 
an efficient critical path, a design proposal needed to be identified quickly. The first step 
in understanding the sponsor’s requirements was to set up an interview to discuss how the 
design has the potential to positively impact society and to discuss design goals. Team 9 
learned that the most important goal was the ability to make the design as inexpensive as 
possible. Other important goals were to maximize efficiency and power consumption by 
pulsing the rotor and stator coils, achieve a wide range of speeds, increase the torque at 
low speeds, and implement regenerative braking. In order to understand and implement a 
design that met all of the requirements, multiple analysis techniques were performed. One 
technique was the development of a FAST diagram in order to understand and define the 
product functionality and the scope of the project. Figure 3 below is the Team 9 FAST 
diagram. 

Page 8​
 of 103 

 
Figure 3: E­Bike FAST Diagram 
 
The basic function of the design is to use the alternator to control the electric vehicle’s 
speed. This is done by either speeding up or slowing down the alternator. In order to 
speed up the alternator, the throttle needs to be applied. In order to speed up the alternator 
shaft, current needs to be applied to the stator and rotor at the quadrature angles. This is 
done using the microcontroller and the software logic to switch the MOSFETs that are 
connected to the stator and the rotor. In order to slow down the electric vehicle, the brake 
lever needs to be applied. Slowing down the alternator is achieved by slowing down the 
alternator shaft. This is done using regenerative braking. Regenerative braking is 
executed by drawing current from the alternator to charge the battery that is supplying the 

Page 9​
 of 103 

 
circuit and the alternator. This can be done by controlling the field using the 
microcontroller and the software. 
 
Another technique that was utilized was the House of Quality analysis technique. This 
analysis method proved to be quite useful because it helped Team 9 understand the 
Critical Customer Requirements ­ CCRs ­  for the design. This helped prioritize the 
project needs and gave direction for which specifications to look for when selecting 
components. The House of Quality matrix is shown in Figure 4. 

Figure 4: House of Quality Analysis 
 
This type of analysis was very helpful because it was a tool used to assist in data based 
decision making. It also helped to reduce design uncertainty because by understanding 

Page 10​
 of 103 

 
the customer requirements and how the quality characteristics or measures affect them. It 
was easy to clarify how the data collected would help determine a best­approach. It was 
also a good tool to determine which measurements would prove to be of higher 
importance for selecting a design that best matches all of the specifications. From the 
House of Quality, it was determined that efficiency and speed were the easiest customer 
requirements to analyze using the quality characteristics. One of the harder requirements 
to measure was the reliability. It was also noticeable that high output power and power 
dissipation had a strong inverse relationship because the more output power of the 
alternator that is measured, the lower the power loss or dissipation. Some of the other 
strong positive relationships as seen in the house of quality were high rpm and current 
draw, high current draw and output power, and high output power and high torque. 
Another useful piece of this type of analysis was being able to prioritize customer 
requirements. The most important customer requirements for this design were cost, 
efficiency, speed, and reliability. 
 
Once the main project goals were prioritized, project design functionality planning could 
begin.  To make critical design component selections, decision matrices were developed 
which allowed for the comparison of different options in relation to the established 
design goals and sponsor requirements. The first major decision encountered was the type 
of motor to be used with the prototype. From the motor decision matrix in Figure 5, an 
automotive alternator clearly met the goals for the project over other available options, an 
AC motor or a brushless DC motor. As can be seen from the decision matrix below, the 
alternator is significantly better than its counterparts with regards to cost and speed. 
 

Page 11​
 of 103 

 
 
Figure 5: Motor Decision Matrix 
 
The next major design decision the team faced was the choice of microcontroller that 
would provide the speed, number of GPIO pins, and floating point operations desired. To 
more easily analyze the possible options, another decision matrix was created and shown 
in Figure 6.  From this comparison, Texas Instruments was chosen over the Raspberry Pi 
and the Arduino as it best supported the team’s design goals. 
 

Page 12​
 of 103 

 
Figure 6: Microcontroller Decision Matrix 
 
The final design decision encountered was the selection of a rotary position sensor 
needed to monitor the position of the rotor shaft within the alternator. The sensor decision 
matrix shown in figure 7 outlines the criteria used to make the selection of an AMS 
sensor over an Avago sensor. 

Page 13​
 of 103 

 
 
Figure 7: Sensor Decision Matrix  
 

 
 
 
 
 

Page 14​
 of 103 

 
2.2 Budget 
 
One of the key constraints of this project was developing a design that is both cost 
effective and efficient. The most expensive portion of the project are the automotive 
alternators, which cost around $20 to $30. The use of these alternators instead of 
brushless DC motors will save at least $60 per motor. Like most of the parts that are 
required for this project, the automotive alternators were already provided to the team; 
therefore the cost is not tracked in the $500 budget, but will be included in the cost per 
unit budget.  Additional parts that were needed include the diametrically magnetized 
magnet, the AMS AS5132 rotary sensor, the p­channel and n­channel power MOSFETs, 
terminal blocks, power recovery diodes, and an external throttle.  Other hardware circuit 
components such as color coded resistors, NPN and PNP transistors, zener diodes, 
capacitors, heat sinks, and header pin connectors that were required for the MOSFET 
switching PCB were not included in the budget since they were obtained from the ECE 
shop at no cost.  These circuit items were included in the cost per unit budget. 
 
In order to have the opportunity to implement design changes throughout the design 
process, extra components were ordered just in case components were damaged during 
testing. The table below shows the cost of all of the components ordered by Team 9 
throughout the design process. The total prototype design cost was $332.54, which is 
within the $500 budget for the semester. 

Page 15​
 of 103 

 
Figure 8: Total Prototype Design Costs 
 
The table above does not include the cost of the PCB fabrication, 10 AWG wiring used 
for the stator coils and battery connections, two 12V batteries, and all other hardware 
components mentioned above.  This is because these components were obtained from the 
sponsor or from the ECE shop.  A majority of the prototype design costs were shipping 

Page 16​
 of 103 

 
costs. For example, the shipping cost for $0.38 magnets was greater than the product cost. 
For the per unit production cost, the cost was calculated without the shipping costs of the 
parts. 
 
A per unit production cost was also calculated below to show the cost to make one 
prototype E­bike motor and controller.  

 
Figure 9: Cost of One Production Unit 
 
It is easy to see that the cost of one production unit is significantly lower than the cost to 
make the prototype design.  This is due to the fact that additional components were 
ordered even though not all of them were necessary.  For future production, terminal 
blocks like those used in the prototype design will not be necessary for attachment to the 

Page 17​
 of 103 

 
PCB from the stator coils.  Prices for components such as the AMS sensor, recovery 
power rectifier, p­channel and n­channel MOSFETs, 10 AWG wire are much cheaper if 
bought in bulk quantity.  For a production setting, all of these components will be 
purchased in bulk. 

 
2.3 Initial Project Management Plan 
 
The initial project timeline consisted of seven main phases. These phases include project 
definition, research of new designs, development of conceptual designs, initial prototype 
preparation, initial testing, initial prototype construction, and final design construction. 
 
The project schedule and project timing was organized using a Gantt chart.  This Gantt 
chart displayed the seven main phases, which were further broken down into tasks. 
These tasks consisted of a start date and an end date.  The project schedule consisted of a 
critical path.  Tasks on the critical path could not be started unless the task before was 
completed.  These tasks were the most critical to the project because any delay caused a 
delay to the whole project.  It was important to try to shift the critical path.  Below is the 
Team 9 initial Gantt Chart. 
 
 
 
 

Page 18​
 of 103 

 
 
 
 

 
 
 

Page 19​
 of 103 

 
Figure 10: Initial Project Gantt Chart 
 
For the most part, the project Gantt chart was followed exactly as noted above throughout 
the design process. The only modification came near the end of the design process in the 
“Construct Final Design” phase. Since the team decided to go with one PCB design, the 
“design PCB layout” and “PCB fabrication/soldering” tasks were moved to the 

Page 20​
 of 103 

 
“Construct Initial Prototype” phase. The project prototype and final design were very 
similar, and the PCB was fabricated before testing efficiency. This was because in order 
to run and test the high current portion of the circuit, a PCB needed to be fabricated. A 
breadboard could not be used for these tests. 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Page 21​
 of 103 

 
Chapter 3 ­ Technical Description 
 
3.1 Hardware Design 
 
3.1.1 Automotive Alternator 
 
The automotive alternator is perhaps the most important component or piece of the 
design. Without the alternator, there would be no source of mechanical power to run the 
electric tricycle. After selecting an automotive alternator to be the motor for the design, it 
was important to select the correct stator coil orientation that best fit the design. The 
figure below shows a common automotive alternator and its main components.  

Figure 11: Automotive Alternator Components 
 
The main hardware components that Team 9 utilized within the automotive alternator are 
the rotor and the stator. The rotor of the alternator consists of a coil of wire wrapped 
around an iron core. DC field current produces a magnetic field around the core. The 

Page 22​
 of 103 

 
stator is a set of coils fixed to the shell of the alternator. Magnetic field from the rotor 
couples to the stator coils producing current in the stator windings. These stator coils are 
placed 120 degrees apart, producing 3 separate phases.  
 
The automotive alternators used in this design are of the hybrid­brushless variety, having 
no expensive, internal rare­earth permanent magnets. Instead, the motors require that a 
small amount of current be passed through brushes to a coil in the rotor in order to 
magnetize it. Current is then applied to the outer stator coils in order to induce an 
electromagnetic force to turn the rotor. The stator has 36 coils around its perimeter. The 
test alternators have 36 coils that are wired into 3 phases connected in a “delta” pattern 
such that each phase has 12 coils and each coil is separated by 10 degrees around the 
stator. 
 
The first step in the hardware design process was to determine the most effective way to 
orient the stator coils in the alternator. As mentioned above, the alternator was originally 
connected in a delta configuration. Delta configuration allows for lower voltage but 
higher current. The figure below shows a delta connection and a Wye connection with a 
common. 

Figure 12: Wye Connection with a Common (Left) and Delta Connection (Right) 

Page 23​
 of 103 

 
 
In order to precisely pulse only one stator coil at a time, the alternator was re­oriented to 
a Wye connection with a common wire. This was less resistive than the delta connection 
and allowed for more current to pass through the stator windings providing higher RPMs. 
 
The first test that was run with the alternator before any hardware or software was 
developed was a connection of the rotor field coil to a 12V battery, and the connection of 
each stator phase to either 12V or ground. A current limiting resistor of 1Ω was placed 
from the active stator coil to ground in order to limit the current and the torque in the 
alternator. This was implemented strictly for testing purposes and was removed in the 
final design.  
 
This test was performed in order to find the alternator stepping states. This was a critical 
design procedure because the software code uses this stepping theory in order to know 
which stator coil to pulse in order to rotate the rotor shaft. When these connections were 
made, each stator phase rotated 10 degrees when connected to the batteries. This covered 
30 degrees in 3 phases and by activating the same three phases with the opposite polarity, 
the next 30 degrees could be covered. This pattern then repeats 6 times every 60 degrees 
to make a full 360 degree rotation. Because of the Wye configuration of our motor, one 
end of each stator coil is exposed as an external connection. These three external 
connections are arbitrarily labeled Black, Green, and Red. The other end of all three coils 
are connected together and exposed as a single “common” external connection. The 
following table describes the connections required to turn on on the 3 stator coils to rotate 
the rotor 60 degrees in one direction. 
 
 
 
 

Page 24​
 of 103 

 
 
 

State  Common Connection  Pole Connection 

1  12 volts  Black to ground  

2  12 volts  Green to ground 

3  12 volts  Red to ground 

4  ground  Black to 12 volts 

5  ground  Green to 12 volts 

6  ground  Red to 12 volts 
 
Figure 13: Stator Coil Sequence 
 
After the 12V stator switching tests, the rotor resistance was calculated. Since 12V was 
used to supply the rotor, the current draw was measured at the rotor. This current value 
was found to be 3A, so the resulting rotor resistance with 12V supplied to the rotor is 4Ω. 
 

3.1.2 MOSFET Switching Circuit 
 
After the alternator pulsing states were understood, the next step in the design process 
was to develop a MOSFET switching schematic to interface with the microcontroller and 
the software in order to pulse specific stator coils with current at specific moments in 
time. P­channel and n­channel MOSFETs have the capability of turning on or off 
depending on the gate to source voltage difference. The figure below shows the circuit 
symbol for a p­channel MOSFET. 

Page 25​
 of 103 

 
Figure 14: P­channel (Left) and N­channel (Right) MOSFETs  
 
In order to understand the application of these MOSFETs in a power electronics setting 
like this design, it was important to understand how they can be turned on and off. For 
the hardware portion of the initial demo, a breadboard circuit was constructed after power 
MOSFETs were ordered that simulated the switching of current to different stator coils. 
The schematic for this simple MOSFET switching circuit is shown in the figure below. 

Figure 15: Initial Demo MOSFET Switching Circuit 
 
The p­channel MOSFETs are the top row of MOSFETs in the circuit diagram with their 
sources connected to the 12V supply line. The drains of the p­channel MOSFETs were 
connected to two LEDs (one red and one green) in parallel and oriented in reverse to 
simulate the stator coils. If the top LED turned on, then it was known that current was 

Page 26​
 of 103 

 
flowing from the left side of the circuit to the right side, and vice versa for the other LED. 
The n­channel MOSFETs are the bottom row of MOSFETs with their sources connected 
to the ground line and their drains also connected to the stator coil LEDs. As mentioned 
earlier, in order to turn on the MOSFETs, a voltage needed to be applied to the gates of 
the MOSFETs. For the p­channel MOSFETs, the Vgs, or the gate to source voltage needs 
to be greater than 3V to turn on. Therefore, in the demo Team 9 shorted the gate and the 
source together to turn the p­channel MOSFET off. In order to turn it on, the gate voltage 
was driven by 5V. For the n­channel MOSFETs, they were turned off by shorting both 
the gate and the source to ground. In order to turn them on, a voltage of 5V was applied 
to the gate. For example, if the goal is to turn on LED A in the circuit diagram above, the 
p­channel MOSFET labeled “1” needs to be turned on, and the n­channel MOSFET 
labeled “2” needs to be turned on. This lets current flow from the source of “1” through 
the LED “A” and down to ground, or the source of “2”. This is how each stator state is 
pulsed with current and activated. The figure below is a picture of the initial demo setup. 

Figure 16: Initial Demo Setup 
 
After successfully completing the initial demo and understanding how to switch states 
and pulse the LEDs with the MOSFETs, the next step in the hardware design process was 
to design a schematic that would allow for a 0V or 3.3V input from a microcontroller to 

Page 27​
 of 103 

 
control the gates of the MOSFETs, signifying which MOSFETs are on and off. To 
achieve this, the circuit schematic in the figure below was developed for each of the 
stator coils. 
 
 

Figure 17: MOSFET Gate Circuit 
 
The 3.3V inputs from the microcontroller are on the left side of RE1 and RE4 in the 
schematic above. When 3.3V was applied to either of these resistors, it would turn on the 
corresponding MOSFET. The final design consisted of four of these circuits, one for each 
stator phase and one for the common phase. 
 
The next step in the design process was to construct a prototype of the gate circuit and 
test the functionality. This was done at low voltage and current levels and on a 

Page 28​
 of 103 

 
breadboard. The circuit in the schematic above was constructed. Only one stator phase 
and the common phase was constructed because the rest of the switching circuitry will 
have identical components and functionality. Below is a picture of the MOSFET gate 
prototype circuit on a breadboard. 

Figure 18: MOSFET Gate Circuit Prototype 
 
In order to simulate the microcontroller code, a 3.3V power supply was connected to RE1 
or RE4 depending on which MOSFET was to be activated. The remaining simulated 
microcontroller inputs were grounded. The circuit was powered with 12V from another 
power supply and the LEDs correctly simulated the activation of the stator coils. 
 
The next step, and arguably the most critical hardware step, was the transfer of the 
schematic and circuitry onto EAGLE software in order to fabricate a PCB. This was done 
by first creating a schematic file and drawing the circuit connections. The first step was to 
duplicate the gate MOSFET circuit for all of the stator phases. Once this was completed, 
a connection to the batteries and the terminal blocks needed to be accounted for. There 
were no footprints in EAGLE for high current connections, therefore terminal block 

Page 29​
 of 103 

 
footprints needed to be ordered and created in EAGLE. Below are the terminal blocks 
that were used for the design. 

Figure 19: Terminal Blocks on PCB 
 
In order to pulse both the rotor and the stator, rotor pulsing circuitry was also critical. 
This was done using the same concept as the n­channel portion of the stator pulsing 
circuit. The rotor circuit schematic is shown below. 

Figure 20: Rotor Gate Schematic 
 

Page 30​
 of 103 

 
It is easy to see that there is no 12V connection to the emitter of BJT14 like there is in the 
stator switching circuit. This was a simple design error that was easily fixed by soldering 
a wire from the emitter to the 12V source line on the PCB right after fabrication. 
 
Now that the stator and rotor circuitry was developed, the next step was to develop a 
power supply circuit in order to step down the voltage from 12V to 5V and 3.3V in order 
to power the microcontroller and the remaining peripherals such as the AMS sensor, the 
LCD display, and the hall­effect throttle. Below is a high­level block diagram of all of the 
hardware used in the design. The block diagram proved to be very helpful in the 
development of the rest of the peripheral circuitry and the connections to the 
microcontroller in EAGLE. 

Page 31​
 of 103 

 
Figure 21: High­Level Block Diagram 
 
In order to support the MOSFETs and protect them during avalanche mode or 
regenerative braking, the hardware design needed recovery power rectifiers from the 
source to the drain of each p­channel MOSFET. These MOSFETs contain a protection 
diode inside from the source to the drain, but with the amount of current used in the 
design during avalanche mode, these would be damaged. These diodes are referenced in 
the appendix 2 section. 
 

Page 32​
 of 103 

 
To make sure that the microcontroller pins would not erroneously send pulses to both the 
p­channel and n­channel MOSFETs simultaneously, diodes were inserted from the 
collector of the NPN transistors to the 1kΩ output of the microcontroller. This makes sure 
that the MOSFETs of the same phase do not turn on at the same time. 
 
Another design implementation that occurred during the development phase was 
placement of the 9V zener diodes from the source of the p­channel to the gate in order to 
keep the gate to source voltage a constant 9V difference when the MOSFET is activated. 
The same zener diodes were also placed between the gate and the source of the n­channel 
MOSFETs for the same reason. 
 
The next step of the hardware design was to develop a power supply circuit in order to 
convert 12V from the battery into 5V for the LCD display, throttle, and the AMS sensor. 
Another portion of the power supply needed to step down 5V to 3.3V in order to power 
the microcontroller. The circuit that was used is the power supply circuit from the earlier 
ECE 480 labs and is shown in the figure 22 below. It contains two voltage regulators and 
5 capacitors. 

Figure 22: Power Supply Circuit 
 

Page 33​
 of 103 

 
Node 1 of IC1 is the 12V input from the battery supply. Node 3 of IC1 is the 5V output 
that goes to the peripherals mentioned above. Node 3 of IC2 is the 3.3V output that goes 
to the microcontroller. 
 
After connecting the power supply circuit, the next step was to connect the peripheral 
circuitry together. In the design, it was important to make sure that the spacing of the 
microcontroller header pins was exactly 1.5 inches apart so that the microcontroller could 
successfully connect to the PCB. Header connectors were also needed for the connection 
of the AMS sensor, the throttle, and the LCD display. These were placed conveniently on 
the board so that they could easily be connected and would not interfere with other 
connections. 
 
The rest of the schematic was wired together and double checked to make sure that all of 
the correct connections were made. The final prototype schematic from EAGLE is shown 
in the figure below.  
 
 
 

Page 34​
 of 103 

 
Figure 23: Final Prototype Schematic 
 
After correct routing of the schematic, the next step was to transfer the schematic onto a 
PCB. This was also performed using the EAGLE software. In this phase of the hardware 
design, it was crucial that the high current and low current sections of the PCB were 
separated and understood. In order to accomplish this, the high current traces from the 
drains of the MOSFETs to the terminal blocks for the stator coils were given a width of 
0.254 inches in order to sustain the high amount of current. These traces were routed on 

Page 35​
 of 103 

 
the top of the board. On the bottom of the board, the low current traces for the MOSFET 
gate circuitry and the connections to the peripheral devices were routed using a width of 
0.024 inches. Several vias were needed in order to route some of the traces. A figure of 
the final prototype board is shown below. 

Figure 24: Prototype PCB Design 
 
The surrounding copper on the PCB that was not used for routing or for components was 
the ground plane for the design. One of the terminal block pins was connected to this 
plane from the negative terminal of the supply battery. 

Page 36​
 of 103 

 
 
Once the PCB was fabricated in the ECE shop, the through­hole components needed to 
be soldered to the PCB. It was important to add wires from the top of the board to the 
bottom of the board at all of the vias. Additional copper wiring was added to the drain to 
stator connections as well as the 12V source line on the PCB. This was so that the current 
limit was never reached and the traces were able to handle at least 70A of current. The 
figure below shows the copper wire added to the physical PCB. 

Figure 25: Copper Wire on the High Current Traces 
 
After the soldering was complete and all components were placed onto the board, the 
next step was to make the battery and stator connections to the terminal blocks and to 
develop a circuit protection system. 
 
 
 

Page 37​
 of 103 

 
 

3.1.3 Battery Connections and Protection  
 
The diagram below shows how the connections were made into the terminal blocks from 
the battery and from the alternator. 

Figure 26: Battery/Alternator Connections 
 
The terminal block on the left has connections to ground (negative terminal of the 
battery), negative slip ring of the rotor, positive slip ring of the rotor, and the 12V battery 
positive terminal. The 12V positive terminal and the positive slip ring of the rotor were 
shorted together since both the rotor and the circuit are both supplied with 12V. The 

Page 38​
 of 103 

 
second terminal block is for the connection to each of the stator coils. There are 4 phases 
in the Wye­connected alternator with a common. These were named black, green, red, 
and common. 
 
In order to make sure that a secure and rugged connection was made to the battery 
terminals, eyelet connectors were used. Other hardware protection techniques were made 
as well. In order to make sure that only a specific amount of current was drawn by the 
circuit for the prototype, a 20A circuit breaker was placed at the negative terminal of the 
battery. 
 
Another protection requirement was to make sure that the MOSFETs were protected from 
heat. To meet this requirement, large metal heat sinks were attached to the drain tabs of 
each MOSFET. The figure below shows these heat sinks. Later in the design process, a 
heat sink was also added to the n­channel MOSFET in the rotor circuit.  
 
 

Figure 27: Heat Sinks Attached to MOSFETs 
 
In order to protect the entire PCB, a metal box was constructed so that the PCB and all of 
the components are protected from any external electrical interference. The figure below 
shows the metal box with the PCB inside. 

Page 39​
 of 103 

 
 
 
 
 

Figure 28: Enclosure with PCB Inside 

 
3.1.4 Problems and Adjustments 
 
One of the first issues that occurred during the hardware design was that the footprints for 
the MOSFETs utilized different pin configurations than what the team was using for the 
design. In order to adjust for this, the team had to modify the existing footprint in order to 
have the pins oriented as “Gate, Drain, Source”. In the future, the MOSFET footprints 

Page 40​
 of 103 

 
should also be modified so that the individual pins have more separation. This would 
prove to make soldering and placing the components much easier. 

 
The same issue occurred with the NPN and PNP transistors. This was fixed in the same 
way by modifying the component footprints in EAGLE so that the pins were oriented as 
“Emitter, Base, Collector”. 
 
Another hardware issue that came up was that the microcontroller was not reading the 
throttle as accurately as it should have been. This was due to an incorrect voltage divider 
resistor value from the throttle output to the microcontroller input. This was adjusted and 
resolved by changing the resistance from 22kΩ to 2.2kΩ.  
 
From running tests on the gate of the red phase stator circuit, a bad diode was also found 
by running a continuity test at both of the diode leads. This was quickly replaced and the 
circuit worked properly. 
 
During initial testing, the microcontroller was erroneously resetting. The issue was 
resolved by placing a 1uF capacitor from the reset pin on the microcontroller to ground, 
and placing a 1kΩ pull­up resistor to 3.3V to fix the issue. 
 
Throughout the hardware design process, the team faced two major design issues. The 
first issue was that the common p­channel MOSFET was not functioning properly. This 
was a direct result of the n­channel common fall time being too long because the gate 
circuit had too much resistance. Below in Figure 29 is a graph of the p­channel gate pulse 
(top) and the n­channel gate pulse (bottom). 
 
 

Page 41​
 of 103 

 
 
 
 

Figure 29: P­Channel and N­Channel Common Gate Pulses 

 
This problem was resolved by altering the resistance values of the common gate circuitry. 
All of the 10kΩ resistors in the common p­channel and n­channel gate circuitry were 
changed to 1kΩ. All of the 3.3kΩ resistors in the same circuit were changed to 330Ω 
resistors. These alterations fixed the p­channel common MOSFET issue. 
 
The second major hardware design issue was that the 12V battery source line was 
producing a lot of noise in the gate circuitry and at the microcontroller pins. This is a 
common problem in many circuit designs. Below in Figure 30 is a graph showing the 
noisy supply voltage (second from bottom) and the noise generated at the microcontroller 

Page 42​
 of 103 

 
pin (second from top). The top channel is the p­channel common gate pulse and the 
bottom channel is the n­channel common gate pulse. 
 
 
 

Figure 30: 12V Supply Noise Issue 
 
To fix this issue, the team added 100uF (50V) capacitors to the 12V source line on the 
PCB right before the connection to the gate circuits and the microcontroller. A diode was 
also added in series to the 12V supply line after the MOSFET connection and before the 
gate circuit connection. This diode limited the current to one direction. A 100uF capacitor 
was also added to the 12V terminal block connection to further limit the 12V source 
noise. The graph in Figure 31 shows the supply voltage (top channel) with the noise 

Page 43​
 of 103 

 
significantly reduced. It also shows a working p­channel common gate pulse (middle 
channel) and a working n­channel common gate pulse (bottom channel). 
 
 
 
 

Figure 31: Graph Showing Design Issue Resolution 
 
 
 
 
 
 
 
 

Page 44​
 of 103 

 
3.2 Microcontroller and Software Design 
 
3.2.1 Microcontroller 
 
A microcontroller was integral in the design of the circuit as it allowed an interface 
between custom developed software and the hardware circuits. A microcontroller is a 
computer chip that integrates a microprocessor, memory, hardware modules and physical 
interfaces into one package. The microcontroller provided the pulses for the circuit to 
turn on and off the MOSFETs to drive the motor. The microprocessor processes the 
calculations for the pulsing of the stator in real time. The hardware modules interface 
with the physical pins on the chip to allow communication with external peripherals. 
These modules include analogue to digital converters, pulse width modulation generators, 
digital pulse generators, digital interfaces and timers.  
 
The microcontroller to be chosen had a series of requirements that needed to be met. The 
microcontroller needed to be sufficiently fast. The upper limit of the rotational speed for 
the motor was initially thought to be 10,000 rotations per minute. This would translate to 
3,600,000 angles per minute or 60,000 angles per second. The microcontroller would 
need to read the data at a speed of 60kHz. As data is usually transmitted in bytes (8 
digital bits), the microcontroller would need to be able to take in multiple bytes at this 
rate, calling for a higher clock rate. The microprocessor also needed to be able to make 
calculations on which motor phases to enable at each of these angles, increasing needed 
processing power. The microprocessor needed to be able to calculate fractions in real 
time to be able to make more accurate calculations with no loss in speed. These 
calculations can be simulated on the microprocessor itself, however, a Floating Point Unit 
(FPU) allows the processor to offload fractions and thereby decimal values to the unit to 
improve the speed of microprocessor. The microcontroller needed to be energy efficient 

Page 45​
 of 103 

 
to lower the overall power consumption. It needed to be able to have at least 19 hardware 
interface ports to allow an interface to the MOSFETs, a throttle, a sensor, and an LCD for 
testing. These hardware interface ports are called General Purpose Input Output (GPIO) 
ports. The MOSFETs needed 9 ports, 2 for each phase, 2 for the common and 1 for the 
rotor. The sensor needed 3 ports, the throttle needed 1 and the LCD needed 6. 
 
Many microcontroller choices were available. The top 3 most commonly used 
microcontrollers are available from Texas Instruments, Raspberry PI and Arduino. Each 
had strengths and weaknesses, which required a starting point be set for research. The 
first requirement that was chosen to research was the floating point unit. A floating point 
unit is part of the architecture of the chip itself, 
rather than a module added by specific 
manufacturers. A search of low­cost 
microcontrollers from these manufacturers show 
the Arduino does not have a floating point unit. 
The other two manufacturers have solutions 
with a floating point unit. These 
microcontrollers are based on the Acorn RISC 
Machine (ARM) Cortex family of 
microcontrollers. 
 
With an architecture, the next requirement was 
low cost. The lowest cost solution came from Texas 
Instruments. The Texas Instruments board has a   Cortex M4F microcontroller which is 
the lowest in the family of Arm Cortex microcontrollers with integrated floating point. 
The Texas Instruments boards range from $13.03 to $13.49 for the lowest cost models. 
The microcontroller used for this design is the Texas Instruments TM4C123GH6PMI. 
This microcontroller runs at a max clock speed of 80MHz, which allows the chip to be 

Page 46​
 of 103 

 
able to make the required calculations in real time. This microcontroller has a hibernation 
module that allows the chip to improve power usage by going into hibernation during 
periods of inactivity. This microcontroller has up to 43 GPIO ports, exceeding 
 ​
requirements. This microcontroller also has a great deal of documentation,​that is 
referenced in the appendix below, which contributed to the development phase of the 
software. For prototyping purposes, a TI Launchpad TM4C123GXL evaluation board 
was used. This board has the chosen microcontroller on a pre­soldered board with easy to 
use pins for testing. Another iteration of the design would use the microcontroller 
soldered directly to the board.  
 
The microcontroller evaluation board was integrated into the circuit by using rows of pins 
that the board could plug directly into, as it has connectors on the bottom that accept the 
pins. These connections can be seen in the hardware section. Header pins were routed to 
the various devices on the board that needed a direct connection to the microcontroller. 
Groupings of pins are dedicated to the MOSFETs, an LCD, a throttle, and an AMS 
sensor. The board design allowed for the microcontroller to be easily removed and 
reprogrammed safely. The evaluation board also allowed for the pins to be tested through 
the use of the pins on the top of the board. Integration required enabling of the general 
purpose output pins for digitally pulsing the pins. These pulses drove the pins at a voltage 
of 3.3V for a digital 1 and 0V for a digital 0. This pulsed the bipolar junction transistors 
in the circuit to turn on and off the MOSFETs. The throttle required the enabling of an 
analogue to digital converter that used the voltage output of the throttle to provide 
percentage values for the software.  
 

 
 
 
Page 47​
 of 103 

 
3.2.2 AMS Sensor   

 
To sense the rotational angles of the rotor shaft of the alternator, a specialized sensor was 
required. In a DC brushless motor, a Hall­effect sensor is used to measure the magnetic 
field from the rotating magnets on the rotor.​
 Hall sensors work on the Hall­effect 
principle that when a current­carrying conductor is exposed to the magnetic field, charge 
carriers experience a force based on the voltage developed across the two sides of the 
conductor. As the permanent magnets in the rotor pass the sensor, a voltage is read which 
determines the location of the field in relation to the sensor. ​
These sensors are built into 
the design of the DC motor. The sensor to be used would need to be external to the 
device to reduce costs and lower future manufacturing complexity. A solution to this 
problem is to use a magnet affixed to the end of the shaft and a sensor placed externally 
to read the field as the magnet spins. The sensor for this application is a magnetic rotary 
encoder. A magnetic rotary sensor uses an array of Hall­effect sensors to measure the 
field as a diametrical magnet spins a few millimeters from the center of the array. by 
using such a device, the angle of the shaft in relation to the stationary stator can be read 
by the microcontroller. 
 
Multiple companies manufacture magnetic rotary sensors. The 
Austrian Micro Systems (AMS) AS5132 and Avago Technologies 
AEAT­6600­T16 are two solutions available​
. To choose from the 
available options, a set of requirements were made. The first was 
cost, the AMS chip , the Avago chip costs $8.04 for a 
production chip, the AMS is $2.79 for a production chip. 
The second was for the sensor to be easily purchased, as 
the sensor would need to be purchased from different nations, both companies provide 
easily available parts. The third was for the chip to be able to handle very high rotations 

Page 48​
 of 103 

 
per minute as the motor would have the potential to rotate at thousands of rotations per 
minute. The AMS is able to read 72,900 rotations per minute (rpm), while the Avago can 
read 30,000 rpm. The fourth was for the chip to be able to read at least 360 discrete 
angles, the AMS chip reads 360 angles, the Avago reads 65,536. Finally, the availability 
of a development board for testing was weighed. The AMS chip is available as a 
development board, while the Avago is not. The chip chosen for the task is the AMS 
AS5132 chip shown in Figure 34. 

 
Figure 34: AMS Block Diagram 
With a chip selected, the next step was to read the data from the sensors. Initially, the 
format used by the AMS sensor appeared to follow a subset of the Synchronous Serial 
Interface standard. This subset, called Microwire, was developed by the National 
Semiconductor Corporation. The interface defines a way that information is sent and read 
by the chip. The way the chip first received instructional data to enable either reading or 
writing to the chip and then communicated data afterwards closely resembled this format. 
After testing, it was found that although the chip appeared to use Microwire, the chip had 
a slight offset between the instruction and the data right after the 0 bit of the 8­bit control 
shown in figure 35.

Page 49​
 of 103 

 
 

 
Figure 35: AMS Sensor Data, Upper is Microwire, Lower is Tested Pulses 
This led to a custom software solution that sent the control data to the chip and sent 
received the data from the chip when the microcontroller is able to read it. This data was 
read in a binary format that corresponded to 360 angles, from 0 to 359. With these values, 
angle data could be used within the software to trigger pulses of the stator coils based on 
which grouping of angles the sensor fell within, the optimal quadrature angles. 
 

Page 50​
 of 103 

 
The needed optimal quadrature angles were measured using the angle data from the AMS 
sensor, displayed on an LCD, and the force of the motor when it was locked into one of 
the phases using a test setup shown in figure 36. To do this, the rotor was powered 
directly from the battery, to produce full field. One of the stator coils was also powered 
directly from the battery, to produce full field. This locked the rotor into a stationary 
position. The angle was then read, this is the center of each of the 6 poles for the phase. 
The rotor was then turned and the force exerted by the turning of the rotor was measured 
on a scale. This force was due to the tendency of the field to want to stay locked into the 
pole position. As the rotor was turned further, the scale showed the force to increase as it 
moved away from the pole. The force was measured at each of the poles and the 
maximum was found to be approximately 12 degrees away from the pole shown in 
figures 37 and 38. With this data there was a starting point for implementing quadrature 
angles within the software. 

Figure 36: Picture of Quadrature Angle Measurement with Initial Sensor Integration 
 
 
 

Page 51​
 of 103 

 
 
 

Figure 37: Quadrature Data 

Figure 38: Pole Averages with Quadrature Value 

Page 52​
 of 103 

 
 
 
The final design has the sensor mounted directly to the casing of the alternator. A 
pre­soldered board was used for this 
design. The chip on the board is placed 
directly over the magnet, which is bonded 
to the end of the rotor shaft as shown in 
Figure 39. This design would ease future 
manufacturing as only minor alterations to 
the alternator would be required. 
Integration into the circuit required 
certain GPIO pins to be enabled a 
physical interface for the software. 

 
3.2.3 Throttle   

 
A throttle was needed to provide a user interface to the motor. The throttle needed to be 
rugged and bike mountable. The throttle selected by Team 9 is the Electric Scooter 
Throttle, Type­2 by Parts for Scooters shown in Figure 40. This throttle uses a Hall­effect 
sensor, instead of the variable resistor sometimes found 
in electric throttles. Twisting the throttle varies the 
strength of the magnetic field adjacent to the sensor, 
which sends a corresponding voltage between .74V and 
4.15V to the microcontroller. By using the hall­effect 
sensor, the throttle is more rugged and reliable as 
there are no moving electrical components, in 

Page 53​
 of 103 

 
contrast to the variable resistor which can wear over time.  

 
3.2.4 Software Algorithm 
 
3.2.4­A Core Design Principles 
 
One of the largest tasks in the development of the motor controller was the development 
of  an algorithm suitable for correctly and efficiently driving the power MOSFET 
hardware in order to operate the motor. The final solution provides a central hub 
connecting the throttle, AMS rotary position sensor, and power MOSFET circuitry in a 
meaningful and intelligent manner. Throughout the development of the software portion 
of the project, there were four core software design principles essential to the immediate 
and continued success of the project: Correctness, Maintainability, Rapid Development 
and Speed of Execution.  
 
Above all, correctness was the most important value. Without a correct algorithm, the 
motor controller would be largely useless. This is a well known, but very important 
concept within computer science and engineering in general. Only after a correct solution 
was found did we focus on the other three design principles.  
 
Maintainability was important because the code for this motor controller will very likely 
have a long service life and see several different programmers and maintainers in future 
iterations. Real­world maintainability was achieved through the use of good coding 
practices including the appropriate use of commenting, good coding structure, consistent 
formatting, and clear and concise naming. Additionally, much care was taken to not 
“over­engineer” the code. In other words, in order to make the code more easily 
understood by future programmers, simpler code structures and algorithms were 

Page 54​
 of 103 

 
employed whenever complex algorithms and code structures were not needed for 
correctness or speed of execution.  
 
The capability for rapid development was needed due to the tight time constraints 
imposed on the project. It was known from the beginning of the semester that the length 
of the semester was going to be a limiting factor on the capabilities of the software. 
Importance was placed on getting a working solution as quickly as possible so that 
iterative improvements could be implemented continuously until the end of the semester. 
Rapid development was achieved in several ways. First, it was decided that the software 
would be written in C++, a language intimately familiar to all of the team members 
collaborating on the software. Second, it was decided that the development environment 
used would need integrated debugging support so that problems with the code could be 
quickly and decisively corrected. The development environment that was eventually 
chosen (Code Composer Studio, by Texas Instruments) allows the code running on the 
microcontroller to be paused and stepped through line­by­line while, at the same time, 
showing the contents of  memory and other variables. This last capability proved 
invaluable when troubleshooting complex software issues. The software development 
was started very early in the semester with the bare minimum supporting hardware being 
implemented on a protoboard. This allowed drivers to be written to communicate with the 
AMS rotary position sensor and throttle peripherals before the software and hardware 
were ready for integration.   
 
The design principle integral to the success of the software portion of the project was 
speed of execution. Only after a portion of the code was deemed to be logically correct 
and maintainable, was it considered for optimization. Indeed, a great deal of optimization 
is done automatically by the C++ compiler when it translates the C++ code into ARM 
assembly language. Additionally, a sufficiently fast microcontroller was chosen such that 
speed would not be an issue that would limit the functionality of the final product. Future 

Page 55​
 of 103 

 
iterations of the design could make use of a less expensive yet slower microcontroller by 
implementing more aggressive code optimizations. 
 
3.2.4­B Details of the Algorithm  
 
In the most basic sense, the software algorithm to drive an alternator as a motor only 
needs to make one major decision on each loop through the algorithm. Namely, the 
software needs to decide which coils of the stator to turn on and which ones to turn off at 
any given point in time. In order to do this effectively, two main pieces of information 
need to be gathered: the absolute angle of the rotor shaft relative to the stator coils, and 
the throttle input from the user. As mentioned previously, this design uses C++ and as 
such, takes advantage of the object­oriented software design patterns available when 
using this language. For those unfamiliar with the meaning of “object­oriented design 
patterns” this means that the language allows for the definition of “objects” within the 
code which can represent both abstract concepts and real world objects. These definitions 
are called “classes.” Within the code implemented for this design, four main classes were 
defined to represent the four primary components of the physical hardware. These classes 
are the RotorManager, StatorManager, ThrottleManager and finally the AS5132Sensor 
representing the rotor, stator coils, throttle input, and rotary position input respectively. 
Various other small supporting classes were created as well. The motor control algorithm 
operates in a tight repetitive loop with three simple steps: Update the throttle, update the 
rotor, and finally update the stator. Each step is important and generates some bit of 
information needed by the next step.  
 
First, within the update method of the throttle a value is read from the analog to digital 
converter (ADC) connected to the throttle pin. This value is converted to a percent 
between 0 and 100 based on experimentally predetermined limits on the numerical 

Page 56​
 of 103 

 
outputs of the ADC. The following equation is used to convert the numerical output of 
the ADC into a percentage: 

 
The percentage is then stored internally for later use. If the ADC can not be read in a 
reasonable amount of time, this step is skipped and the previous value for the throttle 
percentage is used. This is done to prevent the microcontroller code from from freezing 
and potentially causing an unsafe mode for the motor.  
 
Second, the rotor is updated. This step is significantly more involved than the throttle 
update because it involves reading an angle value from the AMS rotary position sensor. 
The first step in updating the rotor mager is to determine how much time has passed since 
the last update. This is used primarily to determine the speed of the rotor by comparing 
the elapsed time between updates with the change in angle measurement between 
updates. After the elapsed time has been recorded and the timer started again 
immediately, the AS5132 driver component is instructed to take an angle reading from 
the AMS rotary position sensor. The driver does this by implementing the serial protocol 
described in the data sheet for the AS5132 sensor.  
 
First, the chip select pin is pulled low to begin the transmission. Then the first seven out 
of eight command bits are clocked in by writing the corresponding command bit to the 
DIO pin and then pulsing the clock pin. The last data bit needs to be handled differently 
due to the nature of the protocol. The 8th command bit is written to the DIO line and the 
rising edge of the clock is given to latch the bit into the memory of the AMS chip. 
However, on the falling edge of this clock pulse the sensor chip will immediately change 

Page 57​
 of 103 

 
its end of the shared DIO line to an output and begin driving bits on the line. If the 
microcontroller does not switch its end of the shared DIO line to an input before this 
happens, two microcontroller outputs may be inadvertently tied together creating a short 
circuit that could cause damage to either chip. For this reason, the microcontroller side of 
the DIO line is changed to an input before allowing the falling edge of this clock pulse to 
occur. This ensures both the correctness of the protocol and the safety of both the rotary 
position sensor and the microcontroller. Finally, 16 data bits are clocked in from the chip 
and the chip select pin is pulled high to terminate the transmission. The raw data is 
unpacked into the individual readings including the strength of the magnetic field begin 
sensed and (most importantly) the angle of the field. This last value is interpreted as the 
angle of the rotor shaft itself. Following the update of the AS5132 driver, the actual angle 
of the rotor can be obtained and used for processing. 
 
Now that the rotor class knows the angle of the actual rotor, it first checks to make sure 
the reading is valid. There are several errors that can occur in transmission and if any one 
of them has indeed happened, the rotor manager throws away the faulty angle reading 
and retains the last known good reading. For example, the rotary position sensor contains 
an internal ADC and if a read of the angle is attempted while that ADC is locked, the data 
is unreliable. Additionally, if a bit is flipped in transmission or if the previous angle 
reading is equal to the current angle reading, the new reading is discarded because it is 
meaningless. Assuming, however, that the angle reading is a good one, it is written down 
to be used later. If there have been at least two good angle readings, the velocity of the 
rotor is also computed and written down for later use. 
 
The third and final step is the updating of the stator performed in the stator manager 
class. This step synthesizes the information gathered in the first two steps regarding the 
position and speed of the rotor as well as the position of the throttle. It is in this step that 
the microcontroller actually chooses the driven stator coil and whether or not to drive the 

Page 58​
 of 103 

 
rotor coil. First, the rotor angle and the throttle percent are retrieved from the rotor 
manager and throttle manager respectively. The stator manager then computes an 
effective angle for the rotor given its actual angle. Because the stator coil configuration is 
repeated six times in one rotation of the rotor, the actual angle of the rotor can be 
converted into an equivalent angle in the range 0 to 60 degrees without changing the 
operation of the motor. This is done using a modulus operation. 

 
The stator manager now needs to make a decision regarding the rotor. During motor 
startup, a large amount of torque is desired in order to reliably start the motor and prevent 
stalling. This can be achieved by turning the rotor coil on at all times as long as the rotor 
is spinning slower than a predetermined speed. Once the rotor is spinning fast enough, 
efficiency and top speed can be achieved by lessening the field strength in the rotor. This 
is done by modulating the rotor to only be active half as much as it would be under 
startup conditions. The following code snippet is responsible for deciding how to handle 
the rotor pulses: 

 
It is interesting to note that, during the startup state, not only is the modulation of the 
rotor turned off, the throttle is also assumed to be at 100 percent regardless of the actual 

Page 59​
 of 103 

 
throttle position. This allows the motor to start reliably no matter the angle at which the 
rotor finds itself when it needs to start spinning. As soon as the rotor begins to turn, the 
throttle resumes its normal operation and the rotor coil begins modulating to improve 
performance and efficiency.  
 
Next, the stator manager needs to decide which coil to turn on given the current rotor 
angle and throttle percent. This is done by asking each state (there are only 6 of them) if 
it can handle the current rotor angle given a particular throttle percent. Each state has a 
method on it called “CanHandleAngle” which returns true if the state should be on right 
now and false if the state should be off. If a state reports that it should be active, it is 
recorded as the active state to be turned on after the loop. The reason for this is one of 
circuit safety. When moving from one state to another, it is important to turn the previous 
state off before turning the next state on so that a short circuit is not created in the 
H­bridge mosfet circuitry. For this reason, if a state reports in this loop that it should be 
inactive, it is turned off immediately. After the loop completes, whichever state reported 
itself to be active (if any) is enabled along with the rotor coil. To really understand when 
a coil should be on or off, it is necessary to look at the contents of the previously 
mentioned “CanHandleAngle” method. 
 
Each state has the ability to determine if it should be on or off for any given angle and 
throttle percent. When the state is constructed, an optimal push angle (quadrature) for that 
state is computed by taking the base angle for the stator coil and subtracting a timing 
angle: 

 
Now, the state needs to compute a range of angles around this quadrature point at which 
the relevant stator coil should be active. Knowing that there is a 10 degree separation 

Page 60​
 of 103 

 
between stator coils (and therefore, between states also), the maximum width of this 
range of angles is 10 degrees (that is, 5 degrees before and after the quadrature point). 
Additionally, at low throttle input the pulse should be narrower but still centered on the 
quadrature point. At maximum throttle percent, the pulse should be as wide as possible. 
This is accomplished using the following equation to compute the minimum and 
maximum angles for the pulse centered on the quadrature point. 

 
Notice the use of floating point to compute the min and max angles. This allows for more 
possible pulse widths and finer control over the torque of the motor using the throttle. At 
this point, it is simply a matter of determining if the given angle for the rotor is between 
the min and max angles just computed. If the rotor angle is between the min and max 
angles, CanHandleAngle will return true and the stator manager will enable the pins 
associated with this state. Otherwise it will return false and the state will be deactivated 
immediately.  
 
The entirety of the code required to implement this above described algorithm has been 
included in Appendix 3. 
 

 
 
 
 

Page 61​
 of 103 

 
Chapter 4 ­ Data Testing 
 
For validation of the constructed motor controller, data collection of key performance 
characteristics were taken to compare the design of Team 9 to the design of DC motors 
that are already in the market. The results demonstrate the that the Team 9 alternator with 
motor controller design can achieve a satisfactory performance at a much more affordable 
cost than a DC motor. 
 

4.1 Revolutions Per Minute 
 
For the electric vehicle application, a 
major factor of performance is the speed 
that the vehicle is able to achieve. The 
speed is correlated to the revolution per 
minute of the alternator rotor and varies 
with different throttle levels. To measure 
the revolutions per minute, a stroboscope 
was used. As shown in Figure 41 on 
the right, a stroboscope is a device 
that that emits a flashing light with a tunable frequency. One fin of the alternator was 
 ​
marked with white tape and the stroboscope was faced toward the alternator.​The 
alternator was then driven at a constant throttle level and the dial on the stroboscope was 
adjusted until the white tape on the rotor fin appeared to be stationary. This occurred 
when the frequency of the strobe flashed matched the frequency of the motor. This test 
was done at increasing throttle levels and the results are shown in the figures below. It is 
shown that the revolutions per minute of the motor increase linearly with the throttle until 
the throttle reaches a level of about 50%. After this point the slope drastically decreases 

Page 62​
 of 103 

 
and the correlation between throttle percentage and revolutions per minute increase 
linearly once again. This is because the sensitivity of the throttle varies at different 
throttle percentages. It is useful to have more sensitivity at lower throttle levels to help 
start the vehicle and less sensitivity at higher speeds so the driver is able to maintain their 
chosen speed. Throttle percentage versus RPM is shown below in Figures 42 and 43. 

Figure 42: Throttle Percentage vs RPM 

Figure 43: Throttle Percentage vs RPM 

 
 

Page 63​
 of 103 

 
4.2 Input Power 
 
With any electric vehicle, the input power required to drive the vehicle is a key 
parameter. In the case of Team 9, this power is in the form of electrical power. To 
calculate electrical power the equation, 
P = V rms * I rms , may be used. While it is 
simple to use the digital multimeter 
supplied in the ECE 480 lab to measure 
the input voltage, it was more difficult to 
measure the Irms value. The initial thought 
to use a series connection to the digital 
multimeter supplied in the ECE 480 lab to 
measure the input current was not feasible 
because the input current is higher than the 
rated current of the multimeter. An “Ideal 
 ​
61­772”​model multimeter with a current 
clamp was then acquired because it is able 
to measure the high current and has a true 
rms feature that will calculate the rms 
value of non­sinusoidal waveforms. This 
was an important feature because the 
input current is in the form of a square wave and using other meters could cause major 
errors in the current calculation.   
The bench multimeter was connected to the terminals of the battery, and the “Ideal 
61­772” multimeter was clamped around the negative terminal wire. The values of each 
meter were observed , with no load connected to the alternator, at increasing throttle 
levels and are displayed in the figures below. It was observed that the input power 

Page 64​
 of 103 

 
increases until the throttle level reaches around 50% and then drops off. This is because 
around this throttle level the code enters a phase where the duty cycle of the rotor is 50% 
instead of 100%. While this results in a desirable reduction input power, some torque is 
lost at higher speeds as shown in Figures 45 and 46. 

Figure 45: Throttle Percentage vs Input Power 

Figure 46: Throttle Percentage vs Input Power 
 

 
 
 

Page 65​
 of 103 

 
4.3 Torque     

 
Torque is an important mechanical parameter of interest in vehicles because it translates 
into the amount of force that the vehicle can provide. In industry, this important 
parameter is typically measured with a dynamometer and can be done quite easily, but in 
a student laboratory setting, Team 9 was not able to access a dynamometer for testing. 
Two alternate torque measuring techniques were devised by Team 9. 
 
The first measuring 
technique used old bicycle 
components and simple 
physics to measure the force 
provided by the motor.  As 
shown in the figure on the 
right, an apparatus was 
constructed in which the 
alternator was secured onto a 
rotating fixture that was connected 
to an arm. A scale was place under the arm and when a load was applied to the energized 
alternator, the scale measured the force applied by that arm. Using the equation 
T orque = |r||F |sin(theta)  the torque was able to be calculated. The variable “r” is the 
length of the arm which was measured to be .298m, “F” is the force that the arm exerted 
on the scale, and theta was measured to be approximately 90 degrees because the arm is 
perpendicular to the scale. 
 
In the lab, the alternator was energized at increasing throttle percentages and a load was 
applied to the rotor. This load was large enough to stop the rotation of the rotor, which 

Page 66​
 of 103 

 
causes the rotor to operate very near the maximum torque. At each throttle level, the 
available torque was calculated and is displayed in figures 48 and 49 below. 

Figure 48: Maximum Torque vs Throttle Percentage 

Figure 49: Maximum Torque vs Throttle Percentage 
 
In order to verify the quality of the data obtained using the first torque measuring 
technique a second method was devised using only the mass of the rotor itself as the load. 
It is possible to determine the average torque over a period of time using the equation 
T orque = α ∙ I  where alpha is the angular acceleration of the rotor and I is the moment of 
inertia of the rotor. The rotor itself was weighed outside of the motor and found to be 
2.24 kg. It’s radius was also measured to be .0508 meters. Using the equation for the 
moment of inertia of a solid cylinder:  I = 12  m ∙ r 2 the moment of the rotor was determined 
2​
to be 0.003097 ​
kg∙m​. ​
The motor was then reassembled and run from 0 rpm to it’s 
maximum speed of 2075 rpm at full throttle. After averaging several stopwatch 

Page 67​
 of 103 

 
measurements it was determined that, at full throttle, the motor was able to accelerate the 
rotor from 0 rpm to 2075 rpm in 1.8 seconds. After some unit conversion, this gives an 
2​
average angular acceleration of 120.7 rad/s​. The torque equation listed above can now be 
filled in, giving an average torque (at full throttle) over the full rpm range of 0.37 Nm. 
This value validates that the values measured using the first method were reasonable and 
consistent with basic kinematics.   

 
4.4 Efficiency 
 
Efficiency is one of the most important factors in the design of electric motor controller 
systems. The formula used to calculate efficiency is  efficiency = P out/P in . Typically 
efficiency would be calculated using a dynamometer but the team was able to calculate a 
value from data collected using the test fixtures. 
 
The input power from the battery was calculated by multiplying the input current with the 
input voltage while the rotor was under an external load. Averaging the values from the 
figure above, the average input power under a variety of loads was found to be 128 
Watts. The average output power was calculated by multiplying the average output 
torque by the average output speed.  P = T orque ∙ v  In this equation torque is in 
v​
Newton­meters and velocity (​) is in radians per second. The average velocity is exactly 
half of the maximum velocity if a linear speed increase is assumed. Given an average 
torque of 0.37 Nm and an average velocity of 108.5 radians per second, the average 
mechanical output power was 40.14 Watts. This value takes into account all electrical 
and mechanical losses including friction and heat losses.  Given these values for input 
40W
and output power, the efficiency of the design was found to be  128W × 100% = 31% . 

Page 68​
 of 103 

 
4.5 Scope Measurements 
 
4.5.1 Common MOSFET Gate Pulses 
 
The following diagrams show the pulses that are applied to the gates of the MOSFETs. 
The p­channel mosfets are driven with a negative pulse below the supply voltage while 
the n­channel mosfets are driven by a positive pulse above ground. In the following two 
diagrams, the three negative pulses on the p­channel mosfet and the three positive pulses 
on the n­channel are interleaved like the teeth on a set of gears. When the p­channel 
pulses are idle, the n­channel mosfet is being pulsed and vice versa. When the throttle 
percent is lessened, the distance between consecutive pulses is increased creating more 
idle time for the stator coils and reducing torque output. The following diagrams in figure 
50 and 51 show the operation of the mosfet gates at maximum throttle which is also the 
point of maximum stress on the circuitry. 
 

 
Figure 50: P­Channel Common Gate Pulses at 100% Throttle 

Page 69​
 of 103 

 
 
Figure 51: N­Channel Common Gate Pulses at 100% Throttle 

 
 
 
 
 
 
 
 
 
 
 
 

Page 70​
 of 103 

 
4.5.2 Rotor Gate Pulses 
 
Any time that a stator coil is active, the rotor coil is also activated in order to produce 
torque. The following diagram in Figure 52 shows the pulses given to the gate of the 
n­channel rotor mosfet at 100% throttle. It is important to note that, although the rotor is 
activated often (every time a stator coil is on), the total area underneath the curve is 
significantly less than it would be if the rotor were activated permanently. This is due to 
the modulation of the stator coil at high RPMs. This modulation weakens the rotor field 
and allows for increased speed and efficiency. 
 

 
Figure 52: Rotor Gate Pulses at 100% Throttle 

 
 
 
 
 

Page 71​
 of 103 

 
4.6 Design Specification Achievements 
The chart below documents the success of Team 9 in achieving the project goals: 
  

Design Specification  Achieved?  Notes 

Working DC motor  Yes  Automotive alternator was successfully 


alternative  converted to a motor. 

Inexpensive design  Yes  Motor and controller can be 


purchased/manufactured for under $100 
USD. 

Wide range of speed  Yes  Achieved over 2000 RPM max speed with 


only a 12 V supply.. 
Fine control of speed is possible with the 
throttle. 

Automatic controls for  Yes  Rotor current is increased or reduced under 


enhanced performance  certain conditions to allow higher operating 
speed or regenerative braking. 

Increased torque at low  Yes  Throttle percent and rotor current are 


speeds  automatically modified for increased torque 
at low speeds. 

Increased efficiency  Partial  The design is reasonably efficient 


considering it is only an initial prototype. 
Future improvements in this area are 
discussed further in the summary section.  

Reverse  Partial  Technically allowed by the software 


algorithm. Additional user input required 
for real world operation. 
 
 
 
 
 

Page 72​
 of 103 

 
Chapter 5 ­ Design Issues 
 
As this project is sponsored by and partnered with MSU RCPD, accessible design is 
extremely important in the production of an E­Bike Motor and Controller. Since the 
Team 9 design is very versatile in the number of applications it could be applied to, there 
are numerous ways accessibility could be improved in the prototype. For example, for 
someone with extremely limited physical dexterity, it may be difficult to accurately 
control the throttle input. To make the design easier to use, a joystick modification could 
be implemented which would allow for the user to control the entire vehicle with a single 
hand. This modification could also allow for the vehicle to be designed at a much smaller 
size similar to that of a wheelchair.  
 
Another modification that could be made to the design is the use of hand pedals which 
could provide assistance to the motor in propelling a vehicle.  Accompanied with 
appropriate circuitry, these hand pedals would also be able to charge the vehicle’s 
battery. This addition would allow for people with limited lower body functionality to use 
the vehicle effectively. 
 
Environmental issues must also come into consideration when designing any type of 
vehicle, especially when dealing with electronics. Since the vehicle is projected for use in 
a rugged environment, water and humidity resistance is critical. To prepare the product 
for production on a large scale, some type of waterproof casing or waterproofing spray 
must be applied to the motor controlling circuit to ensure a long lifetime. Similarly, 
environmental heat will also cause many problems if not addressed. To ensure the motor 
circuit components do not overheat and malfunction, good heat sinks and potentially 
some sort of active cooling should be applied to the controlling circuit. 
 

Page 73​
 of 103 

 
With any design that is mass produced for the public, it is important to take into 
consideration the safety issues that can arise with use of the design. Electric vehicles 
come with inherent risk, but with careful design these risks can be reduced. These risks 
include the use of a chemical battery, such as one found in in an automobile and used in 
this design and the use of high current electronics. Motor controllers are the driving force 
of these vehicles and added features to this component can help solve many safety issues.  
 
Quick acceleration at the startup could cause an unexpected jostle to the rider. This may 
cause the rider to experience whiplash, develop contusions, or lose control of the vehicle. 
A key feature of the Team 9 design is that this can all be prevented with added code to 
the microcontroller. The code could have an algorithm that does not allow the throttle 
input to be a large value during the startup phase of the code. This would help an 
unknowing rider who started the vehicle at full throttle avoid quick acceleration. 
 
The various terrain and conditions that the vehicle will be exposed to may cause 
unforeseeable adverse effects to the circuit. Increased loads may cause the circuit to draw 
large amounts of current. Large amounts of current may cause the circuit to overheat and 
even become damaged beyond repair. This could cause the rider to lose control of the 
vehicle. While the current circuit has many protection devices installed such as breakers, 
rectification diodes, and reinforced traces; a “smart” overcurrent protection device could 
be used to further protect the circuit. This device could take the place of the breaker and 
allow for short spikes of high current while suppressing sustained overcurrent conditions. 
This allows for the circuit to continue to run if spikes of current occur that are not 
threatening to the circuit. 
 
Sustained usage of the vehicle in hot conditions could cause parts of the design to 
become very hot. This could not only cause burns to the rider, but also may damage 
components on the circuitboard. To combat this problem heatsinks are installed on 

Page 74​
 of 103 

 
components that are at risk of overheating. While these heatsinks do a great job of 
keeping these components cool at normal operating conditions, there are some 
circumstances that could still cause these components to overheat. To prevent this 
occurrence, temperature sensors could be installed that signal to the microcontroller that 
the circuit is getting too hot and provide a warning to the rider and potentially 
automatically shut down the circuit. 

 
Chapter 6 ­ Final Cost, Summary, and Conclusions 
 
Over the course of this project, multiple steps were taken to complete the task of 
modifying an automotive alternator for use as a DC motor. The alternator itself was 
modified from its original design to improve efficiency. A complex power switching 
circuit was designed to allow the exterior stator coils and the rotor field coils to be pulsed 
in a novel way, at optimal quadrature angles. A microcontroller was used to drive the 
hardware circuits such that they would effectively operate the alternator as a motor. A 
magnetic rotary position sensor was used to provide the microcontroller with the data 
needed to perform the calculations for pulsing the stator and rotor. This design proved to 
be a unique alternative to a DC motor and a cost effective way of powering a small 
electric vehicle. 
 
The project had both successes and challenges. The design of the circuit proved 
troublesome. Although eventually a success, the circuit is complex, and a great deal was 
learned regarding the intricacies of switching mosfets at high frequencies. The early 
phases of the design worked by simulating the switching of one phase of the MOSFET 
circuit. This design would ultimately be integrated into the final design. After the initial 
design was complete, the next phase of designing the PCB proved problematic. The 
complexity of the circuit proved to be difficult in the process of providing an effective 

Page 75​
 of 103 

 
design that allowed for high voltages and currents to the MOSFETs. The software is also 
complex, which provided its own set of problems. The building of the software went 
slowly, for each new success, new complications arose. When it was believed that the 
software and circuit were complete, integration was the next phase. This also proved to 
be problematic. Initially, the software was changed frequently to solve problems such as 
a stuttering effect that the motor kept exhibiting. The software was refined, and the motor 
appeared to be working. The next phase of testing showed that the bipolar junction 
transistors were not switching fast enough to be able to handle the high frequency of the 
pulses. This caused a multitude of issues including overheating and malfunctioning 
MOSFETs. The culmination of all of the hardware issues up to this point were resolved 
through minor alterations to gate driving circuitry. Ultimately, the problems were 
resolved, and the design was finalized. 
 
The project was able to stay near the original timeline. Some of the intended stages of the 
critical path were naturally condensed from the original timeline as the circuit design 
required only minor tweaks, not a complete redesign. This allowed for more testing of the 
design and better characterization of the performance of the motor. 
 
The final cost for prototype development of the design was $332.54. This cost included 
all materials that were used in the prototyping phase. This cost was well under the budget 
for the project. The final cost of a single production unit was $99.01. This value 
represents a success to the team, because one of the major objectives of the project was 
an inexpensive design. This final cost could be reduced by buying the components in 
bulk from wholesalers. This cost is not representative of the cost in the nation in which 
the final design will be manufactured. The cost of manufacturing will likely be reduced 
as parts such as the alternator are available in India locally for much less than in the 
United States. 
 

Page 76​
 of 103 

 
At the beginning of the project, it was assumed that costs could be reduced by using 
inexpensive discrete components (junction transistors, resistors, diodes, etc.) to drive the 
gates of the MOSFETs. While the design has successfully accomplished this, the effort 
has required the addition of a large number of these devices to improve performance. 
Considering the actual component costs, PCB space, and cabinet costs required to 
accommodate this, it is now obvious that MOSFET gate driver circuits are easier to use, 
less costly to manufacture, and provide higher performance. TI makes a driver, 
UCC27714 for example, that can outperform the circuit at a cost of $2 each in quantity. 
This driver also saves cost because it can drive n­channel MOSFETs on the high side of 
the supply, thereby eliminating the need to use expensive p­channel MOSFETs and 
additional avalanche rectifiers.  
 
Additional cost saving could be obtained by soldering the 10 AWG wire to the printed 
circuit board to replace the expensive terminal blocks as well as using a fuse and switch 
to replace the circuit breaker. The original design was constructed with parts that are 
rated well beyond their use in the circuit. This allowed for a more robust design and 
eliminated the chance of hardware failure while testing different codes or conditions.  
 
The Team 9 design proved that it is in fact entirely feasible to convert a standard 
alternator into a motor. Through the study of the components used in the design, along 
with the data gathered, a conclusion can be drawn that the automotive alternator can and 
will be used in the future as a motor. Measuring the optimal angles and using that data as 
a way to improve the efficiency of an alternator to motor conversion is very unique. This 
uniqueness should provide others with an area to study for future improvements. Team 9 
is happy to have contributed its implementation of a very promising design and to have 
delivered a complete working prototype. Team 9 has assigned its intellectual property 
rights to RCPD and sincerely hopes that the technical and societal benefits of the E­Bike 
will be fully realized. 

Page 77​
 of 103 

 
Appendix 1 ­ Technical Roles, Responsibilities, and 
Work Accomplished 
 

 
The picture above from left to right: (Myles Moore ­ Document Prep, Tyler Borysiak ­ 
Project Manager, Alex Sklar ­ Lab Coordinator, Joshua Lamb ­ Presentation Prep, 
Stephen Dunn ­ Web Developer) 
 
Myles Moore 
The design team we established was partially split into two subgroups, hardware and 
software.  This was to increase the efficiency of the team so that two parts of the project 
could be developed simultaneously. As an electrical engineer, I was part of the hardware 
subgroup which was mainly focused on learning how the different alternator parts 
worked, developing a MOSFET switching circuit, and developing an efficient PCB 
layout for the final design. The first step taken during the semester was to determine how 
to make the alternator spin. To do this, I helped manually attached a 12V car battery to 
each phase of the stator coils to make the alternator act similar to a stepper motor. Once 
we figured out the sequence of the stator coils to make the alternator complete a full 

Page 78​
 of 103 

 
rotation we could begin to design the high­voltage MOSFET switching circuit. The first 
step in this process was to verify the turn­on voltage of the MOSFETs and determine how 
to safely use them. To experiment with the MOSFETs, I helped create a proof­of­concept 
switching circuit with LEDs acting as the stator coils for safety purposes. Once this 
circuit was working as intended, we began to integrate all the circuit elements we were 
going to use as footprints in Eagle’s PCB designer. When all the footprints were created, 
we then connected all the elements in the circuit schematic and imported the schematic 
into the PCB designer layout. At this part we were able to brainstorm a space efficient 
way to layout the different circuit elements and began to construct the traces. Once the 
entire layout was completed and printed in the ECE shop, we began soldering the 
different elements to the board. Since the MOSFETs would be handing a lot of current 
we added heat sinks to dissipate the power lost to heat. At this point we were able to 
integrate the hardware and software sub­groups to construct our prototype. The final 
steps in this project before design day are to optimize our software algorithm to make the 
motor run the most efficiently, as well as prepare the prototype for demonstration. 
 
Tyler Borysiak 
Along with the project management role, I was also continuously involved with the 
technical portion of the project as the hardware design lead. Throughout the semester, I 
set up hardware meetings in order to discuss technical specifications and design issues. 
On the hardware side, I designed the MOSFET stator switching schematic along with the 
rotor circuit and the peripheral connections to the microcontroller on the EAGLE 
schematic software. After designing the schematic, I organized the components on the 
board file and correctly routed the PCB traces and vias. After the fabrication of the board, 
I was involved in the component soldering and also in the connection of the software and 
hardware. After connecting the hardware and running tests, I was in charge of 
troubleshooting the hardware in order to find simple adjustments that needed to be made. 
I also have been suggesting new design alterations such as slight adjustments to the stator 

Page 79​
 of 103 

 
quadrature angle based on alternator performance during testing. I was also actively 
involved with the stator and rotor pulsing theory. The original plan was to read the angle 
of the rotor using the AMS sensor and pulse the stator coils every time that this was read. 
A more effective and efficient solution was to pulse the stator states less frequent at 
higher RPMs, allowing for less power consumption and wider ranges of speed. From a 
rotor theory standpoint, I have been involved in maximizing the field current efficiency 
by figuring out ways to only apply field current to the rotor when necessary. For 
example, we have found it more practical to constantly magnetize the rotor at start​
up for 
a short amount of time, and then gradually reduce the rotor field supply pulses. Towards 
the end of the design process, I also was actively involved in finding a solution to the two 
major hardware issues, which were the p­channel MOSFET not activating properly and 
the noise issue from the voltage source. 
 
Alex Sklar 
To achieve the proposed design there were two main components of the motor controller, 
the hardware/power electronics, and the microcontroller/software. I elected to focus most 
of my time on the hardware/power electronics because I have more knowledge on about 
hardware and less experience and knowledge of microcontrollers than the computer 
engineers in our team. 
 
As a team we selected the properly rated mosfets for our project that had the proper 
switching capabilities and current ratings for our project. Once we had the parts, I created 
an H­Bridge circuit with the mosfets that allowed for each coil of our alternator to be 
energized individually and in each polarity. This circuit also has diodes that are used for 
regenerative braking. I was able to test this circuit by connecting it to LEDs to signify 
each coil and separate polarities. I then worked with our sponsor and team to interface 
BJT transistors to drive the gate of the mosfets. This allowed the 3.3V output of the 
microcontroller to drive the gate of the mosfets. 

Page 80​
 of 103 

 
 
After the H­Bridge circuit was working I designed a similar circuit to control the rotor of 
the alternator. This used just one N channel mosfet and allowed the rotor coil to be 
connected to either 12V or just an open circuit. 
 
Because our circuit can draw large amounts of current it was difficult to test our design 
using a breadboard. This required the design of a printed circuit board. Tyler and I 
designed a printed circuit board in Eagle that contained very thick traces connected to the 
mosfets. This allowed for the circuit to draw high currents without the board melting. 
These abnormally thick traces required us to manually route the traces on the board 
instead of using the popular “autoroute” feature. 
 
During the design of the PCB I was also in charge of ordering parts for the final board. 
Because many of these parts are not in the included library of Eagle it was necessary to 
model many of these parts to be used in our PCB. 
 
Once our PCB was fabricated I was able to work on the soldering portion of our project. I 
then worked with my team to troubleshoot all of the problems with our board and finalize 
our hardware circuit and got it ready to be used to optimize the code on the 
microcontroller. I then worked on securing testing equipment and coordinated with the 
team to test each code and come up with solutions to each problem that degraded our 
efficiency and perfect the “startup” and “high speed” phases of our code.   
 
Joshua Lamb 
My defined part of the project was to serve as one of two Software Specialists. The 
software specialists were responsible for implementing the motor control algorithm 
which effectively interfaced with the AMS sensor, throttle sensor, and the power 
MOSFET switching circuits. I was a part of researching the steps needed to enable the 

Page 81​
 of 103 

 
functionality on the microcontroller. I assisted in the communication of the AMS sensor 
with the microcontroller. I made decisions regarding the design of the interface between 
the microcontroller and the circuit.  As one of the software specialists, I became an expert 
in the specifications and use of the sensor and microcontroller used in the project. I used 
computer language standards, electrical standards, schematic standards and many more 
over the course to communicate with the team. I was involved in creating a list of 
specifications the microcontroller needed to satisfy as well as researching and choosing a 
microcontroller to be used for the project. I researched and helped choose the magnetic 
rotary sensor used in the project based on a list of requirements we created. I helped 
create a list of requirements that would need to be satisfied for the PCB board that would 
need to be created. I was involved in the building and testing of the alternator initial 
design. I recognized potential issues that would need to be addressed in the final design. I 
was involved in the initial framework of the software design as well as the research into 
the documentation of the microcontroller to enable the needed features. I was then 
involved in the process of building the software. This process involved multiple steps to 
build the scaffolding of the design. I was involved in a great deal of the testing of each 
design iteration, from software to hardware. I was involved in the building of the final 
circuit. My role within the project stayed specialized but became more robust.  
 
Stephen Dunn 
For this project I served as both the software specialist webmaster and as a webmaster. I 
began design work on the project by helping to select a microcontroller and rotary 
position sensor. Part of the motivation for selecting the Texas Instruments 
microcontroller was the familiarity that myself and Josh had with the platform. Once the 
microcontroller and rotary position sensor were selected I began the process of 
prototyping a development environment that would allow Josh and I to work on the code 
collaboratively. This involved setting up a source control repository on the CSE servers 
here at MSU. Once the source control environment was setup, I created a code composer 

Page 82​
 of 103 

 
studio project specifically designed to work with our development board. This included 
selecting the appropriate header files and libraries and setting up the memory map on the 
microcontroller. All of these tasks were needed in order to make rapid development on 
the microcontroller possible. Next, I began work prototyping the circuitry needed to 
connect to the rotary position sensor, throttle and LCD to the microcontroller. With these 
circuits setup on a protoboard, I began writing the code to communicate with these 
devices. Around this same time in the design process, Josh and I disassembled the 
alternator, rewired it from a delta configuration to a wye configuration, and 
experimentally discovered the sequence of stator pulses needed to drive the rotor. I was 
also responsible for writing the logic needed to drive the stator coils at the appropriate 
angles. When it came time to assemble the circuit I was one of the primary solderers and 
took an active role in helping to debug the circuit when trouble was encountered. Finally, 
I proposed and executed one of the testing methods used to measure the average torque of 
the rotor using basic kinematic physics concepts. I was very excited about this project 
from the beginning and decided to take an active role in as much of the project as 
possible even outside my software speciality. As webmaster, it was as much a pleasure as 
responsibility to make our course deliverables accessible to the team and to the public. 
 
 
 
 
 
 
 
 
 
 
 

Page 83​
 of 103 

 
Appendix 2 ­ References 
 
AMS AS5132 Rotary Sensor Data Sheet: 
http://ams.com/eng/content/download/254823/1001597/147615 
TivaWare Peripheral Driver Library: 
http://www.ti.com/lit/ug/spmu298a/spmu298a.pdf 
Tiva TM4C123GH6PMI Microcontroller Data Sheet: 
http://www.ti.com/lit/ds/symlink/tm4c123gh6pm.pdf 
Hall Effect Sensor: 
http://www.edn.com/design/sensors/4406682/Brushless­DC­Motors­­­Part­I­­Constructio
n­and­Operating­Principles 
Hyperfast Recovery Diode Datasheet: 
http://www.mouser.com/ds/2/149/FFH75H60S­244361.pdf 
P­Channel MOSFET Datasheet: 
http://www.mouser.com/ds/2/205/DS100024B%28IXTA­TH­TP76P10T%29­312838.pdf 
N­Channel MOSFET Datasheet: 
http://www.mouser.com/ds/2/196/IPP045N10N3%20G_Rev2.5­96667.pdf 
 
Automotive Alternator Schematic Illustration: 
http://www.alternative­energy­tutorials.com/wind­energy/pmdc­generator.html 
Delta vs Wye: 
https://en.wikipedia.org/wiki/Delta­wye_transformer 
Automotive Alternator Diagram: 
http://www.examiner.com/article/introduction­to­alternators­part­three­alternator­compo
nents 
MOSFET Diagram: 
http://www.eeweb.com/company­blog/ixys/p­channel­power­mosfets­and­applications 

Page 84​
 of 103 

 
Appendix 3 ­ Software Reference Code 
/* 
 * main.cpp 
 */ 
 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_memmap.h" 
#include "inc/hw_types.h" 
#include "inc/hw_gpio.h" 
#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/pwm.h" 
#include "driverlib/rom.h" 
#include "driverlib/rom_map.h" 
#include "driverlib/sysctl.h" 
#include "driverlib/ssi.h" 
#include "driverlib/systick.h" 
 
#include "GeneralUtil.h" 
#include "LiquidCrystal.h" 
#include "AS5132Sensor.h" 
#include "RotorManager.h" 
#include "Timer.h" 
#include "StatorManager.h" 
#include "ThrottleManager.h" 
 
LiquidCrystal* lcd; 
RotorManager* rotor; 
ThrottleManager* throttle; 
StatorManager* stator; 
 
void setup(void) { 
// max clock speed. 
GeneralUtil::SystemClock80MHz(); 
 
// enable GPIO modules 
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); 
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); 
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); 
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); 
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); 
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); 
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); 
 
// small delay required to let the peripheral devices turn on. 
GeneralUtil::DelayMicro(10); 
 
// write a pin to indicate setup time 
GeneralUtil::PinMode(GPIO_PORTB_BASE, GPIO_PIN_0, OUTPUT); 
ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0xFF); 
 
// LCD talks on port B 
// set up the LCD's number of columns and rows: 
lcd = new LiquidCrystal(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, 
GPIO_PIN_7); 
lcd­>begin(20, 4); 
 
// throttle ADC is on port E 
throttle = new ThrottleManager(GPIO_PORTE_BASE, GPIO_PIN_3); 

Page 85​
 of 103 

 
 
// rotor talks on port A 
rotor = new RotorManager(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_2, GPIO_PIN_4, 
GPIO_PORTA_BASE, GPIO_PIN_7, throttle); 
 
// stator talks on ports C and F 
stator = new StatorManager( 
rotor, throttle, 
GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7, 
GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_4); 
 
// write a pin to indicate setup time 
ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0x00); 

 
int main(void) { 
setup(); 
 
// toto: if needs calibration, calibrate! 
// else, continue with normal operation 
 
while(1){ 
/* 
 * Basic algorithm 
 */ 
 
throttle­>Update(); 
rotor­>Update(); 
stator­>Update(); 
 
 
/* 
 * Debug Printing. VERY SLOW! Disable for actual operation! 
 */ 
 
// if(calcIterations > 5000) { 
// lcd­>setCursor(0, 0); 
// lcd­>print('['); 
// lcd­>print(rotor­>GetAngle()); 
// lcd­>print(']'); 
 
// calcIterations = 0; 
// } 
/**/ 

 
return 0; 

 
/* 
 * AS5132Sensor.cpp 
 * 
 *  Created on: Oct 20, 2015 
 *      Author: Stephen Dunn, Josh Lamb 
 */ 
 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_memmap.h" 
#include "inc/hw_types.h" 
#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h" 

Page 86​
 of 103 

 
#include "driverlib/rom.h" 
#include "driverlib/rom_map.h" 
#include "driverlib/sysctl.h" 
 
#include "GeneralUtil.h" 
#include "AS5132Sensor.h" 
 
AS5132Sensor::AS5132Sensor(uint32_t port, uint8_t pinCS, uint8_t pinCLK, uint8_t pinDIO) { 
mPort = port; 
mPinCS = pinCS; 
mPinCLK = pinCLK; 
mPinDIO = pinDIO; 
 
// set pin directions 
ROM_GPIOPinTypeGPIOOutput(mPort, mPinCS); 
ROM_GPIOPinTypeGPIOOutput(mPort, mPinCLK); 
ROM_GPIOPinTypeGPIOInput(mPort, mPinDIO); 
 
// ChipSelect­>high means no transmission 
ROM_GPIOPinWrite(mPort, mPinCS, ALL_HIGH); 
ROM_GPIOPinWrite(mPort, mPinCLK, ALL_LOW); 
 
mAngle = 0; 
mSensorGain = 0; 

 
 
void AS5132Sensor::TakeReadings() { 
// read the raw bit data into a structure 
ReadAngleResponse raw; 
raw.value = Command(AMS_RD_ANGLE); 
 
// grab the values from the bitfield 
mAngle = raw.fields.AngleReading; 
mSensorGain = raw.fields.SensorGain; 
mLockADC = raw.fields.LockADC; 

 
uint16_t AS5132Sensor::Command(uint8_t command) { 
 
uint16_t tmp = 0; 
uint16_t data = 0; 
 
// pull chip select low to start the transmission 
ROM_GPIOPinWrite(mPort, mPinCS, ALL_LOW); 
 
// the first 7 of the 8 command bits 
ROM_GPIOPinTypeGPIOOutput(mPort, mPinDIO); // set DIO pin to an output. 
for(int i = 0; i < 7; i++) { 
// write data bit, MSB first 
ROM_GPIOPinWrite(mPort, mPinDIO, (command & 0x80) >> 7); 
command = (command << 1); 
 
// pulse the clock to latch the bit in the AS5132 
ROM_GPIOPinWrite(mPort, mPinCLK, ALL_HIGH); 
ROM_GPIOPinWrite(mPort, mPinCLK, ALL_LOW); 

 
// The last data bit is handled differently in read mode because the DIO 
// pin needs to change from an output to an input. 
 
// write last data bit 

Page 87​
 of 103 

 
ROM_GPIOPinWrite(mPort, mPinDIO, (command & 0x80) >> 7); 
command = (command << 1); 
 
// clock it in on the rising edge 
ROM_GPIOPinWrite(mPort, mPinCLK, ALL_HIGH); 
 
// before the falling edge of the clock, change the pin mode 
ROM_GPIOPinTypeGPIOInput(mPort, mPinDIO); 
 
// now let the clock fall. 
// the AS5132 will immediately begin outputing data on the DIO line 
ROM_GPIOPinWrite(mPort, mPinCLK, ALL_LOW); 
 
// 16 data bits 
for(int i = 0; i < 16; i++) { 
// read data bit (MSB first) 
tmp = ROM_GPIOPinRead(mPort, mPinDIO); 
 
tmp = tmp >> 4; // get the bit in the ones position 
data = data | (tmp << (15 ­ i)); // shift it into the result 
 
// clock in the next bit. 
ROM_GPIOPinWrite(mPort, mPinCLK, ALL_HIGH); 
ROM_GPIOPinWrite(mPort, mPinCLK, ALL_LOW); 

 
// finish the transmission by pulling the chip select pin high 
ROM_GPIOPinWrite(mPort, mPinCS, ALL_HIGH); 
 
return data; 

 
/* 
 * AS5132Sensor.h 
 * 
 *  Created on: Oct 20, 2015 
 *      Author: Stephen Dunn, Josh Lamb 
 */ 
 
#ifndef AS5132SENSOR_H_ 
#define AS5132SENSOR_H_ 
 
#define AMS_RD_ANGLE  0x00 // read angle command bits 
#define AMS_RD_MT_COUNTER 0x04 // read multiturn counter command bits 
 
// bitfield for raw reading 
struct ReadAngleStruct { 
uint8_t Parity : 1; 
uint8_t SensorGain : 5; 
uint8_t LockADC : 1; 
uint16_t AngleReading : 9; 
}; 
 
// a union to allow setting all the bits at once 
union ReadAngleResponse { 
  struct ReadAngleStruct fields; 
  uint32_t value; 
}; 
 
// the class that represents the AMS sensor 
class AS5132Sensor { 
public: 

Page 88​
 of 103 

 
// constructor 
AS5132Sensor(uint32_t port, uint8_t pinCS, uint8_t pinCLK, uint8_t pinDIO); 
 
// causes the class to take a fresh set of readings from the sensor 
void TakeReadings(); 
 
// various possible fault modes of the sensor itself can be queried 
// with these three methods here: 
 
// field strength is too low to detect 
bool GetIsFieldStrengthFault() { return mSensorGain > 60; } 
 
// sensor internal ADC was locked when angle was read 
bool GetLockADC() { return !mLockADC; } 
 
// somehow the angle is out of bounds 
bool GetIsRangeFault() { return mAngle > 359; } 
 
uint32_t GetAngle() { return mAngle; } 
uint32_t GetFieldStrength() { return mSensorGain; } 
 
private: 
// the angle last reported by the sensor 
uint32_t mAngle; 
// the gain last reported by the sensor 
uint32_t mSensorGain; 
 
// during the last reading, was the internal ADC locked? 
bool mLockADC; 
 
// raw data from the sensor 
uint16_t mRaw; 
 
// GPIO ports and pins for communication 
uint32_t mPort; 
uint8_t mPinCS; 
uint8_t mPinCLK; 
uint8_t mPinDIO; 
 
// sends the given command bits and returns the result from the sensor 
uint16_t Command(uint8_t command); 
}; 
 
#endif /* AS5132SENSOR_H_ */ 
 
/* 
 * GeneralUtil.cpp 
 * 
 *  Created on: Oct 6, 2015 
 *      Author: Stephen Dunn, Josh Lamb 
 */ 
 
#include "GeneralUtil.h" 
 
#include <stdint.h> 
 
#include "inc/hw_memmap.h" 
#include "inc/hw_types.h" 
#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/rom.h" 
#include "driverlib/rom_map.h" 

Page 89​
 of 103 

 
#include "driverlib/sysctl.h" 
 
uint32_t GeneralUtil::mSysClock = 0; 
 
uint32_t GeneralUtil::GetSysClock() { 
return mSysClock; 

 
void GeneralUtil::SystemClock80MHz() { 
    // Run from the PLL at 80 MHz. 
ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | 
SYSCTL_OSC_MAIN); 
mSysClock = ROM_SysCtlClockGet(); 

 
void GeneralUtil::DelayMicro(uint32_t us) { 
// assumed 80MHz clock 
ROM_SysCtlDelay((float)us * 26.67); 
 
// real calculation 
// ROM_SysCtlDelay(us * ((float)mSysClock / (float)3 / (float)1000000)); 

 
// used to port the liquid crystal library 
void GeneralUtil::DigitalWrite(uint32_t portbase, uint8_t pinmask, uint8_t value) { 
ROM_GPIOPinWrite(portbase, pinmask, value); 

 
// used to port the liquid crystal library 
void GeneralUtil::PinMode(uint32_t portbase, uint8_t pinmask, uint8_t value) { 
if(value == OUTPUT) { 
ROM_GPIOPinTypeGPIOOutput(portbase, pinmask); 
} else { 
ROM_GPIOPinTypeGPIOInput(portbase, pinmask); 


 
/* 
 * GeneralUtil.h 
 * 
 *  Created on: Oct 6, 2015 
 *      Author: Stephen Dunn, Josh Lamb 
 */ 
 
#ifndef GENERALUTIL_H_ 
#define GENERALUTIL_H_ 
 
#include <stdint.h> 
#include <stdbool.h> 
#include "driverlib/gpio.h" 
 
#define HIGH 0x01 // first bit high 
#define ALL_HIGH 0xFF // all bits high 
#define LOW 0x00 // first bit low 
#define ALL_LOW 0x00 // all bits low 
 
#define INPUT GPIO_DIR_MODE_IN // naming shortcut 
#define ALL_INPUT 0x00 // naming shortcut 
#define OUTPUT GPIO_DIR_MODE_OUT// naming shortcut 
#define ALL_OUTPUT 0xFF // naming shortcut 
 
#include <stdint.h> 

Page 90​
 of 103 

 
#include <stdbool.h> 
 
class GeneralUtil { 
private: 
// System clock rate in Hz. 
static uint32_t mSysClock; 
 
public: 
static uint32_t GetSysClock(); 
 
static void SystemClock80MHz(); 
 
// looses accuracy below ~10us 
static void DelayMicro(uint32_t us); 
 
static void DigitalWrite(uint32_t portbase, uint8_t pinmask, uint8_t value); 
 
static void PinMode(uint32_t portbase, uint8_t pinmask, uint8_t value); 
 
}; 
 
#endif /* GENERALUTIL_H_ */ 
 
/* 
 * RotorManager.cpp 
 * 
 *  Created on: Oct 27, 2015 
 *      Author: Stephen Dunn, Josh Lamb 
 */ 
 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_memmap.h" 
#include "inc/hw_types.h" 
#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/rom.h" 
#include "driverlib/rom_map.h" 
#include "driverlib/sysctl.h" 
#include "driverlib/pwm.h" 
 
#include "GeneralUtil.h" 
#include "AS5132Sensor.h" 
#include "RotorManager.h" 
#include "Timer.h" 
 
RotorManager::RotorManager(uint32_t port, uint8_t pinCS, uint8_t pinCLK, uint8_t pinDIO, uint32_t coilPort, uint8_t coilPin, 
ThrottleManager* throttle) { 
// initialize the sensor object and throttle dependency 
mAms = new AS5132Sensor(port, pinCS, pinCLK, pinDIO); 
mThrottle = throttle; 
 
// store port and pin information for later 
mCoilPort = coilPort; 
mCoilPin = coilPin; 
 
// assume the coil is off to start 
mCoilEnabled = false; 
 
// configure the coil pin and actually turn the coil off. 
GeneralUtil::PinMode(mCoilPort, mCoilPin, OUTPUT); 
DeactivateCoil(); 

Page 91​
 of 103 

 
 
// initial values 
mMicrosSinceMeasurement = 0; 
mMeasuredAngle = 0; 
mMeasuredVel = 0; 
mAngle = 0; 
mVel = 0; 
mIsFirstReading = true; 
mIgnoreCount = 0; 

 
RotorManager::~RotorManager() { 
delete mAms; 

 
void RotorManager::Update() { 
// the first reading is handled slightly differently because there 
// is no previous reading to compare with. 
if(mIsFirstReading) { 
Timer::ResetAndStart(); // start the timer for next time 
mAms­>TakeReadings(); // grab some angle readings 
 
// multiply by 1000 to bring the values into a better range for computation 
mMeasuredAngle = mAngle = mAms­>GetAngle() * 1000; 
mIsFirstReading = false; 
return; 

 
uint32_t microsSinceUpdate = Timer::GetElapsedMicro(); // first note the timestamp of the readings 
Timer::ResetAndStart();  // start the 
timer again for next time 
mAms­>TakeReadings();
// grab some angle readings 
mMicrosSinceMeasurement += microsSinceUpdate; // keeping track of time between good 
measurements 
int32_t newAngle = mAms­>GetAngle() * 1000;  // again, brings the values into a better range 
for computation. 
int32_t oldAngle = mMeasuredAngle; 
 
// only take a real reading if there are no error conditions from the sensor, 
// and the angle reading is different from last time. 
if((mAms­>GetIsRangeFault() || mAms­>GetLockADC() || newAngle == oldAngle) && mIgnoreCount < 100) { 
 
// the ams did not read a new angle, or some other error occored. 
// ignore the reading and estimate the next angle based on the known speed of the rotor. 
//mAngle += mVel * microsSinceUpdate; 
mIgnoreCount++; 
} else { 
// the ams read a new angle, or there have been more than 10 identical readings in a row. 
// store the new angle 
mMeasuredAngle = mAngle = newAngle; 
 
// properly handle the transition from zero to 359 or from 359 to zero. 
int32_t delta = (newAngle ­ oldAngle); 
if(delta < ­180) { 
oldAngle = oldAngle ­ 360; 
delta = newAngle ­ oldAngle; 
} else if(delta > 180) { 
newAngle = newAngle ­ 360; 
delta = newAngle ­ oldAngle; 

 

Page 92​
 of 103 

 
// calculate measured velocity 
mMeasuredVel = mVel = (float)delta / (float)mMicrosSinceMeasurement; 
 
// reset some variables 
mMicrosSinceMeasurement = 0; 
mIgnoreCount = 0; 

 
// idle state 
if(IsIdle() && mThrottle­>GetPercent() == 0) { 
DeactivateCoil(); 
return; 


 
void RotorManager::ActivateCoil(bool modulate) { 
// this logic allows the rotor to actually turn on only ever­other time it is told to 
// if "modulate" is set to true. This reduces the field strength in the rotor 
// allowing for higher speeds with less back emf. 
if(modulate) { 
if(!mCoilEnabled) { 
ROM_GPIOPinWrite(mCoilPort, mCoilPin, 0xFF); 
mCoilEnabled = true; 
} else { 
DeactivateCoil(); 

} else { 
ROM_GPIOPinWrite(mCoilPort, mCoilPin, 0xFF); 
mCoilEnabled = true; 


 
void RotorManager::DeactivateCoil() { 
ROM_GPIOPinWrite(mCoilPort, mCoilPin, 0x00); 
mCoilEnabled = false; 

 
 
/* 
 * RotorManager.h 
 * 
 *  Created on: Oct 27, 2015 
 *      Author: Stephen Dunn, Josh Lamb 
 */ 
 
#ifndef ROTORMANAGER_H_ 
#define ROTORMANAGER_H_ 
 
#include <math.h> 
 
#include "ThrottleManager.h" 
#include "AS5132Sensor.h" 
 
/* 
 * The rotor manager class manages the rotor of the motor. It is able to report the angle and speed of the rotor 
 * using information from the rotary position sensor. This class is tolerant to bad readings from the sensor 
 * and will estimate the position of the rotor using previously obtained data. This class is also used to turn the 
 * coils within the rotor on and off. 
 */ 
class RotorManager { 
public: 

Page 93​
 of 103 

 
RotorManager(uint32_t port, uint8_t pinCS, uint8_t pinCLK, uint8_t pinDIO, uint32_t coilPort, uint8_t coilPin, 
ThrottleManager* throttle); 
virtual ~RotorManager(); 
 
// turn on the rotor coil 
void ActivateCoil(bool modulate); 
 
// turn off the rotor coil 
void DeactivateCoil(); 
 
// update the position information of the rotor coil. 
void Update(); 
 
// in degrees 
float GetAngle() { return mAngle / 1000.0; } 
 
// degrees per second 
float GetVel() { return mVel * 1000.0; } 
 
bool IsIdle() { return fabs(GetVel()) < 100.0; } 
 
private: 
// sensor object 
AS5132Sensor* mAms; 
 
// microseconds since a real­data measurement 
uint32_t mMicrosSinceMeasurement; 
 
// private measurements. Always equal to the last real measurement. 
int32_t mMeasuredAngle; 
float mMeasuredVel; 
 
// the "public" values. Can be actual or estimated values depending on the situation. 
float mAngle; // thousandths degrees 
float mVel; // thousand degrees per microsecond 
 
// special handling for the first update. 
bool mIsFirstReading; 
 
// remembers if the coil is currently on or off 
bool mCoilEnabled; 
 
// if too many readings are ignored in a row due to the data being duplicated, 
// go ahead and take a new reading anyway. 
uint8_t mIgnoreCount; 
 
// port and pins for controlling the rotor coil 
uint32_t mCoilPort; 
uint8_t mCoilPin; 
 
ThrottleManager* mThrottle; 
}; 
 
#endif /* ROTORMANAGER_H_ */ 
 
/* 
 * State.cpp 
 * 
 *  Created on: Nov 5, 2015 
 *      Author: Stephen 
 */ 
 

Page 94​
 of 103 

 
#include <stdint.h> 
 
#include "inc/hw_memmap.h" 
#include "inc/hw_types.h" 
#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/rom.h" 
#include "driverlib/rom_map.h" 
#include "driverlib/sysctl.h" 
 
#include "State.h" 
#include "GeneralUtil.h" 
 
State::State(PinAssignments* pins, int32_t baseAngle, int32_t timing) { 
// store off the pin assignments 
mPins = pins; 
 
// configure the pins for output 
GeneralUtil::PinMode(mPins­>OnPortP, mPins­>OnPinP, OUTPUT); 
GeneralUtil::PinMode(mPins­>OnPortN, mPins­>OnPinN, OUTPUT); 
 
// but turn them off to start 
Deactivate(); 
 
// the optimal quadrature angle at which to push the rotor is calculated given 
// the base angle of the stator coil minus (that is, counter­clockwise) the timing 
// angle. This greates a quadrature point around which to pulse the stator. 
mOptimalAngle = baseAngle ­ timing; // for clockwise operation, make this a plus instead. 
 
// make sure the angles play nice with the 0­>360 border 
if(mOptimalAngle > 359) mOptimalAngle ­= 360; 
if(mOptimalAngle < 0) mOptimalAngle += 360; 

 
bool State::CanHandleAngle(uint32_t rotorAngle, uint32_t throttlePercent) { 
// short circuit to speed up logic if the throttle is off 
if(throttlePercent == 0) 
return false; 
 
// this will be the number of degrees before and after the quadrature point 
// to start and stop the rotor pulse 
float angleDelta = (HALF_STATE_SEP_DEGREES * (float)throttlePercent) / 100.0; 
 
// min and max angles 
float minAngle = mOptimalAngle ­ angleDelta; 
float maxAngle = mOptimalAngle + angleDelta; 
 
// make them play nice with the 0­>360 border 
if(minAngle < 0) minAngle += 360.0; 
if(minAngle > 359) minAngle ­= 360.0; 
if(maxAngle < 0) maxAngle += 360.0; 
if(maxAngle > 359) maxAngle ­= 360.0; 
 
// range does not overlap the 0 degrees mark. 
// traditional min/max apply here 
if(minAngle < maxAngle) { 
if(rotorAngle >= minAngle && rotorAngle < maxAngle) 
return true; // rotor angle is within the quadrature pulse angle range. 
else 
return false; // rotor angle is outside the quadrature pulse angle range. 
} else { 
// range overlaps the 0 degrees mark. 

Page 95​
 of 103 

 
// use different concept of min/max here 
if((rotorAngle >= 0 && rotorAngle < maxAngle) || (rotorAngle <= 359 && rotorAngle >= minAngle)) 
return true; // rotor angle is within the quadrature pulse angle range. 
else 
return false; // rotor angle is outside the quadrature pulse angle range. 


 
bool State::Activate() { 
// set the pins on. 
ROM_GPIOPinWrite(mPins­>OnPortP, mPins­>OnPinP, ALL_HIGH); 
ROM_GPIOPinWrite(mPins­>OnPortN, mPins­>OnPinN, ALL_HIGH); 

 
void State::Deactivate() { 
// turn the pins off 
ROM_GPIOPinWrite(mPins­>OnPortP, mPins­>OnPinP, 0); 
ROM_GPIOPinWrite(mPins­>OnPortN, mPins­>OnPinN, 0); 

 
/* 
 * State.h 
 * 
 *  Created on: Nov 5, 2015 
 *      Author: Stephen 
 */ 
 
#ifndef STATE_H_ 
#define STATE_H_ 
 
#include <stdint.h> 
 
#define STATE_SEP_DEGREES 10.0 // the seperation in degrees between stator coils 
#define HALF_STATE_SEP_DEGREES 5.0 // half that value... 
 
/* 
 * A structure to associate 2 pins with eachother, one controlling a P­Channel MOSFET 
 * and another controlling an N­Channel MOSFET 
 */ 
struct PinAssignments { 
 
PinAssignments(uint32_t onPortP, uint8_t onPinP, uint32_t onPortN, uint8_t onPinN) { 
OnPortP = onPortP; 
OnPinP = onPinP; 
OnPortN = onPortN; 
OnPinN = onPinN; 

 
// for the P­Channel mosfets (high­side switches) 
uint32_t OnPortP; 
uint8_t OnPinP; 
 
// for the N­Channel mosfets (low­side switches) 
uint32_t OnPortN; 
uint8_t OnPinN; 
 
}; 
 
/* 
 * Represents a single state in the sequence of states needed to run the motor. 
 * Essentially, this is coorelated with a particular stator coil polarized in a particular direction. 
 * These states repeat 6 times every 60 degrees for a total of 360 degrees. 

Page 96​
 of 103 

 
 * Each state is assigned a particular set of pins. When the state is on, those pins are on. Otherwise, those pins are off. 
 */ 
class State { 
public: 
State(PinAssignments* pins, int32_t baseAngle, int32_t timing); 
 
// returns true if the given angle is suitable to be handled by this state 
bool CanHandleAngle(uint32_t rotorAngle, uint32_t throttlePercent); 
 
// activates the pins associated state 
bool Activate(); 
 
// deactivates the pins associated with the state 
void Deactivate(); 
 
private: 
// the pins associated with this state 
struct PinAssignments* mPins; 
 
// optimal torque angle for this state. 
// calculated once at startup. 
int32_t mOptimalAngle; 
}; 
 
#endif /* STATE_H_ */ 
 
/* 
 * StatorManager.cpp 
 * 
 *  Created on: Oct 29, 2015 
 *      Author: Joshua, Stephen 
 */ 
#include "StatorManager.h" 
 
StatorManager::StatorManager( 
RotorManager* rotor, ThrottleManager* throttle, 
uint32_t portC, uint8_t pinC4, uint8_t pinC5, uint8_t pinC6, uint8_t pinC7, 
uint32_t portF, uint8_t pinF1, uint8_t pinF2, uint8_t pinF3, uint8_t pinF4) { 
 
mRotor = rotor; 
mThrottle = throttle; 
 
mModulateCoil = false; 
 
// this is where the pin assignments, base angles and quadrature angles are configured 
// for each state (stator coil). This list need not be in any particular order 
// as long as each coil is configured correctly. 
mStates[0] = new State(new PinAssignments(portF, pinF3, portC, pinC5), 10, STATOR_TIMING); 
mStates[1] = new State(new PinAssignments(portF, pinF3, portC, pinC7), 20, STATOR_TIMING); 
mStates[2] = new State(new PinAssignments(portF, pinF3, portF, pinF2), 30, STATOR_TIMING); 
mStates[3] = new State(new PinAssignments(portC, pinC4, portF, pinF4), 40, STATOR_TIMING); 
mStates[4] = new State(new PinAssignments(portC, pinC6, portF, pinF4), 50, STATOR_TIMING); 
mStates[5] = new State(new PinAssignments(portF, pinF1, portF, pinF4), 60, STATOR_TIMING); 

 
void StatorManager::Update() { 
// grab the needed info from the rotor and throttle 
float rotorAngle = mRotor­>GetAngle(); 
uint32_t throttlePercent = mThrottle­>GetPercent(); 
 
// convert the rotor angle to an effective angle. 
// This is possible because the 6 states repeat 6 times every 60 degrees 

Page 97​
 of 103 

 
// to make a full 360. 
float effectiveAngle = (uint32_t)rotorAngle % 60; 
 
// keep track of which state should be on. 
int32_t activeState = ­1; // less than 0 means no active state 
 
// Handle the Rotor coil behavior for different situations 
if(mRotor­>IsIdle()) { 
if(throttlePercent > 5) { 
// startup state 
throttlePercent = 100; // simulate 100 percent throttle for startup 
mModulateCoil = false; 
} else { 
// idle state 
throttlePercent = 0; 
mModulateCoil = false; 

} else { 
// run or regen states 
mModulateCoil = true; 

 
// figure out which states (if any) need to be on. 
// at the same time, deactivate states which can't handle the current angle. 
for(int i = 0; i < 6; i++) { 
if(mStates[i]­>CanHandleAngle(effectiveAngle, throttlePercent)) { 
activeState = i; 
} else { 
mStates[i]­>Deactivate(); 


 
// activate the single active state (if any) 
if(activeState >= 0) { 
mStates[activeState]­>Activate(); 
mRotor­>ActivateCoil(mModulateCoil); // the coil should only be on when a state is on too. 
} else { 
mRotor­>DeactivateCoil(); 


 
/* 
 * StatorManager.h 
 * 
 *  Created on: Oct 29, 2015 
 *      Author: Joshua, Stephen 
 */ 
 
#ifndef STATORMANAGER_H_ 
#define STATORMANAGER_H_ 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_memmap.h" 
#include "inc/hw_types.h" 
#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/rom.h" 
#include "driverlib/rom_map.h" 
#include "driverlib/sysctl.h" 
 
#include "State.h" 
#include "GeneralUtil.h" 

Page 98​
 of 103 

 
#include "RotorManager.h" 
#include "ThrottleManager.h" 
 
#define STATOR_TIMING 5 // ** THIS IS THE QUADRATURE ANGLE FOR ALL STATES ** 
 
class StatorManager { 
private: 
// access to the rotor and throttle 
RotorManager* mRotor; 
ThrottleManager* mThrottle; 
 
// all 6 discrete states needed to make a complete rotation. 
// these states are repeated 6 times every 60 degrees to make a full 360. 
State* mStates[6]; 
 
// depending on the situation, we may want to modulate the rotor coil 
// in order to increase efficency, reduce back emf, and increase speed. 
bool mModulateCoil; 
 
public: 
StatorManager( 
RotorManager* rotor, ThrottleManager* throttle, 
uint32_t portC, uint8_t pinC4, uint8_t pinC5, uint8_t pinC6, uint8_t pinC7, 
uint32_t portF, uint8_t pinF1, uint8_t pinF2, uint8_t pinF3, uint8_t pinF4); 
 
// Runs the logic to turn the coils on and off. 
void Update(); 
}; 
 
 
#endif /* STATORMANAGER_H_ */ 
 
/* 
 * ThrottleManager.cpp 
 * 
 *  Created on: Nov 3, 2015 
 *      Author: Stephen 
 */ 
 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_memmap.h" 
#include "inc/hw_types.h" 
#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/rom.h" 
#include "driverlib/rom_map.h" 
#include "driverlib/sysctl.h" 
#include "driverlib/adc.h" 
 
#include "ThrottleManager.h" 
#include "math.h" 
 
// min and max numerical readings from the ADC 
#define THROTTLE_MIN 700 
#define THROTTLE_MAX 3600 
 
ThrottleManager::ThrottleManager(uint32_t port, uint8_t pinVin) { 
 
// enable analog function on the pin 
ROM_GPIOPinTypeADC(port, pinVin); 
 

Page 99​
 of 103 

 
ROM_ADCReferenceSet(ADC0_BASE, ADC_REF_INT); // uses the internal 3V reference 
 
// disable sequencer 3 before configuration 
ROM_ADCSequenceDisable(ADC0_BASE, 3); 
 
// Use sequencer 3 on ADC0, triggered manually by the processor, with the higest priority (0). 
ROM_ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); 
ROM_ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_IE | ADC_CTL_END | ADC_CTL_CH0); 
 
// enable sequencer 3 
ROM_ADCSequenceEnable(ADC0_BASE, 3); 
 
// trigger a sequence so the value is ready for the first update. 
ROM_ADCProcessorTrigger(ADC0_BASE, 3); 

 
int32_t ThrottleManager::GetPercent() { 
return mPercent; 

 
void ThrottleManager::Update() { 
 
uint32_t rawReading; 
 
// Wait until the previous sample sequence has completed 
// but dont wait forever lest we hang the microcontroller. 
uint32_t tries = 0; 
while(!ROM_ADCIntStatus(ADC0_BASE, 3, false)) { 
tries++; 
if(tries > 10) return; 

 
// Read the value from the ADC. 
ROM_ADCSequenceDataGet(ADC0_BASE, 3, &rawReading); 
 
// convert to a percent using known min and max numerical values from the ADC 
// these were determined expirementally and contain a small amount of slack 
// on the high and low ends. 
mPercent = ((int32_t)rawReading ­ THROTTLE_MIN) / ((THROTTLE_MAX ­ THROTTLE_MIN) / 100); 
 
// clamp to 0 and 80 percent for reliability reasons. 
if(mPercent < 0) mPercent = 0; 
if(mPercent > 80) mPercent = 80; 
 
// finally, trigger the sequencing so the value is ready for next time 
ROM_ADCProcessorTrigger(ADC0_BASE, 3); 

 
/* 
 * ThrottleManager.h 
 * 
 *  Created on: Nov 3, 2015 
 *      Author: Stephen 
 */ 
 
#ifndef THROTTLEMANAGER_H_ 
#define THROTTLEMANAGER_H_ 
 
class ThrottleManager { 
public: 
ThrottleManager(uint32_t port, uint8_t pinVin); 
 

Page 100​
 of 103 

 
// grabs the throttle information from the hardware 
void Update(); 
 
// returns the last read throttle percent 
int32_t GetPercent(); 
 
private: 
// the last read throttle percent 
int32_t mPercent; 
}; 
 
#endif /* THROTTLEMANAGER_H_ */ 
 
/* 
 * Timer.cpp 
 * 
 *  Created on: Oct 27, 2015 
 *      Author: Stephen 
 */ 
 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_memmap.h" 
#include "inc/hw_types.h" 
#include "inc/hw_nvic.h" 
#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/rom.h" 
#include "driverlib/rom_map.h" 
#include "driverlib/sysctl.h" 
#include "driverlib/ssi.h" 
#include "driverlib/systick.h" 
 
#include "Timer.h" 
#include "GeneralUtil.h" 
 
#define SYS_TICK_PERIOD_MAX 0xFFFFFF 
 
void Timer::ResetAndStart() { 
ROM_SysTickDisable(); // stop the timer tick 
ROM_SysTickPeriodSet(SYS_TICK_PERIOD_MAX); 
*((uint32_t*)NVIC_ST_CURRENT) = 0x01;// writing any value triggers immediate reset of counter value 
ROM_SysTickEnable(); // start the timer tick 

void Timer::Stop() { 
ROM_SysTickDisable(); 

 
// Elapsed since last reset 
uint32_t Timer::GetElapsedMicro() { 
// get the counter value 
uint32_t sysTickValue = ROM_SysTickValueGet(); 
 
// assumed 80MHz clock for speed of operation 
float nanosPerClock = 12.5; // The actual calculation: (1000000000.0 / (float)GeneralUtil::GetSysClock()); 
 
// calculate the elapsed clock cycles and convert to microseconds. 
uint32_t elapsedClocks = SYS_TICK_PERIOD_MAX ­ sysTickValue; 
uint32_t elapsedMicros = (elapsedClocks * nanosPerClock) / 1000; 
 
return elapsedMicros; 

Page 101​
 of 103 

 
 
/* 
 * Timer.h 
 * 
 *  Created on: Oct 27, 2015 
 *      Author: Stephen 
 */ 
 
#ifndef TIMER_H_ 
#define TIMER_H_ 
 
/* 
 * General purpose timer for measuing the time between events 
 */ 
class Timer { 
public: 
 
// resets the timer to zero, and starts it again. 
static void ResetAndStart(); 
 
// stops the timer alltogether 
static void Stop(); 
 
// returns the number of microsenconds since the timer was started 
static uint32_t GetElapsedMicro(); 
}; 
 
#endif /* TIMER_H_ */ 
 
 

Page 102​
 of 103 

Das könnte Ihnen auch gefallen