Sie sind auf Seite 1von 26

A 2kVA 12VDC to 120VAC inverter for power backup

This description of the inverter is preliminary and incomplete. Although working, the inverter still
has some way to go, esp. in the area of waveform synthesis. The Inverter has been tested and is
now in fact in standby use awaiting the next power failure (Of course since the inverter is ready
there won't be one ... :)

Abstract

The project presented is a 2kVA power inverter designed for backup during utility failures. The
inverter is affectionately called the 'I2K' for two reasons: It has a 2kVA output capacity and some
have suggested it might have been useful when Y2K hits (remember the Y2K paranoia/fiasco :)
Duh.

This inverter is of a traditional Ferro resonant design using large step-up transformers however
the pulse-width modulated signals which feed the transformers are generated in real-time by a
PIC RISC microcontroller. The microcontroller senses AC output voltage via an 8-bit ADC then
adjusts the pulse width accordingly using a closed control loop algorithm. The functions of
waveform timing, pulse width adjustment, and error control (shutdown when overload occurs)
are all done in software making upgrades easy to accomplish.

Many commercial inverters tested, including those used for PC UPS usages, will not provide the
enormous start-up currents required by many motors -- especially single phase motors under
load such as those found in the average natural gas furnace. This design provides those required
currents and, during one test, was observed to convert over 2kVA of power (The input current
exceeded 200A at 12VDC for several seconds until the motor started). Software control of the
inverter allows the inverter to be overloaded for a period of time before shutdown occurs giving
the motor time to start.

The inverter has been tested on 1/3hp single phase motor loads as well as with large resistive
loads of over 1500W and has performed well. Power factor correction was found to be required
with large motor loads and has been included in the design.
Efficiency of the inverter (Power Output / Power Input) driving a variety of both resistive and
inductive loads ranges between 71% and 82%. With an improved sinewave algorithm it is felt that
the inverter can approach the theoretical efficiency limit of 92%.

Disclaimer and Warning

The design presented employs high currents on the primary side and high voltages on the
secondary side. High currents of over 1000A were observed during circuit fault and despite the
fact this design has safety systems included to deal with such problems, high currents can cause
spectacular -- and dangerous -- effects such as component explosion. The output of the inverter
is 120VAC and must be treated with the same respect as any other AC source. In addition,
connection of the inverter to any device must be in accordance with local/national electrical rules
(in Canada, the Canadian Electrical Code) which specifies grounding, neutral bonding, and other
isuues. Do not attempt construction of a device such as this unless entirely familiar with high-
power electronics as well as proper safety procedures. The author specifically disclaims any and
all liabilities associated with the construction and use of such devices. The design is presented
here in the interests of providing information on operational principles only.

DANGEROUS HIGH VOLTAGES AND HIGH CURRENTS ARE PRESENT IN A PROJECT OF THIS
TYPE ... DO NOT ATTEMPT CONSTRUCTION UNLESS SKILLED IN SUCH AREAS

Power Drivers and Electronics

The design is of a standard ferroresonant type using large step-up transformers to convert 12 V
into 120 V. 12 VDC from large, high capacity batteries is chopped into alternating square waves
which are fed to opposite windings of a transformer. The batteries can be seen in the photo to the
left. I use a bank of twelve cells, each rated at 2V, 300Ah. The cells were surplus and were
originally used to backup a large telephone PBX system. The cells are wired as two banks of six
in series for a total capacity of 600Ah at 12VDC. For a 1500 VA output, current on the primary side
of the transformers would be about 150 amps so the transformers must be physically large (i.e. A
120VAC to 12VAC transformer with an output of 150 A is required) and the driving electronics
must be able to handle such large currents continually (most transistors cannot handle currents
over 20A so a bank of driver transistors is required).

The most difficult elements to obtain were the transformers. Mine were scavenged from two old
RCA power supplies used for TV broadcasting equipment. The original linear power supplies had
a rated output of 70A each. Each transformer has a 75A, 18V C.T. primary and hence a power
rating of about 1kVA. Two such transformers give the 2kVA power rating required. The
transformer's primary (low voltage) windings wer found to have a DC resistance of about 0.008
ohms. This implies that a very low impedance drive circuit is required. In the inverter, the
transformers are used as step-up transformers in push-pull configuration with the centre-tap
connected to the +12V DC terminal and each of the outer terminals grounded alternately using
large power MOSFETs.

The power drivers which switch battery current to the transformers consist of two banks of six
IRL2203 high-current FETs, with each bank driving both transformers in parallel. These devices,
manufactured by International Rectifier, have an on resistance of only milliohms each so that a
bank of six in parallel has a low enough source impedance to drive the transformers without
huge losses. It would be virtually impossible to use bipolar transistors for this application
without huge losses in the drivers. Data sheets for the IRL2203 may be found at IR's web site.
This device is clearly designed for such high-power uses. It features a low on resistance as well
as a quick saturation point (5VDC on the gate will drive the device to saturation). The only
problem with this device is the low voltage rating of 30V. To protect these devices, large zener
diodes are required across the Drain-to-Source connections. 24V Zeners were chosen to give a
good margin of safety in operation.

The above schematic shows one half of the main power drivers. From the far left, the waveform
from the drivers (next schematic) is fed to the banks of FET drivers via series gate resistors
which help share the load between the parallel FETs. The output of the power transformer, at
right, is fed to the power-factor control and output sensing circuitry. The centre-tap of the
transformer is connected to the battery +12V terminal via two large (70A) relays and a 150A series
fuse for protection.

There are 24 zener diodes included on each driver bank as back-emf protection to prevent the
FETS from ever having a reverse voltage of over 24V across them. This quantity of diodes was
found necessary during prototyping to absorb the huge emf 'spikes' from the transformer when
driving inductive loads such as motors. In the end though, with power factor correction applied
(in the form of a capacitor across the AC line) this quantity of diodes was found to be quite
excessive and their number could probably be cut in half or in third! (It was useful having this
quantity of zeners available during prototyping though and they are kept in the system to protect
the FETs during further development).

Note the 0.0033 ohm 75 Watt resistor used as a shunt to sense total current through the inverter.
This resistor is actually composed of fifteen 0.05 ohm 5 Watt ceramic resistors in parallel. These
resistors are forced-air fan cooled as they are
Opraed at rated power when the inverter is at the 1500 VA level..

The drivers above take the TTL-level signals generated by the microcontroller and provide a low-
impedance source to drive the FETs. The output swing is 0 to +12 volts which ensures complete
saturation of the FETs (hence low power dissipation). Although the data sheet for the FETs states
that +5V is enough to saturate the devices it was felt that transistor drivers would perform better
since a loaded MCU output pin could output only 3 or 4 V.

Included on this driver board is an overcurrent limiter. When the current through the 0.0033 ohm
shunt resistance reached some threshold value (usually about 200A), the voltage on pin 5 of the
comparator will exceed the reference voltage set by the pot. When this occurs two TIP120
transistors will clamp the FET inputs to ground and will hence instantaneously halt current flow.
This limiter was necessary during testing to avoid catastrophic failures when, say, a software bug
led to both sets of FET drivers being switched-on simultaneously. During such a fault condition
the system can easily consume over 1000A from the battery!! (_ enough to cause a fire _) as it did
on one prototype inverter tested.

It was felt that a pure-hardware current limiter was the safest way to prevent huge overcurrents
during testing. The limiter remains installed despite the fact that with debugged software it
should never be required (and in fact has not been observed to be switched-into the system since
prototyping). It must be realized that Fuses such as the 150A main fuse are not fast enough to
protect the FET drivers from overcurrent. Besides, 150A fuses cost over $40.00 each!.

The above diagram shows the placement of hardware in the 19 inch rack-mount chassis. The
large transformers weigh about 30 lbs. each and are mounted to the right side of the chassis.
Behind the transformers are two 70A Potter-Brumfield relays. You will note that the high currents
are carried by multiple pieces of 10 gauge wire.

The FET drivers along with associated zeners and the 15 shunt resistors are mounted on a PCB
atop a heatsink in the center of the unit. A fan immediately behind the driver assembly cools the
components on top as well as the heatsink which the FETs are mounted on top of. All control
electronics such as the MCU board (containing the MCU, ADC, and 7805 regulator), the driver
board (containing the TIP120 transistors and the LM339), and the output voltage sensing
transformer are mounted on the left side of the chassis.
Control Circuitry

AC Output voltage from the main inverter transformers is sensed using a small 9VAC transformer
across the output. This attains isolation of the AC output side from the DC-side of the inverter.
The 9VAC output is rectified by a 1N4001 diode then integrated by a 10uF capacitor. By sampling
at the same point on the AC waveform each time, the microcontroller is able to read an
approximation of the average AC output voltage.

Using average output voltage, rather than RMS, is a tradeoff which results in an output voltage
which varies +/- 5 VAC from the RMS target of 120 VAC as read by a true-RMS meter when
different types of loads are applied to the inverter. This is accurate enough for most applications
however the performance may be improved by including an RMS-to-DC converter such as that
made by Maxim between the AC output of the sensing transformer and the ADC input. Such a
device would ensure the inverter always produces an accurate RMS output value (Again, this was
not found to be crucial since an output variation of +/- 5 VAC was deemed to be quite tolerable).

The integrated output from the sense transformer (or the RMS-to-DC converter in an upgraded
design) is then fed to an ADC0831 which allows the microcontroller to read the output voltage.
The ADC0831 is an 8-bit converter and was chosen since it is a serial device (3 wires are required
to connect it to the MCU) and hence consumes less I/O pins on the tiny (18 pin) microcontroller
used.

The actual microcontroller is a PIC16C84 running at 3.6864MHz. The rather odd clock frequency
is a multiple of 60Hz allowing accurate frequency synthesis. The PIC reads the ADC, adjusts the
pulse-width for the next cycle, and synthesizes the PWM output on pins RB7 and RB6. Included
are several status LEDs, a beeper, and an output to switch-in a power-factor correction capacitor
of 22.5uF 200VAC for large inductive loads.

Control Algorithms (Firmware)

The algorithm to produce the necessary PWM waveform is simple in this initial test version: it is
designed to produce a basic inverter allowing the hardware to be prototyped. The firmware
functions as a pulse-width modulator (PWM) producing a variable pulse ranging in width from 4.1
mS to 8.2 mS. The width of the pulse depends on the output voltage required. A wider pulse
produces a higher output voltage while a thinner pulse produces a lower voltage. By sensing the
AC output voltage of the inverter the MCU can adjust the pulse width accordingly to produce a
nominal output voltage of 115 VAC. The PWM is required in the first place to compensate for
loading of the output. If the inverter's pulse width were originally set to give an RMS output of 115
VAC and a large load were applied, the output voltage would drop drastically essentially
producing a brownout condition on the load. The PWM must compensate for this by increasing
the pulse width as more load is applied. In essence the system operates as a voltage regulator
keeping the output voltage constant as loads of varying degrees are applied.

The single variable width pulse is produced by producing two back-to-back pulses. The first
pulse is fixed at 1/240th of a second (one-quarter of a complete cycle) width. During this relatively
long time the ADC is read and the required pulse width is calculated. The pulse width is
calculated by subtracting the actual voltage read from the target voltage (115VAC). An error
figure results which is added-to or subtracted-from the current pulse width. This is a unity-gain
closed-loop system.
Once the fixed time of the first pulse has elapsed (as set by TMR0 on the MCU) a pulse of variable
width is generated. This variable pulse can be a minimum of 0 mS to a maximum of 4.0 mS. It is
generated based on the pulse-width calculated previously. After the variable pulse is complete
the FET bank is shut off and the program waits for the timer to expire (another 1/240th of a
second). The total pulse width can now vary in width from 50% to 97% of one-half of the 60Hz
waveform. This completes one phase of the waveform (time consumed for the first pulse is
1/120th of a second) and the process is now repeated with the opposite phase (other FET bank)
with the exact same pulse width so as to produce a symmetric AC output with no DC offset.

Several features are included in the basic inverter algorithm such as indicators and overload
detection. The later is most notable feature although it may not be clear why it is required. When
a large motor starts it usually consumes up to 5 or 10 times it's rated current. You may have
noticed lights on the same circuit as a motor will often blink when the motor starts. Imagine that a
1/3hp motor which normally consumes about 6A could consume over 30A when starting! Clearly
this inverter will not produce that type of power. When a large motor attached to the inverter
attempts to start the pulse width will rapidly increase to maximum and the output voltage will still
drop below acceptable limits (as low as 95 volts have been measured). Normally we would
consider this an overload condition and shut down the inverter however if we simply wait a few
seconds the motor will start and will then consume its normal rated current of 6A. The algorithm
therefore has an 'overload timer' which permits the inverter to operate at overload (maximum
pulse width) for up to 10 seconds before being shut down. This has proven successful in
allowing virtually any motor to start properly.

As well as allowing temporary overloads for motor starting the inverter also permits 'moderate'
overloads. If the pulse width is at maximum, the MCU will monitor the AC output voltage and will
not deem an overload to have occurred until the AC output voltage falls below 107 VAC. This
extends the maximum power output of the inverter by allowing it to drive huge loads (albeit at
slightly reduced output voltages).

Indicators are provided on the front panel which show when the pulse width is changing (the
yellow LED) as well as when an overload is occurring and when the inverter has shut down due
to an overload.

Preliminary software to run the inverter (in MPASM) format is available here. Bear in mind that
this software is primarily designed to allow prototyping of the hardware of the inverter and will
subsequently be improved.

Firmware

INVERT7.ASM PIC microcontroller code to operate the I2K Inverter. NOTE: This was written for an
OLD version of MPASM and may require modifications in order to assemble on a newer version. I
will NOT be updating this in the near future. Please do not ask me to update this code for a
particular assembler.

Improvements and Modifications

True Sine Wave Production

Improvements are to be made in the PWM algorithm now to effect better sine-wave approximation
which will lower the harmonic content of the final output. In terms of the waveform produced, the
biggest improvement would be to chop the large squarewave pulse into many smaller pulses
varying in width from thin to fat then thin again. In this manner the output of the transformer will
closely resemble a true sine wave rather than a square wave. There are a number of techniques
to accomplish this. Originally, I planned to chop the 1/120th second period of one phase into ten
smaller pulses and use a lookup table to determine the pulse width for each small pulse in the
wave. To increase pulse width each small pulse would have to be scaled (multiplied). The
problem here is that the waveshape will change somewhat as the overall pulse width changes
and so harmonic content will vary depending on the load. To illustrate this, imagine a huge load
where each smaller pulse is scaled so fat that it 'runs into' the next pulse. The output wave
begins to resemble a square wave once again. The scaling technique is simple, but not optimal
(still, it should produce an output considerably better than the simple squarewave currently
used).

Added Note (2000/05): With new PIC processors getting faster and including more features (e.g.
The 18Cxxx series which features 10 MIPS performance and includes an 8*8 multiply in hardware)
it should be an easy matter to generate a true scaled sinewave with low harmonic distortion.

220V 50Hz Operation

I've had a number of E-Mails from people looking to use the inverter in Europe and other parts of
the world. To change the output voltage to 220V the only real changes required should be to the
output transformers: use units which are rated at 220-12 instead of the 120-12 ones employed in
my design. In the case of my inverter, which has two separate transformers in parallel to deliver
the currents required, these could simply be wired in series (observe the phase) to produce 220V
at about 8A. Be sure the voltage-sensing transformer is still on only one transformer (120V)
though or put it across the 220V output and change it to a 220V unit.

Changing from 60Hz to 50Hz operation can be done in two ways. The first requires changes to the
microcontroller's firmware to increase the pulse-width of the base pulse to 5 mS from 4.16 mS as
well as extra delays in the PWM code to scale the pulse accordingly. The second method would
be to change the crystal from 3.6864MHz to 3.072MHz (also a common crystal frequency). This
slows the processor by a factor or 5/6 so that it will now produce a 50Hz output wave.

Please do not ask me to modify the code or design for you. It is presented in the interest of
experimentation - You're on your own! I don't mind entertaining technical questions about the
design but I am not in the business of designing custom inverters for specific applications nor do
I have the time to give lessons on microcontroller programming. Unless you are already skilled at
assembly-language programming, this project is not suitable for you.

Links

International Rectifier manufacturers of the IRL2203 FET (datasheets available)

Microchip Inc. manufacturers of the PIC16C84 MCU (datasheets available)

Don Lancaster's Guru's Lair describing the concept of 'magic sinewaves'

Program for pic16C84

;*******************************************************************
;* INVERT7.ASM PIC PWM DC->AC Inverter Controller

;* Generates 60Hz PWM waveform for primary of inverter Xfrm

;* Begins at 0.5 max. width and uses ADC to sample average

;* AC output voltage. Also controls main power relays and

;* corrects load power factor

;*

;* M. Csele original version: 96/12/04 version 7: 98/12

;*

;* Hardware: Adapted for PIC Applications PCB with on-board ADC0831

;*

;* RA0 = ADC DATA Line

;* RA1 = ADC CLK Line

;* RA2 = ADC CS Line

;* RA3 = Alarm Beeper Output

;* (Used to announce startup and shutdown)

;* RA4 = [FUTURE OPTION] Shutdown Input (Active Low)

;*

;* RB0 = [FUTURE OPTION] Serial Receive/Transmit

;* RB1 = Power Factor Correction capacitor relay

;* (Switches in PF capacitor above 500VA load)

;* RB2 = Error LED Output

;* (Error code when shutdown due to fault)

;* RB3 = OverLoad LED Output

;* (Fast Blink = permissive overload)

;* (Constant = Vout < 115V at max pulse width)

;* (Slow Blink = shutdown after 6 secs of overload)

;* RB4 = PWM Change Status LED Output


;* (Lights when PW changing due to voltage error > 2)

;* RB5 = Main driver bank Relay ON Output

;* (Controls main power relays for xfmrs)

;* RB6 = Phase 2 Output to driver transistors (ACTIVE LOW)

;* RB7 = Phase 1 Output to driver transistors (ACTIVE LOW)

;*******************************************************************

LIST p=16C84 ;PIC16C84 is the target processor

INCLUDE "P16C84.INC" ;Include file with register defines

;Register Defines

Temp equ 2F ;temp storage during misc functions

ADCresult equ 2E ;stores ADC reading

ADCCtr equ 2D ;stores count for reading 8 bits from serial ADC

PulseWidth equ 2C ;Width of var. part of pulse in 10uS increments

Timer equ 2B ;Used as a count-down timer

ErrorValue equ 2A

ErrorTimerLo equ 29

ErrorTimerHi equ 28

LedBlinkTimer equ 27 ;Used for blinking LED during max. load

;PORT A Defines

ADCCLK equ 1

ADCDAT equ 0

ADCCS equ 2

BEEP equ 3
;PORT B Defines

PHASE1 equ 7

PHASE2 equ 6

PWRRELAY equ 5

LEDPWM equ 4

LEDOVERLD equ 3

LEDERROR equ 2

PFCRELAY equ 1

Main

movlw b'00000001' ;Port B all outputs except unused RB0

tris PORTB

movlw b'11000000' ;All Outputs LOW except drivers OFF (high)

movwf PORTB

movlw b'00010001' ;Port A all inputs except RA4 and RA0 (DATA)

tris PORTA

movlw b'00000000' ;All Outputs LOW

movwf PORTA

movlw .0 ;Initialize Pulse Width to 0.5 Max. (Min)

movwf PulseWidth

movlw b'10000110' ;Set timer 0 to overflow at 240Hz. 7200Hz in =

;Internal clock, Divide by 128 prescaler

bsf STATUS,RP0 ;select Page 1

movwf OPTION_REG
bcf STATUS,RP0 ;select Page 0

clrwdt

movlw .226 ;Initialize timer for 240Hz overflow

movwf TMR0

bsf PORTA,BEEP ;Beep for 1 second

movlw .240 ;1 second delay using timer

movwf Timer

NextDly

call WaitForTmr

decfsz Timer,f

goto NextDly

bcf PORTA,BEEP

bsf PORTB,PHASE1 ;Turn Phases OFF

bsf PORTB,PHASE2

bsf PORTB,PWRRELAY ;Main Power Relay ON

bcf PORTB,PFCRELAY ;Power Factor Correction OFF

;Starting Value: Minimum pulse width

movlw .1

movwf PulseWidth

;** Inverter main loop: Generate 60Hz PWMed Sine Wave and check system

MainLoop

;Phase A half-cycle output


;Generate fixed width pulse of 1/240th sec.

bcf PORTB,PHASE1 ;Phase A ON (active low)

;During Phase A fixed delay, check output voltage and adjust

;Pulse Width Accordingly for the next cycle

call ReadADC

call AdjustPulseWidth

call WaitForTmr ;Wait for 1/240th second to elapse

;Generate variable width pulse of 0 to 1/240th sec

movfw PulseWidth

movwf Timer

NextPhaseADly

call Delay10uS ;Generate from 1 to 255 10uS delays

decfsz Timer,f

goto NextPhaseADly

bsf PORTB,PHASE1 ;Phase A OFF

call WaitForTmr ;Wait for rest of 1/240th sec period

;Phase B half-cycle output

;Generate fixed width pulse of 1/240th sec.

bcf PORTB,PHASE2 ;Phase B ON (active low)

call WaitForTmr ;Wait for 1/240th second to elapse

;Generate variable width pulse of 0 to 1/240th sec


movfw PulseWidth

movwf Timer

NextPhaseBDly

call Delay10uS ;Generate from 1 to 255 10uS delays

decfsz Timer,f

goto NextPhaseBDly

bsf PORTB,PHASE2 ;Phase B OFF

call WaitForTmr ;Wait for rest of 1/240th sec period

goto MainLoop

;******************************

;** Called Functions Library **

;******************************

;** 10 microsecond Delay Function ... includes 4 cycles for call/return

Delay10uS

nop ;6uS+4uS for Call/Return = 10uS total

nop

nop

nop

nop

nop

nop ;ADDED to increase max PW to 8.06 mS (This delay=11.9uS)

return
;** Function to wait for RTCC to expire and re-load it for 240Hz

WaitForTmr

movf TMR0,w

btfss STATUS,Z

goto WaitForTmr

;Set RTCC for divide by 30 again

movlw .226

movwf TMR0

return

;** Function to read one byte from the ADC and store it in ADCresult

; Result is a number representing Output Voltage (AC). Range is 0 to 255

; Target output (binary at the ADC) is 127 (= 120 VAC)

ReadADC

movlw 0 ; Clear out ADCresult register for new data

movwf ADCresult

bcf PORTA,ADCCS ; Activate /CS line on the ADC to start

movlw 9 ; Set number of bits to read in = 8 +1 start

movwf ADCCtr ; Load this into the counter register

bsf PORTA,ADCCLK ; Pulse the ADC clock line High then Low

nop ; signals the start of a conversion

bcf PORTA,ADCCLK

Get_One_Loop ; This is the main loop, should execute 9 times

bsf PORTA,ADCCLK ; Pulse the ADC clock line hight then low

nop ; to get the first bit

bcf PORTA,ADCCLK
btfsc PORTA,ADCDAT ; Check the value of the data bit

goto SetCarry

bcf STATUS,C ; If its a zero, put a zero into the Carry

goto RotateBits

SetCarry

bsf STATUS,C ; Otherwise its a 1, put that into the carry

RotateBits

rlf ADCresult ; Shift bits left from carry into ADReslt

decfsz ADCCtr ; Decrement Counter -

goto Get_One_Loop ; Do it 9 times

bsf PORTA,ADCCS ; When done, Disable the ADC

return

;** Function to adjust Pulse Width

; PulseWidth must be constrained to a range of 1 to 255

;If required for stability, ERROR could be divided by 2 using a shift

AdjustPulseWidth

;First, calculate error. Error = 127(target)-ADCresult(actual)

;Error will be a 2's complement number in the range -128 to +127

movfw ADCresult

sublw .127 ;Calculate error (w = 127-Vactual)

movwf ErrorValue

;If error is a POSITIVE quantity, Vactual is too low ... PW++

;If error is a NEGATIVE quantity, Vactual is too high ... PW--

;If error is zero, we are at target output voltage ... do not adjust
btfsc STATUS,Z

goto ZeroError

;Error is a 2's complement number (0x00-0x7F=pos, 0xFF-0x80=neg)

bsf PORTB,LEDPWM ;Light PWM Change LED (yellow)

btfsc ErrorValue,7 ;If High Bit is set, it is negative

goto NegativeError

PositiveError

;Output voltage is too low, increase PulseWidth

;Since error is a positive quantity (0x00 to 0x7F), add it to PW

movfw ErrorValue

addwf PulseWidth,f ;PW = PW+Error

;Now check if we overflowed (ie PulseWidth > 255: Carry set)

btfss STATUS,C

goto AdjustPowerFactor

movlw .255 ;Maximum pulse width = 255

movwf PulseWidth

;PERMISSIVE OVERLOAD LOGIC: If the inverter is at max. PW and the

;error is small (ie output voltage > 105 VAC), allow it to run.

;If the error is large, it is a true overload so time 10 seconds

;then shutdown if it persists.

movfw ErrorValue
sublw .20 ;Check if error is > .20

btfss STATUS,C ;C=1 if Error < .20

goto LargeError

incf LedBlinkTimer,f ;Blink the Overload LED quickly

bcf PORTB,LEDOVERLD

btfsc LedBlinkTimer,4 ;Blink Overload Led at 2Hz to show max. output

bsf PORTB,LEDOVERLD

goto AdjustPowerFactor

LargeError

;The error is large so this is a true overload condition

bsf PORTB,LEDOVERLD ;Show that an overload is occurring (Max PW)

incf ErrorTimerLo ;Increment Overload timer at 60Hz

btfss STATUS,Z ;to keep track of time

goto TestErrorTime

incf ErrorTimerHi ;High counter

TestErrorTime

movfw ErrorTimerHi ;Test for 10 seconds of overload error

sublw .2 ;w=2-w Test for high Byte = 2

btfss STATUS,Z

goto AdjustPowerFactor

movfw ErrorTimerLo
sublw .88 ;w=88-w Test low byte = 88 (600 ticks=10 sec)

btfss STATUS,Z

goto AdjustPowerFactor

;Overload has persisted > 10 seconds. Shutdown and Blink Error Code

bsf PORTB,PHASE1 ;Shut down Phases

bsf PORTB,PHASE2

bcf PORTB,PWRRELAY;Main relay off

ErrorLoop

bsf PORTA,BEEP ;Beep for 0.25 second

bsf PORTB,LEDERROR ;Light Error LED

bcf PORTB,LEDOVERLD ;Light Overload LED alternately

movlw .60 ;0.25 second delay using timer

movwf Timer

NextDlyA

call WaitForTmr

decfsz Timer,f

goto NextDlyA

bcf PORTA,BEEP

bcf PORTB,LEDERROR

bsf PORTB,LEDOVERLD

movlw .60 ;0.25 second delay using timer

movwf Timer

NextDlyB

call WaitForTmr
decfsz Timer,f

goto NextDlyB

goto ErrorLoop ;Never ending loop

ZeroError

bcf PORTB,LEDPWM ;Turn off Overload and PWM change LEDs

bcf PORTB,LEDOVERLD

clrf ErrorTimerLo ;Clear timers for overload error

clrf ErrorTimerHi

goto AdjustPowerFactor ;Error is zero, so no adjustment needed

NegativeError

;Output voltage too high ... decrease pulse width

;Error must be a 2's Comp. negative quantity (0xFF to 0x80)

bcf PORTB,LEDOVERLD ;Turn off overload LED if still on

clrf ErrorTimerLo ;Clear timers for overload error

clrf ErrorTimerHi

;Convert Error to a magnitude (0x00 to 0x7F) and compare it to PW

;If magnitude of error > PW, set PW to minimum, otherwise, add

movfw ErrorValue

comf ErrorValue ;Invert Error then increment to convert ...

incf ErrorValue,f ;... Signed number into a positive integer

;Subtract PW-Error then Check if magnitude of error > PW


movfw ErrorValue

subwf PulseWidth,f ;PW=PW-|ErrorValue|

btfss STATUS,C ;C=0 if result is negative (ie Error>PW)

goto SetMinPulseWidth

btfss STATUS,Z ;If result is zero, set to min width

goto AdjustPowerFactor

SetMinPulseWidth

movlw .1 ;Set PW = 1 (mimimum width)

movwf PulseWidth

;Before exiting AdjustPulseWidth, check if load is > 500VA. If so, switch

;in power factor correction. Not perfect, but helps immensely with motor

;starting! On large resistive loads it simply increases current consumption.

;This logic is required to prevent an unloaded inverter from 'seeing' a huge

;capacitive load.

AdjustPowerFactor

movfw PulseWidth

sublw .55 ;Check if PW > 5.0 mS

btfss STATUS,C ;C=1 if PW < 5.0 mS (small load)

goto LargeLoad

bcf PORTB,PFCRELAY ;Swich out PF correction


return

LargeLoad

bsf PORTB,PFCRELAY ;Switch in capacitor to correct PF

return

END