EE 416
DC/AC Power
Inverter Design
Progress Report A u t h o r s :
J a y s o n E d m u n d s o n
A d a m P e r e t t i
A d a m Y a c k l e y
M e n t o r :
D a v i d D e V r i e s
Team Flavius
Table of Contents
Executive Summary ................................................................................................................................ 3
Introduction ............................................................................................................................................ 4
Project Description ................................................................................................................................. 5
Inverter Method ................................................................................................................................. 5
Pulse Width Modulation ................................................................................................................. 6
Noise ............................................................................................................................................... 6
Overview ......................................................................................................................................... 7
Project Approach ................................................................................................................................ 7
Control Strategy ................................................................................................................................. 8
Modeling, Simulation, and Engineering Analysis ................................................................................... 9
H-Bridge .............................................................................................................................................. 9
Transformer ...................................................................................................................................... 11
Stepped PWM Switches ................................................................................................................... 12
Simulation ......................................................................................................................................... 12
Output Filter ..................................................................................................................................... 16
Microcontroller Programming .............................................................................................................. 17
Project Management and Future Work ............................................................................................... 19
Individual and Team Tasks............................................................................................................ 19
Delays and Future Work ............................................................................................................... 19
RISK MANAGEMENT ......................................................................................................................... 21
Impact Analysis ..................................................................................................................................... 23
Conclusion ............................................................................................................................................ 24
References ............................................................................................................................................ 25
Appendices ........................................................................................................................................... 26
Appendix A Data Sheets ( double-click on the grey boxes) ........................................................... 26
Appendix B - Microcontroller Code .................................................................................................. 26
Assembly Code ............................................................................................................................. 26
C Code ........................................................................................................................................... 61
Executive Summary
This report discusses the progress made by Team Flavius between January 11th
and March 5th
2010. As
described in the original project proposal, Team Flavius is designing a high efficiency, low cost DC/AC
single phase power inverter. This inverter is planned to be a proof of concept prototype that can be
further developed to fit the needs of a possible end user.
The market for high quality DC to AC power converters is expanding, especially with the recent
government emphasis on alternative forms of energy. Current designs of DC to AC power converters,
also called inverters, generally use one of two techniques. Between these two techniques is a classic
tradeoff between price and quality. The proposed design can create a high efficiency, high quality
output, while meeting the price point of lower quality inverters. It accomplishes this by using a different
method than inverters currently available, coupled with a microcontroller (simple computer) to simplify
the rest of the design.
Team Flavius has made progress in modeling/simulation of the inverter components, researched
programming practices of microcontrollers, and created a work-flow diagram as a road map to
converting a DC signal to a sinusoidal AC signal. Described below in the Modeling, Simulation, and
Engineering Analysis section of this document, Team Flavius describes how parts have been modeled
and simulated, and how engineering analysis has been used to validate and refine each component of
the inverter.
Remaining work on the project includes
testing of the final PCB layout for proof
of concept, building an enclosure for the
inverter and prototype station for safety
and exhibition, programming a GUI to
use during exhibition, and testing the
total harmonic distortion of the entire
system plus analog loads. By April 22nd
2010, Team Flavius is confident the
above work will be completed.
1- Team Flavius working on a PSPICE analysis and Microcontroller programming
Introduction
Team Flavius is currently developing algorithms in C++ and refining models of the inverter components
as defined in the Final Design Proposal submitted 11-29-09. Following the completion of the proposal
and oral presentation to David DeVries, Team Flavius lost a team member which has yet to slow the
teams progress. While the loss of Team member Brendon Mesick has increased each team members
work load, the structure of EE 416 has allowed more time for Team Flavius to meet and produce more
relative work per meeting than in the previous EE 415 semester.
Team Flavius worked with David DeVries to finalize the printed circuit board (PCB) design specifications
and have the PCB fabricated through a third party. After the PCB was manufactured, DeVries obtained
the board and proceeded to incorporate the working sections of the inverter into the board. As of this
writing, the board has not been fully assembled for testing.
Since the PCB is not yet in a state to test functionality, Team Flavius has been modeling the H-bridge,
toroidal transformer, switches, and output filter. Ideal sources were used in conjunction with the LT
Spice models to gain intuitive responses with respect to the sinusoidal and square-wave inputs.
The use of a micro controller has introduced some design challenges and uncertainties, although the
team has been able to solve these with the help of Chris Berg from Impel Systems. With a solid
background in Computer Engineering, Edmundson has completed the low-level logic controlling of the
microcontroller and an open-loop algorithm of the MOSFET switching scheme. A closed-loop Algorithm
is being formulated and will be present on the final design.
This report is a milestone in the development process and while much has been accomplished, Team
Flavius recognizes that more work is required to complete the project. Ultimately, the DC/AC inverter
will demonstrate the proposed design concept can triumph in both signal quality and price
competitiveness. While Team Flavius has studied several facets of product integration into lucrative
markets, some practical concerns such as safety implementation and heat dissipation could drive the
cost out of the target value. While these implications directly affect the acceptance of the inverter
proposed, such design criteria are out of the scope of this design project. However, once the
groundwork has been laid by Team Flavius for proof of design, extra work desired in the safety and
cooling sectors could easily be addressed. A detailed report of the project follows, including engineering
analysis and an updated section on project management.
Project Description
Inverter Method
There are two main classifications of inverters; a true sinusoidal and a modified wave inverter. If the
inverter produces equal or better signal fidelity compared to the utility grid, the inverter is classified as a
true sinusoidal inverter. When an inverter does not meet the aforementioned specification, it is
classified as a modified wave inverter.
Since true sinusoidal inverters are required for a variety of sensitive commercial and industrial
equipment, there is a large market for efficient (i.e. cost and power) and accurate inverters. Currently, a
true sinusoidal inverter, with a power rating of 1KW, costs 30-50cents/watt; the price depends on power
efficiency and accuracy.
At its simplest level, a power inverter consists of a single full-bridge inverter also known as an H-bridge
(Figure 1). An H-bridge uses two sets of switches that operate 180 degrees out of phase, which reverse
the polarity of the dc signal and create a square periodic waveform [1].
Figure 1: H-Bridge Diagram [4]
A square periodic signal has a limited number of applications. So to increase the fidelity of a signal, a
technique known as pulse width modulation is often implemented.
Pulse Width Modulation
Pulse width modulation, or PWM, has become an accepted method for generating unique signals, due
to the advancement of microcontrollers and its power efficiency. To create a sinusoidal signal, PWM
uses high frequency square waves with varying duty cycles [1]. Duty cycle is the percentage of time the
signal is on relative to the period. This means as the duty cycle increases, more power is transmitted
(Figure 2).
Figure 2: Pulse Width Modulation of a Sinusoidal
PWM requires rapid on and off signals, which can be achieved using high power MOSFETs [3]. MOSFETs
are ideal switches due to the low power loss when the device is activated. It should be noted, however,
that when a MOSFET is in transition between on and off, the power loss can be significant. For this
reason, the transition times and frequency should be engineered to be as short as possible. This can be
achieved by minimizing the amplitude between the on and off stages and lowering the PWM frequency;
however as the frequency decreases so does the signal quality.
Noise
Due to a non-ideal environment, noise or interference must be taken into consideration. Examples of
interference include: induced current or voltage due to electromagnetic fluxes, thermal noise caused by
unwanted electron movement, and other unpredictable noise within the circuit. To compensate for such
volatile signals and produce a low signal-to-noise ratio, a feedback loop must be implemented. The
design of the feedback is dependent on the quality and safety requirements of the inverter [8]. Most
common feedback loops use a PID controller. A PID controller implements three different parameters:
proportional, integral and derivative. The proportional fraction reacts to the present error of the system,
the integral counters the sum of errors, and the derivative function attempts to anticipate the error.
Overview
As microprocessors have continued to increase in power efficiency and drop in cost, they have
simultaneously become progressively more attractive to the inverter process. Microcontrollers are
specialized processors designed to be self-sufficient and cost-effective. It is possible to program a
microcontroller to control the output of an inverter, and receive feedback to correct any issues of noise
[2]. Solid state devices, such as microcontrollers, continue to become faster and less expensive; which
allows advanced and cost efficient true-sinusoidal inverters.
Project Approach
The team divided the inverter process into four steps (Figure 3). First, the constant DC signal must be
converted into a period signal. Second, the magnitude of the signal must be increased from 24V to 120V
RMS to meet our target specifications. Third, a true sinusoidal wave must be built out of the periodic
signal through the use of PWM. Lastly, the signal will remove noise and harmonic distortion through the
use of an LC passive filter.
Figure 3: Functional Block Diagram
Control Strategy
An early decision to make is simple open-loop control versus a closed-loop system using feedback. While
purely open-loop control is far easier to implement and may work if everything performs according to
theory, it is unlikely to be reliable in reality. It does not account for variability in manufacturing of the
device components and the device itself. Furthermore, it is unable to deal with error imposed from
external sources, such as non-ideal input, electromagnetic interference, or volatile loading scenarios.
Due to these factors, a control scheme lacking feedback is not an option.
With the microcontroller, there also exist several schemes involving machine learning, such as neural
networks. While these are theoretically the most adaptive, they are also somewhat unpredictable, and
ill-suited to an application as sensitive as power delivery. One possible use of machine learning could be
adaptive gains for a PID controller. However, thought must be given to decide if this is far more complex
than necessary, and if it is even possible given resources available to an embedded microcontroller [7].
The last step in the process is filtering, which will eliminate harmonics and transients that are unwanted
in modern power systems. A variety of filters have been tested, and the final design has yet to be
chosen.
Modeling, Simulation, and Engineering Analysis
The design of the AC/DC inverter has several steps that required multiple levels of simulation and
analysis. The majority of the simulation and testing was completed in PSPICE. PSPICE allowed for in
depth and specific analysis. In the near future, MatLab will be used for a complete system modeling;
however, due to the limitations of Simulink, specifically Simscape, the simulation will use ideal
components. The following sections are split into different stages
of the inverting process and will describe the simulations and
analysis performed.
H-Bridge
Starting at the beginning of the inverter process, the H-bridge,
PSPICE was used to emulate the electrical output of the MOSFET
switches and drivers. Due to the limitations of the MOSFET driver
model, only a few simulations were conducted. The inadequacy
of the model and the causes will be discussed later.
The MOSFET driver and MOSFET PSPICE models were available
from International Rectifier. Since PSPICE does not have
programmable logic circuits, the inputs were manually setup
using two stepped voltage sources. To make sure, each
component worked correctly, the team took an iterative setup and design approach for the simulation.
The first design used all ideal components to
ensure the logic of the circuit was correct. In
principle, four MOSFETs are used to reverse
the direction of current across a load every
40us. This is achieved by allowing two pairs
of MOSFETs to turn on 180 degrees out of
phase with respect to each other. The first
simulation responded as expected; that is
the voltage across the 100Ohm load
0s 16s 32s 48s 64s 80s
-25V
-20V
-15V
-10V
-5V
0V
5V
10V
15V
20V
25VV(POS,NEG)
H-Bridge Schematic 1: Ideal H-Brdige Components
H-Bridge Plot 1: Voltage across the R1 resistor from H-Bridge Schematic 1
reversed at a rate of 50 KHz (H-Bridge Plot and Schematic 1).
Once the ideal design was complete, the schematic components were implemented. First the MOSFET
model, IRFB4410, replaced the ideal MOSFETs. The IRFB4410 data table can be accessed in the Appendix
A. As seen in H-Bridge Plot 2, the resulting plot and data acted remarkably similar to the ideal MOSFETs.
The results show a near zero rise and fall time, which is excellent for the transformer and switching
scheme. Any overshoot or long rise/fall time could cause the PWM switching scheme to be unstable or
produce unreliable results.
Preferably, the feedback control
system will fix any issues, but the
system should not rely strictly on
the control.
The next simulation step includes
the MOSFET driver, IR2117. The
drivers main purpose is to keep the
gate voltage 12V above the source
when it the MOSFET is enabled, and
then drive the gate to the source voltage, when the MOSFET is disabled. The expected response of the
driver is approximately 100ns; meaning that after the MOSFET driver is enabled it will take 100ns to
drive the gate voltage to 12V with respect to the source.
At the very beginning of the simulation, problems with program and driver started to arise. While PSPICE
was simulating, it would hang and report that the time step was too small to continue. After researching
the error, it turns out that the problem usually occurs when there is a discontinuity in the circuit
calculations. While examining the error log, it was determined that a diode within the MOSFET driver
was causing the issue. In the IR2117 PSPICE readme, it specifies that MicroSim PSPICE should be used
and that if time step errors do occur, to change specific values in the simulator. Unfortunately, due to a
lack of funds, the team has been using a free version of SPICE known as LTSPICE. While the SPICE
programs are somewhat similar, it is possible that the error could be caused by LTSPICE.
During the troubleshooting process, the team determined the MOSFET will work given certain inputs
and conditions. If the input to the MOSFET drain starts at zero and is immediately increased to 24V,
while the enable input to the MOSFET is a constant DC source, the MOSFETs turn on as desired. The
0s 8s 16s 24s 32s 40s 48s 56s 64s 72s 80s
-25V
-20V
-15V
-10V
-5V
0V
5V
10V
15V
20V
25VV(POS,NEG)
H-Bridge Plot 2: Voltage across resistor R1 after MOSFET model was implemented
described conditions provided a static proof of concept that the switches work, however, the result was
slightly disappointing given the simulators capabilities. At any rate, the H-bridge has been tested by
David Devries and perform as expected. When the team receives the board, more iterative testing will
be completed.
Transformer
Moving on to the transformer, the core material was simulated in PSPICE. According to the core
specifications, the effective area is 154.2mm2 and the relative permeability is 2200 units. Unfortunately,
the simulation through PSPICE is not completely accurate, because the transformer is being custom
wound, so the type of wire, number of windings, and the mutual inductance is still unknown. For this
reason, the simulation results are used only to
get a general grasp of the transformer
response, limitations and other peculiarities.
Since the transformers input is a square wave
several problems need to be taken into
consideration. Specifically, after the square
wave reaches its peak it remains relatively
steady; which will cause the magnetic flux to
decrease and as seen in Transformer Plot 1,
the secondary induction will create a quasi-
square wave that trails towards zero near peak
period. To resolute the lack of magnetic flux
the mutual induction must increase; which can
be accomplished by increasing the number of primary and secondary windings. More windings increase
the magnetic flux, but cause the saturation current to decrease; which means less power can pass
though the transformer.
In addition to mutual induction, there is a slight delay in rise time, which should be taken into
consideration when programming the H-bridge. To enumerate, the H-bridge should preemptively switch
to accommodate for the delay.
Transformer Plot 1: Result of the transformer core and 50 windings
on the primary. The red line represents the input to the transformer.
Stepped PWM Switches
The stepped switching scheme uses the same MOSFET driver as the H-bridge, so the simulations will
show limited and specific circuit scenarios. At any rate, the simulations still provided the team with a
proof of concept and helped solidify the workings of the circuit.
Simulation
During the first PSPICE simulations, the results were less than ideal. The simulation applied a 170V
sinusoidal wave to the MOSFET, while the driver either enabled or disabled the MOSFETS. When the
driver was enabled, the MOSFET operated perfectly; however, when the driver was disabled, the
MOSFET turned on during two different stages of the sinusoidal input. When the input was higher than
150V the MOSFET broke down. This was expected due to the 150V VDS rating of the MOSFET. However,
when the sinusoidal input reached a negative value the driver was unable to keep the gate voltage low
enough. This failure caused the MOSFET to turn on and pass a current. After several days of analysis and
troubleshooting, the team realized that the setup did not accurately represent the schematic operation.
Specifically, while the output of
the inverter appears to be a
sinusoidal, which ranges from
negative to positive 170V, the
MOSFET input would only range
from 0V to 170V.
Once the issue was resolved, the
Team needed to simulate the
MOSFET driver when it is off and
a square wave was applied to the
MOSFETs. To setup the experiment, a single switch was attached to a load as shown in Switch Schematic
1. The results in Switch Plot 1 show that as the input increases, the voltage of the load increases to 24V
and then drops after 5us. To test if the current through the MOSFET will cause problems, a second
switch was added in parallel and enabled (Switch Schematic 2). Switch Plot 2 shows that as long as
another switch is enabled it will drive the other switches to zero.
After the design of each switch was functioning properly, two switches were attached in series with a
load in between them (Switch Schematic 3). The proposed setup tested the functionality of reverse
Switch Schematic 1: PSPICE schematic of a single switch attached to a 1K resistor
0s 20s 40s 60s 80s 100s 120s
-4V
4V
12V
20V
28V
36V
44VV(output) V(input)
current flow, which has been of some concern. Additionally, the simulation emulated the actual function
of the schematic on a smaller scale. As seen in Switch Figure 3, the simulation worked as designed.
When both of the switches were enabled, the MOSFETs passed the signal across the resistive load.
Since the load attached to the inverter may not always be purely resistive, an inductor was added in
series to the resistor. The simulation confirmed the voltage remained steady, the MOSFET stayed on,
and the current steadied due to the inductor. The results proved, once again, that the circuit meets the
design requirements.
Switch Plot 1: When the MOSFET is disabled and the input increases, a small amount of current flows through
Switch Schematic 2: A second switch is enable to drive the first disable MOSFET to zero
0s 20s 40s 60s 80s 100s 120s
0V
20V
40V
60V
80V
100V
120V
140V
160V
180VV(disabled_in) V(output) V(in1)
Switch Plot 2: Resulting plot when a second MOSFET is present to drive the disabled MOSFET to zero
Switch Schematic 3: Proposed circuit for the existing switching scheme
0s 30s 60s 90s 120s
0V
40V
80V
120V
160V
V(in) V(output)
Switch Plot 4: Simulation results showing the design functions properly
0.0ms 0.1ms 0.2ms 0.4ms 0.5ms 0.6ms 0.7ms 0.8ms 0.9ms 1.1ms 1.2ms
-20V
20V
60V
100V
140V
180V
0mA
120mA
240mA
360mA
480mA
600mAV(output) I(R2)
Switch Plot 3: Simulation of Schematic 3 with a reactive load
Output Filter
The design criteria of the output filter was used to determine the components and their respective
values. Due to the H-bridge frequency of 24 KHz and the 43V switching magnitude, the team needed a
filter to reduce the time harmonic distortion to less than
3%; meaning the calculations expected the cut-off
frequency to be around 8 KHz [5].
To determine the frequency response of various filters,
PSPICE was used to calculate bode plots and the cutoff
frequency. The first simulation started with a simple LC
filter. From Filter Schematic 1, the components include a
6.8uF capacitor and a 100uH inductor. The capacitor is
set parallel to the inductor to pass high frequency noise. As seen in Filter Plot 1, the simulation provided
the desired cutoff frequency; however, there is a large resonance frequency. The resonance frequency
has a gain of 40dB at 6.5 KHz, and while the
inverter does not create any noise at this
frequency, any electromagnetic or thermal noise
at the resonance frequency could have damaging
effects on equipment.
To resolve the issue, the team used the design
algorithm, acquired from International Rectifiers
application note AN-1095 [6]. The design paper
specifies a dampening resistor in series to the
capacitor. The resistor decreases the gain at the
resonance frequency, but in a hand-off, increases
the cut-off frequency and decreases the roll-off
slope. To create a near critically damped RLC filter,
the resistor in series should range from 4-8 ohms
(Filter Schematic 2). The resulting Filter Plot 2
shows the response as the resistance is increased
and if the inductor is increased.
Filter Schematic 1: Simple LC output filter
Filter Plot 1: Bode Plot result of a simple LC filter
Microcontroller Programming
The approach used for the microcontroller programming can mostly be divided into two sections. The
first section simply takes the desired magnitude of the transformer output, a number, and determines
the correct pin configurations. This includes changing the configuration at the proper frequency to
Filter Schematic 2: Final output filter with dampening resistor
Filter Plot 2: Bode plots of output filter with vary resistor and inductor values
produce the PWM output. The majority of this is controlled and timed automatically using the
microcontrollers built in timers and interrupts. The various processes keep track of their status and
communicate with a global gate_state structure. When the target output level needs to be changed,
this is done with the set_output_level() function.
Section two is what determines what the magnitude should be. This is accomplished by implementing a
PID controller. Feedback is measured at the output of the device using an analog to digital converter.
Then error is calculated from this measurement and a reference of the desired waveform. This error is
then fed into the PIDMain() routine, which then outputs a correction, if necessary, to
set_output_level(). In order to properly calculate the derivative and integral terms, the PID system
also has a routine which is called at regular intervals via timer interrupt.
The organization of the source code roughly resembles this division, with the first section in
Switch_Control.c, and the second in PIDInt.asm. There are also several other source files for
neatness and conveniences sake, as well as main.c, which contains the code for the initial startup and
main program loop. More detailed descriptions of all functions, as well as their source code, is available
in Appendix B.
The following flowchart helps to illustrate the general flow of information in the program. It is by no
means the sequential order of actual execution. In fact, most of these processes are happening
simultaneously.
Flow Chart 1: Information flow chart of the microcontroller
Project Management and Future Work
During the transition from EE415 to EE416, team Flavius, unfortunately, lost a valuable team member.
With such news, the team immediate began to delegate new tasks for each of the remaining members.
Essentially, the remaining members picked up the lost work force. Currently, the team members are
working collaboratively on most tasks including simulating, modeling, and programming.
Individual and Team Tasks
Team member, Jayson Edmundson, is the driving force for the microcontroller programming. He has
been assigning specific tasks for the other team members. For example, he requested the team
determine the port addresses and algorithms for each switch involved in the inverting process, while he
programmed microcontroller to perform accordingly. Adam Peretti and Adam Yackley have been
focusing on PSPICE analysis and design. The simulation provides useful data for the setup and
programming of the microcontroller. Additionally, when the board is received from David Devries, the
simulation results will be used for future experimentation comparison and analysis.
Delays and Future Work
There have been some minor setbacks, during the spring semester of EE416. Specifically, the board has
been delayed by approximately two months. This was due to several component delays and
malfunctions. Fortunately, the group had planned for such delays and has been moving forward
regardless. The programming is almost complete; however, without the board to test the code it is hard
to test the actual functionality. Additionally, certain optional tasks such as adaptive gain, and advance
computer communication may be cancelled accordingly.
In the future, the team needs to test the board extensively for harmonics, power losses, and inverter
specifications. The board must be able to output a kilowatt of power for a sustainable amount of time
without failure. Equally important, the range of loads, power factor, and their efficiency must be
determined.
Other future work for Team Flavius includes testing of the final PCB layout for proof of concept, building
an enclosure for the inverter and prototype station for safety and exhibition, programming a GUI to use
during exhibition, and testing the total harmonic distortion of the entire system plus analog loads. By
April 22nd
2010, Team Flavius is confident the above work will be completed. See the Risk management
table below for the teams assessment of possible contingency plans.
RISK MANAGEMENT
RISK SEVERITY LIKELIHOOD ACTIONS TO MINIMIZE RISK
Change in customer
preferences
HIGH LOW - Work with the customer to refine
specifications.
- Estimate new time and cost penalties of
changes.
Delay in receiving PCB MEDIUM LOW - Schedule other tasks to be done in case
there is a wait.
- Compensate by having some empty space in
schedule.
Developing switch or
feedback control system is
taking longer than
anticipated
MEDIUM MEDIUM - Check the characteristic of the circuit
components and simulation.
- Compensate by having some empty space in
schedule.
Poor characteristic of switch
or feedback control
MEDIUM HIGH - Check the characteristic of the circuit and
simulate before implementation.
- Have multiple design options available and
tested for experimentation.
Distortions in output
waveform do not meet
specifications
LOW HIGH - Have multiple design options available and
tested for experimentation.
The largest risk in project development/completion is the possibility that David DeVries might change his
design preferences. While this does not seem likely this far in the design after implementation of the
PCB, changes to specifications will be reflected in the design and should be anticipated. The team must
coordinate the new time and cost penalties with any design changes that must be made.
Delays in receiving the PCB, delays from switch and feedback control design taking longer than expected
or other possible contingencies, can be accounted for with a reallocation of extra time defaulted as
extra possible added features. Editing and creating simulations for alternate switching and feedback
control systems is an option for a suitable alternate time investment.
The proactive approach to good characteristics for switch and feedback control is to model and simulate
the design before implementation. Having alternative design approaches for testing and
experimentation can be beneficial when there are problems with a particular control system. This is also
true for distortions in the waveform output that do not meet specifications. Beyond modifying the
particular design for better efficiency, other design approaches might be used.
Since the voltage and current levels used in the inverter can be fatal, the enclosure casing should be
constructed to be tamper proof. Additionally, the setup of the product should be straightforward with
color coded leads, clearly labeled inputs and outputs, and a supplemental instruction manual. To ensure
the quality and safety of each product, they should be thoroughly tested before sold.
The uses of the DC-AC inverter are open-ended and completely up to the user, however there are
expected common applications; including a portable inverter, photo voltaic (PV) generation, and
uninterruptable power supply (UPS). The UPS is used in important situations that require power at all
times, even if power goes out. Meaning, the inverter must have a quick start up time and a high
reliability factor. If the inverter is to be portable, as expected, it must be light enough to carry and safe
to handle. When the inverter is used to invert the PV power, it will most likely be attached to the power
grid and supply a high fidelity wave.
All of the above scenarios will add time to the project, and will be evaluated on as if time permits
basis. Since the delay of the board was predicted and planned for earlier, Team Flavius is still on
schedule for completing the design project on time.
Impact Analysis
The low cost/high efficiency design and implementation of this true sine wave inverter is the motivation
behind its development. Its positive impacts are expected to make the proposed inverter desirable to
many stakeholders. It is possible this inverter will open up markets that earlier inverters were too
expensive to sustain. While this inverter design might seem a cure all for a variety of problems, its
feasibility could have many ethical impacts on the global, economic, environmental, and societal levels.
To fully understand the implications of our design, the use of the inverter with a portable fuel cell will be
explored.
Having the ability to power electronics over prolonged periods of time in remote areas is at the heart of
why portable fuel cells are slowly becoming a viable choice for recreation professionals and enthusiasts
alike. Portable fuel cells are found in a variety of products like security and surveillance cameras,
medical equipment, communication equipment, and recreational/emergency power generators. Each of
these devices at one time needed to be tethered to the power grid, limiting their usage and
effectiveness. The introduction of fuel cells has since made these devices better and more versatile by
offering the availability to mobilize such devices.
While these products have already benefitted by becoming mobile, products with motors and other
analog loads suffer in efficiency when coupled with inferior inverters such as modified sine wave-based
inverters. That said consider the following scenario: If a person would like to power an air conditioned
tent in the remote jungle of the Congo, in order to facilitate medical treatment to a group of people,
they would need a true sine wave inverter coupled with a fuel cell to efficiently power the air
conditioner to cool the tent. Without a true sine wave inverter, like the one team Flavius is proposing,
the fuel cell and air conditioner would not be used as efficiently as possible, thus shortening the amount
of time the air conditioner is able to run.
While the above scenario exemplifies global/societal impacts that this inverter can have, the
economic/environmental impacts are a just as important. Portable fuel cells are not cheap to produce or
to maintain, but with the byproduct of the battery being pure water, the alternative is far from
environmental when compared. Consider the following scenario: The US Army Corps of Engineers need
to core drill holes in the side of a rock face in order to detonate it with explosives.
Two methods are compared below to explore the impacts both economically and environmentally when
a portable fuel cell coupled with a true sine wave inverter is used, instead of the alternative.
The current method is to use an excavator like device that has a pneumatic arm used to bore a hole into
the rock. This machine would take 1 day to complete the job. In order to get the machine to the rock
face, 2 acres of trees need to be removed. An additional two weeks are needed for a team of two and
this requires the use of three extra machines (2 chainsaws, 1 tractor). Consider the alternative: Two men
could make their way through the trees with a man-operated drilling device that is easily movable and
requires a portable fuel cell with a true sine wave inverter. The two men could easily make their way
through the trees without any environmental impact, require 1 week to drill the holes, and still not use a
drop of fuel in the process.
By comparing the two methods, it is easy to see the portable drill method is cheaper on labor, quicker
time wise, and more environmentally responsible.
Conclusion
Overall this design project has seen significant progress towards completion and despite the delays and
setbacks, the prototype is still meeting the schedule requirements. In the very near future, Team Flavius
will be receiving the prototype board and the teams programming can be implemented. For this reason,
communication with David Devries will become much more frequent and important as experimentation
and results are achieved.
The teams group dynamic has been successful and the required work been completed in a professional,
timely, and efficient manner. All team members have been satisfied with the individual work load;
however, due to the recent inrush of required analysis the team meetings have been very time
consuming.
The completed project will result in a high efficiency, low cost DC/AC inverter with low time harmonic
distortion. During the poster session, the product should be available for demonstration and each team
member will be required to have expertise in every component of the inverter design.
References
[1] Timothy L. Skvarenina, The Power Electronics Handbook, Florida: CRC Press LLC, 2002.
[2] Akira Nakamori, High Speed Large Capacity Inverter for Power System Apparatus, Hino-city,
Tokyo: Fuji Electric Corporate Research and Development, Ltd, 1996
[3] Dorin O. Neacsu, Power-Switching Converters: Medium and High Power, Florida:
CRC Press LLC, 2006.
[4] "H-bridge." H Bridge. Web. 02 Nov. 2009. .
[*5] Salvatore Favuzza, Filippo Spertino , Giorgio Graditi, Gianpaolo Wale, member IEEE Comparison
of Power Quality Impact of Different Photovoltaic Inverters: the viewpoint of the grid, 2004 IEEE
International Conference on Industrial Technology (KIT)
[6] Cesare Bocchiola, Design of the Inverter Output Filter for Motor Drives with IRAMS Power
Modules, International Rectifier
[*7] Li Jian, Kang Yong, and Chen Jian, Fuzzy-Tuning PID Control of an Inverter with Rectifier-Type
Nonlinear Loads, Department of Electrical Engineering, Huazhong University of Science and Technology,
Wuhan, 430074, P. R. Chin
[*8] Li Hozgbo, Yu Jun, Xiong Jian, Shan Hongtao, Single-phase Inverter Voltage Control and Parallel
Circulation Current Suppression, Huazhong University of Science and Technology Institute of Electrical
and Electronic Engineering,Wuhan,430074,China
[*9] A. Tomasi, M. Concina, M. Grossoni, P. Caracino, J.Blanchard, Field Applications: Fuel Cells as
Backup Power for Italian Telecommunication Sites, IEEE 2006
Appendices
Appendix A Data Sheets ( double-click on the grey boxes)
Appendix B - Microcontroller Code
Assembly Code
;*************************************************************************
*****
;* This file contains PID functions with interrupt.
;*************************************************************************
*****
;*File name: PIDInt.asm
;*Dependencies: p18f452.inc (change to specific application requirements)
;*Processors: PIC18
;*Assembler: MPASMWIN 02.70.02 or higher
;*Linker: MPLINK 2.33.00 or Higher
;*Company: Microchip Technology, Inc.
;*
;* Software License Agreement
;*
;* The software supplied herewith by Microchip Technology Incorporated
;* (the "Company") for its PICmicro Microcontroller is intended and
;* supplied to you, the Company's customer, for use solely and
IR2117 IRFB4321
;* exclusively on Microchip PICmicro Microcontroller products. The
;* software is owned by the Company and/or its supplier, and is
;* protected under applicable copyright laws. All rights are reserved.
;* Any use in violation of the foregoing restrictions may subject the
;* user to criminal sanctions under applicable laws, as well as to
;* civil liability for the breach of the terms and conditions of this
;* license.
;*
;* THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
;* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
;* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
;* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
;* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
;* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
;*
;*
;*
;* Author Date Comment
;*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;* C.Valenti June 29, 2004 Initial Release (V1.0)
;*
;* Revisions:
;* 7/8/04 -Removed unused variables a_Err1Lim & a_Err2Lim
;* Modified code after the "restore_limit" label to reflect
using
;* aErr1Lim & aErr2Lim defined constants.
;* -Changed constant: #define derivCount to #define
derivCountVal
;* -pidStat1 bit comments were corrected to the correct bit #
;* -In the PidInterrupt routine, the " movlw derivCountVal "
was added
;* for loading the derivCount variable.
;*
;* 10/20/04 -Added bra statment to the Derivative routine
;* Amended code for checking the a_Error2 limits.
;*
;*********************************************************************
;PID Notes:
; PROPORTIONAL = (system error * Pgain )
; System error = error0:error1
;
; INTEGRAL = (ACUMULATED ERROR * Igain)
; Accumulated error (a_error) = error0:error1 + a_Error0:a_Error2
;
; DERIVATIVE = ((CURRENT ERROR - PREVIOUS ERROR) * Dgain)
; delta error(d_error) = errro0:error1 - p_error0:p_error1
;
; Integral & Derivative control will be based off sample periods of "x"
time.
; The above sample period should be based off the PLANT response
; to control inputs.
; SLOW Plant response = LONGER sample periods
; FAST Plant response = SHORTER sample periods
;
; If the error is equal to zero then no PID calculations are completed.
;
; The PID routine is passed the 16- bit errror data by the main
application
; code through the error0:error1 variables.
; The sign of this error is passed through the error sign bit:
; pidStat1,err_sign
; The PID outputs a 24-bit vaule in pidOut0:pidOut2 and the sign of this
; result is the pid_sign bit in the pidStat1 register.
;-----------------------------------------------------------------------
list p=18F4585
#include
;***** SYSTEM CONSTANTS
#define aErr1Lim 0x0F ;accumulative error limits (4000d)
#define aErr2Lim 0xA0
#define timer1Hi 0x3E ;Timer1 timeout defined by timer1Lo &
timer1Hi
#define timer1Lo 0x0D ;this timout is based on Fosc/4
#define derivCountVal .10 ;determies how often the derivative
term will be executed.
;#define pid_100 ;comment out if not using a 0 - 100%
scale
EXTERN FXM1616U,FXD2416U,_24_BitAdd,_24_bit_sub
EXTERN AARGB0,AARGB1,AARGB2,AARGB3
EXTERN BARGB0,BARGB1,BARGB2,BARGB3
GLOBAL error0, error1, pidStat1
;***** VARIABLE DEFINITIONS
pid_data UDATA
#ifdef pid_100
percent_err RES 1 ;8-bit error input, 0 - 100% (0 -
100d)
percent_out RES 1 ;8-bit output, 0 - 100% (0 - 100d)
#endif
derivCount RES 1 ;This value determins how many times the
Derivative term is
;calculated based on each Integral
term.
pidOut0 RES 1 ;24-bit Final Result of PID for the
"Plant"
pidOut1 RES 1
pidOut2 RES 1
error0 RES 1 ;16-bit error, passed to the PID
error1 RES 1
a_Error0 RES 1 ;24-bit accumulated error, used for
Integral term
a_Error1 RES 1
a_Error2 RES 1
p_Error0 RES 1 ;16-bit previous error, used for
Derivative term
p_Error1 RES 1
d_Error0 RES 1 ;16-bit delta error (error - previous
error)
d_Error1 RES 1
prop0 RES 1 ;24-bit proportional value
prop1 RES 1
prop2 RES 1
integ0 RES 1 ;24-bit Integral value
integ1 RES 1
integ2 RES 1
deriv0 RES 1 ;24-bit Derivative value
deriv1 RES 1
deriv2 RES 1
kp RES 1 ;8-bit proportional Gain
ki RES 1 ;8-bit integral Gain
kd RES 1 ;8-bit derivative Gain
pidStat1 RES 1 ;PID bit-status register
pidStat2 RES 1 ;PID bit-status register2
tempReg RES 1 ;temporary register
; pidStat1 register
;
_______________________________________________________________________
________________________
; | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 |
bit 1 | bit 0 |
; | pid_sign | d_err_sign | mag | p_err_sign | a_err_sign | err_sign |
a_err_z | err_z |
;
|__________|____________|________|____________|____________|__________|
____________|__________|
err_z equ 0 ;error zero flag, Zero = set
a_err_z equ 1 ;a_error zero flag, Zero = set
err_sign equ 2 ;error sign flag, Pos = set/ Neg = clear
a_err_sign equ 3 ;a_error sign flag, Pos = set/ Neg
= clear
p_err_sign equ 4 ;a_error sign flag, Pos = set/ Neg
= clear
mag equ 5 ;set = AARGB magnitude, clear
= BARGB magnitude
d_err_sign equ 6 ;d_error sign flag, Pos = set/ Neg
= clear
pid_sign equ 7 ;PID result sign flag, Pos = set/ Neg =
clear
; ________________________________ pidStat2
register______________________________________
; | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit
1 | bit 0 |
; | | | | | | |
| d_err_z |
;
|_______|_________|__________|____________|____________|_______|_______
_____|__________|
d_err_z equ 0 ;d_error zero flag, Zero = set
_PIDCODE CODE ;start PID code here
;***********************************************************************;
; Function: PidInit
;
; ;
; PreCondition: Called by the application code for PID initalization ;
; ;
; Overview: PID variables are cleared, PID gains are given values,
;
; flags are initialized.
;
;
;
; Input:
;
; ;
; Output: none
;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 1 levels deep ;
; ;
;***********************************************************************;
PidInitalize:
GLOBAL PidInitalize
clrf error0
clrf error1
clrf a_Error0
clrf a_Error1
clrf a_Error2
clrf p_Error0
clrf p_Error1
clrf d_Error0
clrf d_Error1
clrf prop0
clrf prop1
clrf prop2
clrf integ0
clrf integ1
clrf integ2
clrf deriv0
clrf deriv1
clrf deriv2
clrf kp
clrf ki
clrf kd
clrf pidOut0
clrf pidOut1
clrf pidOut2
clrf AARGB0
clrf AARGB1
clrf AARGB2
clrf BARGB0
clrf BARGB1
clrf BARGB2
movlw .160 ;10 x 16, Kp, Ki & Kd are 8-bit
vlaues that cannot exceed 255
movwf kp ;Enter the PID gains scaled
by a factor of 16, max = 255
movlw .160 ;10 x 16
movwf ki
movlw .160 ;10 x 16
movwf kd
movlw .10
movwf derivCount ;derivative action = TMR1H:TMR1L *
derivCount
bcf pidStat1,err_z ;start w/error not equal to
zero
bsf pidStat1,a_err_z ;start w/a_error equal to zero
bsf pidStat2,d_err_z ;start w/d_error equal to zero
bsf pidStat1,p_err_sign ;start w/ previous error =
positive
bsf pidStat1,a_err_sign ;start w/ accumulated error =
positive
bcf PIR1,TMR1IF ;clear T1 flag
bsf PIE1,TMR1IE ;enable T1 interrupt
movlw b'00000001' ;configure T1 for Timer operation
from Fosc/4
movwf T1CON
movlw timer1Hi ;load T1 registers with 5ms count
movwf TMR1H
movlw timer1Lo
movwf TMR1L
return ;return back to the
main application code
;***********************************************************************;
; Function: PidMain
;
; ;
; PreCondition: error0:erro1 are loaded with the latest system error ;
; ;
; Overview: This is the routine that the application code will call ;
; to get a PID correction value. First, the error is checked
;
; to determine if it is zero, if this is true, then the PID
;
; code is complete.
;
;
;
; Input: error0:error1, sign of the error: pidStat1,err_sign ;
; ;
; Output: prop0:prop2 ;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 5 levels deep ;
; ;
;***********************************************************************;
PidMain:
GLOBAL PidMain
bcf PIE1,TMR1IE ;disable T1 interrupt
#ifdef pid_100 ;if using % scale then scale
up PLANT error
movlw .40 ; 0 - 100% == 0 - 4000d
mulwf percent_err,1 ;40 * percent_err --> PRODH:PRODL
movff PRODH,error0
movff PRODL,error1 ;percentage has been scaled and available
in error0:error1
#endif
movlw 0
cpfseq error0 ;Is error0 = 00 ?
bra call_pid_terms ;NO, done checking
cpfseq error1 ;YES, Is error1 = 00 ?
bra call_pid_terms ;NO, start proportional term
bsf pidStat1,err_z ;YES, set error zero flag
bsf PIE1,TMR1IE ;enable T1 interrupt
return ;return back to the main
application code
call_pid_terms
call Proportional ;NO, start with proportional term
call Integral ;get Integral term
call Derivative ;get Derivative term
call GetPidResult ;get the final PID result that will go to
the system
bsf PIE1,TMR1IE ;enable T1 interrupt
return ;return back to the main
application code
;***********************************************************************;
; Function: Proportional ;
; ;
; PreCondition: error0:erro1 are loaded with the latest system error ;
; ;
; Overview: This routine will multiply the system's 16-bit error by the ;
; proportional gain(Kp) --> error0:error1 * Kp
;
;
;
; Input: error0:error1, sign of the error: pidStat1,err_sign ;
; ;
; Output: prop0:prop2 ;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 2 levels deep ;
; ;
;***********************************************************************;
Proportional:
clrf BARGB0
movff kp,BARGB1
movff error0,AARGB0
movff error1,AARGB1
call FXM1616U ;proportional gain * error
movff AARGB1,prop0 ;AARGB2 --> prop0
movff AARGB2,prop1 ;AARGB3 --> prop1
movff AARGB3,prop2 ;AARGB4 --> prop2
return ;return to mainline code
;***********************************************************************;
; Function: Integral ;
; ;
; PreCondition: error0:erro1 are loaded with the latest system error
;
; ;
; Overview: This routine will multiply the system's 16-bit accumulated
;
; error by the integral gain(Ki)--> a_Error0:a_Error1 * Ki ;
;
;
; Input: a_Error0:a_Error1, sign of a_Error: pidStat1,a_err_sign ;
; ;
; Output: integ0:integ2 ;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 2 levels deep ;
; ;
;***********************************************************************;
Integral:
btfsc pidStat1,a_err_z ;Is a_error = 0
bra integral_zero ;Yes
clrf BARGB0 ;No
movff ki,BARGB1 ;move the integral gain into BARGB1
movff a_Error1,AARGB0
movff a_Error2,AARGB1
call FXM1616U ;Integral gain * accumulated error
movff AARGB1,integ0 ;AARGB1 --> integ0
movff AARGB2,integ1 ;AARGB2 --> integ1
movff AARGB3,integ2 ;AARGB3 --> integ2
return ;return
integral_zero
clrf integ0 ;a_error = 0, clear Integral term
clrf integ1
clrf integ2
return
;***********************************************************************;
; Function: Derivative
;
; ;
; PreCondition: error0:erro1 are loaded with the latest system error ;
; ;
; Overview: This routine will multiply the system's 16-bit delta
;
; error by the derivative gain(Kd) --> d_Error0:d_Error1 * Kd
;
; d_Error0:d_Error1 = error0:error1 - p_Error0:p_Error1
;
;
;
; Input: d_Error0:d_Error1, pidStat2,d_err_z
;
; ;
; Output: deriv0:deriv2 ;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 2 levels deep ;
; ;
;***********************************************************************;
Derivative:
btfsc pidStat2,d_err_z ;Is d_error = 0?
bra derivative_zero ;YES
movff d_Error1,BARGB1 ;result ---> BARGB1
movff d_Error0,BARGB0 ;result ---> BARGB0
movff kd,AARGB1
clrf AARGB0
call FXM1616U ;Derivative gain * (error_l - prv_error1)
movff AARGB1,deriv0 ;AARGB1 --> deriv0
movff AARGB2,deriv1 ;AARGB2 --> deriv1
movff AARGB3,deriv2 ;AARGB3 --> deriv2
return ;return
derivative_zero
clrf deriv0 ;d_error = 0, clear Derivative term
clrf deriv1
clrf deriv2
return
;***********************************************************************;
; Function: GetPidResult
;
; ;
; PreCondition: Proportional, Integral & Derivative terms have been
;
; calculated. The Timer1 interrupt is disabled within
;
; this routine to avoid corruption of the PID result.
;
; ;
; Overview: This routine will add the PID terms and then scale down ;
; the result by 16. This will be the final result that is
;
; calcualted by the PID code.
;
;
;
; Input: prop0:prop2, integ0:integ2, deriv0:deriv2
;
; ;
; Output: pidOut0:pidOut2 ;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 4 levels deep max.
;
; ;
;***********************************************************************;
GetPidResult:
movff prop0,AARGB0 ;load Prop term & Integral term
movff prop1,AARGB1
movff prop2,AARGB2
movff integ0,BARGB0
movff integ1,BARGB1
movff integ2,BARGB2
call SpecSign ;YES, call routine for add/sub sign
numbers
btfss pidStat1,mag ;which is greater in magnitude ?
bra integ_mag ;BARGB is greater in
magnitude
bra prop_mag ;AARGB is greater in
magnitude
integ_mag ;integ > prop
bcf pidStat1,pid_sign ;PID result is negative
btfsc pidStat1,a_err_sign
bsf pidStat1,pid_sign ;PID result is positive
bra add_derivative ;(Prop + Integ) + derivative
prop_mag ;integ < prop
bcf pidStat1,pid_sign ;PID result is negative
btfsc pidStat1,err_sign
bsf pidStat1,pid_sign ;PID result is positive
add_derivative
movff deriv0,BARGB0 ;YES, AARGB0:AARGB2 has result of
Prop + Integ
movff deriv1,BARGB1 ;load derivative term
movff deriv2,BARGB2
movff pidStat1,tempReg ;pidStat1 ---> tempReg
movlw b'11000000' ;prepare for sign check of bits 7 &
6
andwf tempReg,f
movf tempReg,w ;check error sign & a_error sign
bits
sublw 0x00
btfsc STATUS,Z
bra add_neg_d ;bits 7 & 6 (00) are
NEGATIVE, add them
bra other_combo_d ;bits 7 & 6 not equal to 00
add_neg_d
call _24_BitAdd ;add negative sign values
bra scale_down ;scale result
other_combo_d
movf tempReg,w
sublw 0xC0
btfsc STATUS,Z
bra add_pos_d ;bits 7 & 6 (11) are
POSITIVE, add them
bra find_mag_sub_d ;bits 7 & 6 (xx) are
different signs , subtract them
add_pos_d
call _24_BitAdd ;add positive sign values
bra scale_down ;scale result
find_mag_sub_d
call MagAndSub ;subtract unlike sign numbers
btfss pidStat1,mag ;which is greater in magnitude ?
bra deriv_mag ;BARGB is greater in
magnitude
bra scale_down ;derivative term < part pid
term, leave pid_sign as is
deriv_mag ;derivative term > part
pid term
bcf pidStat1,pid_sign ;PID result is negative
btfsc pidStat1,d_err_sign
bsf pidStat1,pid_sign ;PID result is positive
scale_down
clrf BARGB0 ;(Prop + Integ + Deriv) / 16
= FINAL PID RESULT to plant
movlw 0x10
movwf BARGB1
call FXD2416U
movff AARGB2,pidOut2 ;final result ---> pidOut2
movff AARGB1,pidOut1 ;final result ---> pidOut1
movff AARGB0,pidOut0 ;final result ---> pidOut0
#ifdef pid_100 ;Final result needs to
be scaled down to 0 - 100%
movlw 0x06 ;% ratio for propotional & integral
& derivative
movwf BARGB0
movlw 0x40
movwf BARGB1
call FXD2416U ;pidOut0:pidOut2 / % ratio = 0 -
100% value
movf AARGB2,W ;AARGB2 --> percent_out
movwf percent_out ;error has been scaled down and is
now available in a 0 -100% range
#endif
return ;return to mainline
code
;***********************************************************************;
; Function: GetA_Error
;
; ;
; PreCondition: Proportional term has been calculated
;
; ;
; Overview: This routine will add the current error with all of the
;
; previous errors. The sign of the accumulated error will
;
; also be determined. After the accumulated error is
;
; calculated then it is checked if it = 00 or as exceeded
;
; the defined limits.
;
;
;
; Input: a_Error0:a_Error1, error0:error1
;
; ;
; Output: a_Error0:a_Error1 (updated value) ;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 4 levels deep max.
;
; ;
;***********************************************************************;
GetA_Error:
movff a_Error0,BARGB0 ;load error & a_error
movff a_Error1,BARGB1
movff a_Error2,BARGB2
clrf AARGB0
movff error0,AARGB1
movff error1,AARGB2
call SpecSign ;call routine for add/sub sign
numbers
btfss pidStat1,mag ;which is greater in magnitude ?
bra a_err_zero ;bargb, keep sign as is or
both are same sign
bcf pidStat1,a_err_sign ;aargb, make sign same as
error, a_error is negative
btfsc pidStat1,err_sign
bsf pidStat1,a_err_sign ;a_error is positive
a_err_zero
bcf pidStat1,a_err_z ;clear a_error zero flag
movlw 0
cpfseq AARGB0 ;is byte 0 = 00
bra chk_a_err_limit ;NO, done checking
cpfseq AARGB1 ;is byte 1 = 00
bra chk_a_err_limit ;NO, done checking
cpfseq AARGB2 ;is byte 2 = 00
bra chk_a_err_limit ;NO, done checking
bsf pidStat1,a_err_z ;YES, set zero flag
movff AARGB0,a_Error0 ;store the a_error
movff AARGB1,a_Error1
movff AARGB2,a_Error2
return ;a_error = 00, return
chk_a_err_limit
movff AARGB0,a_Error0 ;store the a_error
movff AARGB1,a_Error1
movff AARGB2,a_Error2
movlw 0 ;a_error reached limits?
cpfseq a_Error0 ;Is a_Error0 > 0 ??, if yes
limit has been exceeded
bra restore_limit ;YES, restore limit value
cpfseq a_Error1 ;Is a_Error1 = 0 ??, if yes,
limit not exceeded
bra chk_a_Error1 ;NO
return ;YES
chk_a_Error1
movlw aErr1Lim
cpfsgt a_Error1 ;Is a_Error1 > aErr1Lim??
bra equal_value ;NO, check for a_Error1 =
aErr1Lim ?
bra restore_limit ;YES, restore limit value
equal_value
cpfseq a_Error1 ;a_Error1 = aErr1Lim?
return ;no, done checking
a_error
chk_a_Error2
movlw aErr2Lim ;Yes, a_Error1 = aErr1Lim
cpfsgt a_Error2 ;Is a_Error2 > aErr2Lim ??
return ;NO, return to mainline
code
restore_limit
clrf a_Error0 ;YES, a_error limit has been
exceeded
movlw aErr1Lim
movwf a_Error1
movlw aErr2Lim
movwf a_Error2
return ;return to mainline
code
;***********************************************************************;
; Function: GetDeltaError ;
; ;
; PreCondition: The derivative routine has been called to calculate the
;
; derivative term.
;
; ;
; Overview: This routine subtracts the previous error from the current
;
; error.
;
;
;
; Input: P_Error0:p_Error1, error0:error1
;
; ;
; Output: d_Error0:d_Error1, d_Error sign
;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 3 levels deep max.
;
; ;
;***********************************************************************;
GetDeltaError:
clrf AARGB0 ;load error and p_error
movff error0,AARGB1
movff error1,AARGB2
clrf BARGB0
movff p_Error0,BARGB1
movff p_Error1,BARGB2
movf pidStat1,w ;pidStat1 ---> tempReg
movwf tempReg ;prepare for sign check of
bits 4 & 2
movlw b'00010100'
andwf tempReg,f
movf tempReg,w ;check error sign & a_error sign
bits
sublw 0x00
btfsc STATUS,Z
bra p_err_neg ;bits 4 & 2 (00) are
NEGATIVE,
bra other_combo2 ;bits 4 & 2 not equal to 00
p_err_neg
call MagAndSub
bcf pidStat1,d_err_sign ;d_error is negative
btfsc pidStat1,p_err_sign ;make d_error sign same as p_error
sign
bsf pidStat1,d_err_sign ;d_error is positive
bra d_error_zero_chk ;check if d_error = 0
other_combo2
movf tempReg,w
sublw 0x14
btfsc STATUS,Z
bra p_err_pos ;bits 4 & 2 (11) are POSITIVE
bra p_err_add ;bits 4 & 2 (xx) are different
signs
p_err_pos
call MagAndSub
bcf pidStat1,d_err_sign ;d_error is negative
btfsc pidStat1,p_err_sign ;make d_error sign same as p_error
sign
bsf pidStat1,d_err_sign ;d_error is positive
bra d_error_zero_chk ;check if d_error = 0
p_err_add
call _24_BitAdd ;errors are different sign
bcf pidStat1,d_err_sign ;d_error is negative
btfsc pidStat1,err_sign ;make d_error sign same as error sign
bsf pidStat1,d_err_sign ;d_error is positive
d_error_zero_chk
movff AARGB1,d_Error0
movff AARGB2,d_Error1
movff error0,p_Error0 ;load current error into previous
for next deriavtive term
movff error1,p_Error1 ;load current error into previous
for next deriavtive term
bcf pidStat1,p_err_sign ;make p_error negative
btfsc pidStat1,err_sign ;make p_error the same sign as error
bsf pidStat1,p_err_sign ;make p_error positive
bcf pidStat2,d_err_z ;clear delta error zero bit
movlw 0
cpfseq d_Error0 ;is d_error0 = 00
return ;NO, done checking
cpfseq d_Error1 ;YES, is d_error1 = 00
return ;NO, done checking
bsf pidStat2,d_err_z ;set delta error zero bit
return ;YES, return to ISR
;***********************************************************************;
; Function: SpecSign ;
; ;
; PreCondition: The sign bits in pidStat1 have been set or cleared
;
; depending on the variables they represent.
;
; ;
; Overview: This routine takes the numbers loaded into the math
;
; variables (AARGB, BARGB) and determines whether they
;
; need to be added or subtracted based on their sign
;
; which is located in the pidStat1 register.
;
;
;
; Input: pidStat1
;
; ;
; Output: add/sub results in math variables (AARGB, BARGB)
;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 2 levels deep max.
;
; ;
;***********************************************************************;
SpecSign
movff pidStat1,tempReg ;pidStat1 ---> tempReg
movlw b'00001100' ;prepare for sign check of bits 3 &
2
andwf tempReg,f
movf tempReg,w ;check error sign & a_error sign
bits
sublw 0x00
btfsc STATUS,Z
bra add_neg ;bits 3 & 2 are
NEGATIVE (00), add them
bra other_combo ;bits 3 & 2 not equal to 00
add_neg
call _24_BitAdd ;add negative sign values
return
other_combo
movf tempReg,w
sublw 0x0C
btfsc STATUS,Z
bra add_pos ;bits 3 & 2 are
POSITIVE (11), add them
bra find_mag_sub ;bits 3 & 2 are different
signs (xx), subtract them
add_pos
call _24_BitAdd ;add positive sign values
return
find_mag_sub
call MagAndSub ;subtract unlike sign numbers
return
;***********************************************************************;
; Function: MagAndSub
;
; ;
; PreCondition: This routine has been called by SpecSign because the ;
; numbers being worked on are different in sign.
;
; ;
; Overview: This routine will detemine which math variable
;
; (AARGB or BARGB) is greater in number manitude and then
;
; subtract them, the sign of the result will be determined by
;
; the values in the math variables and their signs.
;
;
;
; Input: pidStat1
;
; ;
; Output: add/sub results in math variables (AARGB, BARGB)
;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 2 levels deep max.
;
; ;
;***********************************************************************;
MagAndSub:
movf BARGB0,w
subwf AARGB0,w ;AARGB0 - BARGB0 --> W
btfsc STATUS,Z ;= zero ?
bra check_1 ;YES
btfsc STATUS,C ;borrow ?
bra aargb_big ;AARGB0 > BARGB0, no borrow
bra bargb_big ;BARGB0 > AARGB0, borrow
check_1
movf BARGB1,w
subwf AARGB1,w ;AARGB1 - BARGB1 --> W
btfsc STATUS,Z ;= zero ?
bra check_2 ;YES
btfsc STATUS,C ;borrow ?
bra aargb_big ;AARGB1 > BARGB1, no borrow
bra bargb_big ;BARGB1 > AARGB1, borrow
check_2
movf BARGB2,w ;AARGB2 - BARGB2 --> W
subwf AARGB2,w
btfsc STATUS,C ;borrow ?
bra aargb_big ;AARGB2 > BARGB2, no borrow
bra bargb_big ;BARGB2 > AARGB2, borrow
aargb_big
call _24_bit_sub
bsf pidStat1,mag ;AARGB is greater in
magnitude
return
bargb_big
movff BARGB0,tempReg ;swap AARGB0 with BARGB0
movff AARGB0,BARGB0
movff tempReg,AARGB0
movff BARGB1,tempReg ;swap AARGB1 with BARGB1
movff AARGB1,BARGB1
movff tempReg,AARGB1
movff BARGB2,tempReg ;swap AARGB2 with BARGB2
movff AARGB2,BARGB2
movff tempReg,AARGB2
call _24_bit_sub ;BARGB > AARGB
bcf pidStat1,mag ;BARGB is greater in
magnitude
return
;***********************************************************************;
; Function: PidInterrupt
;
; ;
; PreCondition: This Routine will be called by the application's main
;
; code.
;
; ;
; Overview: When Timer 1 overlfows, an updated value for the Integral
;
; term will be calculated. An updated value for the
derivative;
; term will be calculated if derivCount = 0. This routine
;
; will check for error = 0, if this is true,then the routine
;
; will return back to the main line code.
;
;
;
; Input: pidStat1, a_error
;
; ;
; Output: Integral & Derivative terms, Timer1 registers reloaded ;
; ;
; Side Effects: W register is changed
;
; ;
; Stack requirement: 4 levels deep max.
;
; ;
;***********************************************************************;
PidInterrupt:
GLOBAL PidInterrupt
btfsc pidStat1,err_z ;Is error = 00 ?
return ;YES, done.
call GetA_Error ;get a_error, is a_error =
00? reached limits?
derivative_ready?
decfsz derivCount,f ;is it time to
calculate d_error ?
bra skip_deriv ;NO, finish ISR
call GetDeltaError ;error - p_error
movlw derivCountVal ;prepare for next delta error
movwf derivCount ;delta error = TMR1H:TMR1L *
derivCount
skip_deriv
movlw timer1Hi ;reload T1 registers with
constant time count (user defined)
movwf TMR1H
movlw timer1Lo
movwf TMR1L
return ;return back to
the application's ISR
END ;directive 'end of
program'
;********************************************************
;This file contains the following math routines:
;24-bit addittion
;24-bit subtraction
;16*16 Unsigned Multiply
;24/16 Unsigned Divide
list p=18F4585
#include
#define _Z STATUS,2
#define _C STATUS,0
GLOBAL AARGB0,AARGB1,AARGB2,AARGB3
GLOBAL BARGB0,BARGB1,BARGB2,BARGB3
GLOBAL ZARGB0,ZARGB1,ZARGB2
GLOBAL REMB0,REMB1
GLOBAL TEMP,TEMPB0,TEMPB1,TEMPB2,TEMPB3
GLOBAL LOOPCOUNT,AEXP,CARGB2
LSB equ 0
MSB equ 7
math_data UDATA
AARGB0 RES 1
AARGB1 RES 1
AARGB2 RES 1
AARGB3 RES 1
BARGB0 RES 1
BARGB1 RES 1
BARGB2 RES 1
BARGB3 RES 1
REMB0 RES 1
REMB1 RES 1
REMB2 RES 1
REMB3 RES 1
TEMP RES 1
TEMPB0 RES 1
TEMPB1 RES 1
TEMPB2 RES 1
TEMPB3 RES 1
ZARGB0 RES 1
ZARGB1 RES 1
ZARGB2 RES 1
CARGB2 RES 1
AEXP RES 1
LOOPCOUNT RES 1
math_code CODE
;---------------------------------------------------------------------
; 24-BIT ADDITION
_24_BitAdd
GLOBAL _24_BitAdd
movf BARGB2,w
addwf AARGB2,f
movf BARGB1,w
btfsc _C
incfsz BARGB1,w
addwf AARGB1,f
movf BARGB0,w
btfsc _C
incfsz BARGB0,w
addwf AARGB0,f
return
;---------------------------------------------------------------------
; 24-BIT SUBTRACTION
_24_bit_sub
GLOBAL _24_bit_sub
movf BARGB2,w
subwf AARGB2,f
movf BARGB1,w
btfss STATUS,C
incfsz BARGB1,w
subwf AARGB1,f
movf BARGB0,w
btfss STATUS,C
incfsz BARGB0,w
subwf AARGB0,f
return
;-------------------------------------------------------------------------
; 16x16 Bit Unsigned Fixed Point Multiply 16 x 16 -> 32
FXM1616U
GLOBAL FXM1616U
MOVFF AARGB1,TEMPB1
MOVF AARGB1,W
MULWF BARGB1
MOVFF PRODH,AARGB2
MOVFF PRODL,AARGB3
MOVF AARGB0,W
MULWF BARGB0
MOVFF PRODH,AARGB0
MOVFF PRODL,AARGB1
MULWF BARGB1
MOVF PRODL,W
ADDWF AARGB2,F
MOVF PRODH,W
ADDWFC AARGB1,F
CLRF WREG
ADDWFC AARGB0,F
MOVF TEMPB1,W
MULWF BARGB0
MOVF PRODL,W
ADDWF AARGB2,F
MOVF PRODH,W
ADDWFC AARGB1,F
CLRF WREG
ADDWFC AARGB0,F
RETLW 0x00
;--------------------------------------------------------------------
FXD2416U
GLOBAL FXD2416U
CLRF REMB0
CLRF REMB1
CLRF WREG
TSTFSZ BARGB0
GOTO D2416BGT1
MOVFF BARGB1,BARGB0
CALL FXD2408U
MOVFF REMB0,REMB1
CLRF REMB0
RETLW 0x00
D2416BGT1
CPFSEQ AARGB0
GOTO D2416AGTB
MOVFF AARGB1,AARGB0
MOVFF AARGB2,AARGB1
CALL FXD1616U
MOVFF AARGB1,AARGB2
MOVFF AARGB0,AARGB1
CLRF AARGB0
RETLW 0x00
D2416AGTB
MOVFF AARGB2,AARGB3
MOVFF AARGB1,AARGB2
MOVFF AARGB0,AARGB1
CLRF AARGB0
MOVFF AARGB0,TEMPB0
MOVFF AARGB1,TEMPB1
MOVFF AARGB2,TEMPB2
MOVFF AARGB3,TEMPB3
MOVLW 0x02 ; set loop count
MOVWF AEXP
MOVLW 0x01
MOVWF ZARGB0
BTFSC BARGB0,MSB
GOTO D2416UNRMOK
CALL DGETNRMD ; get normalization factor
MOVWF ZARGB0
MULWF BARGB1
MOVF BARGB0,W
MOVFF PRODL,BARGB1
MOVFF PRODH,BARGB0
MULWF ZARGB0
MOVF PRODL,W
ADDWF BARGB0,F
MOVF ZARGB0,W
MULWF AARGB3
MOVFF PRODL,TEMPB3
MOVFF PRODH,TEMPB2
MULWF AARGB1
MOVFF PRODL,TEMPB1
MOVFF PRODH,TEMPB0
MULWF AARGB2
MOVF PRODL,W
ADDWF TEMPB2,F
MOVF PRODH,W
ADDWF TEMPB1,F
D2416UNRMOK
BCF _C
CLRF TBLPTRH
RLCF BARGB0,W
RLCF TBLPTRH,F
ADDLW LOW (IBXTBL256+1) ; access reciprocal table
MOVWF TBLPTRL
MOVLW HIGH (IBXTBL256)
ADDWFC TBLPTRH,F
TBLRD *-
D2416ULOOP
MOVFF TEMPB0,AARGB0
MOVFF TEMPB1,AARGB1
CALL FXD1608U2 ; estimate quotient digit
BTFSS AARGB0,LSB
GOTO D2416UQTEST
SETF AARGB1
MOVFF TEMPB1,REMB0
MOVF BARGB0,W
ADDWF REMB0,F
BTFSC _C
GOTO D2416UQOK
D2416UQTEST
MOVF AARGB1,W ; test
MULWF BARGB1
MOVF PRODL,W
SUBWF TEMPB2,W
MOVF PRODH,W
SUBWFB REMB0,W
BTFSC _C
GOTO D2416UQOK
DECF AARGB1,F
MOVF BARGB0,W
ADDWF REMB0,F
BTFSC _C
GOTO D2416UQOK
MOVF AARGB1,W
MULWF BARGB1
MOVF PRODL,W
SUBWF TEMPB2,W
MOVF PRODH,W
SUBWFB REMB0,W
BTFSS _C