Power loss? No problem. Jeff‘s PIC16F87-based SPI power alarm
peripheral circuit will keep you on top of things. This simple
design will be a useful addition to a variety of
applications,particularly those in the healthcare industry.
The way most folks can tell when they‘ve lost power at home is when
they see "12:00" flashing on their appliances. You may not have
noticed, but some high-end models have a back-up supply that keeps
the clock ticking during power outages. If you have such a model,
you don't have to find the instructions for setting the clock.
Appliances without the need for a timekeeping function will go
through the power-off cycle without a care in the world when power
is temporarily lost. And that‘s fine in most cases. There are,
however, times when it would be helpful to know if a particular
piece of equipment has lost power. For instance, a freezer may need
attention if its temperature rises too high. In testing situations,
it would be nice to know if a power failure has affected your data
without having to wait until the end of the testing period. If you
work with medical or safety devices,it would be extremely important
to know when utility failures and human error cause power outages
in critical systems.
Although this functionality should be part of every initial design,
its importance is easily overlooked. In other devices, the design
may call out this function as an option. Because an alarm function
like this must run on its own, it lends itself well to an optional
separate circuit. I designed this project as an alarm peripheral to
the main processor.
POWER MONITOR & ALARMAs a peripheral, my circuit takes commands from the main processor
via a SPI interface. This simple interface is supported by just
about every microcontroller in use today. If the SPI is not
supported in hardware, software routines are easily added to
support this function.
Four signals make up the alarm interface in addition to power and
ground. Why do I need an interface? I must be able to enable and
disable the alarm. This allows power to be removed intentionally
without the alarm going off. A piezoelectric beeper and LEDs
perform the alarm function. The interface gives access to the
beeper and LEDs for other purposes if you want to use them. Because
this circuit needs to continue to operate after the main power is
gone, it must run from its own power source. The circuit must run
on an alternate power source and keep it charged as well.
MONITORING POWER
The six-wire SPI interface includes system power (5 V) and ground
(see Figure 1)。 In addition to being able to run on system power
when it‘s available,I want to monitor the loss of it without the
loss of power to this circuit. I use a microcontroller that
operates at less than 5 V to do this.

The Microchip Technology PIC16F687 microcontroller has an operating
range of 2 to 5.5 V. System power is applied to the circuit through
a PNP transistor, which the normal bias of the input circuitry
holds on. An output of the microcontroller can pull this bias to
ground and turn off the transistor, effectively removing system
power from the circuit. It might seem counterproductive to turn off
the system‘s power, but it puts the circuit load on the standby
battery and makes it possible to measure the battery's voltage
under load conditions using the PIC16F687 microcontroller‘s ADC.
The standby voltage, which is 3.6 V, comes from a standard portable
telephone NiCd battery pack. The battery is applied to the
microcontroller using a Schottky diode (for the lowest forward
voltage drop).
A 10:1 resistor divider across the system power presents a logic
high when system power is acceptable. You can trim these values so
the junction of the two resistors will present a logic low (at some
particular system voltage level) to a digital input of the
microcontroller. As an alternate power loss circuit, you can use a
reset device like a voltage detector in Microchip‘s MCP111 series.
These voltage detectors come in a variety of voltage detection
ranges and present a logic high as long as the system voltage is
greater than the device's detection voltage.
TRICKLE CHARGINGAlthough NiCd batteries can accept some hefty recharging currents,
they need to receive a constant tricklecharged current to remain
fully charged. This NiCd pack uses three cells with an average
service capacity of 300 mAh. The capacity (C) in this case is 300
mA. Although fast charging can occur at a rate of up to 1 C,the
suggested continuous trickle charge rate is approximately 8
mA(i.e., approximately C/40)。 A simple trickle charging circuit
that applies a current at the trickle charge rate (once the cells
have reached their charged voltage) might be a simple series
resistor. The value of this resistor is chosen based on the
difference between the charging voltage and the cell‘s rated
voltage.
If the NiCds have been discharged,the voltage across this charging
resistor will be greater than normal, supplying a higher charging
current. Make sure the value chosen for the charging resistor will
not allow excessive charging current when the battery pack has been
discharged. As the cells are charged, the cell voltage raises until
they have been fully charged. At this point, the charging resistor
should be allowing only a small trickle charge to keep the battery
pack in tiptop condition. Current from the NiCd batteries to the
microcontroller won't occur as long as the higher system voltage is
present.
When NiCd batteries are assembled in series into battery packs,
they can be ruined if discharged too far. Sometimes a cell will
reverse polarity if it becomes discharged while the other cells
still have potential. To avoid this phenomenon, it‘s recommended
that you prevent discharge past approximately 75% of the rated
voltage. For a 3.6-V pack, that's around 2.7 V. At 2.7 V, about 95%
of its capacity has been expended.
BATTERY VOLTAGEThe aforementioned condition of the NiCd battery pack is measured
under load conditions. The PIC16F687 microcontroller can
periodically turn off the system‘s power by pulling the bias to the
power transistor's circuitry to ground. At this point, the circuit
voltage drops until the NiCd battery‘s voltage (minus the Schottky
diode drop) takes over. Most ADCs use VCC as a reference voltage.
This is a problem in my case because I really don't know what VCC
is. That‘s what I'm attempting to measure! To successfully measure
the battery voltage, I need a stable known reference for the ADC.
The PIC16F687 offers the use of an external reference, which can be
connected to an input pin. In this case, a microcontroller power
reference voltage of, say, 1.2 V (using an LM385-1.2)can supply the
necessary stable reference. If a 2:1 resistor divider is applied
across the battery pack, the resistor junction presents one-third
of the battery pack voltage to the ADC. Using a 1.2-V reference,
the A/D conversion will be at its maximum when the NiCd voltage is
3.6 V (fully charged)and the divider offers 1.2 V (i.e., 1/3 ×3.6
V) to the ADC.
Although a bit obscure, an alternative method can take advantage of
an internally created reference voltage of 0.6 V normally used as
an optional input for the internal analog comparator circuitry.
Although this reference can‘t be used as a reference for the ADC,
it can be sampled as an A/D input. Because the conversion value
will change as the battery voltage(VCC) changes, what good is that?
With one absolute known, a 0.6-V input,you can predict what the VCC
will need to be to give a particular conversion value.
Let's assume a VCC of 5 V. Each bit of a 10-bit conversion will be
approximately 4.9 mV (i.e., 5 V/1,024 with a VCC (reference) or 5
V)。 A 0.6-V A/D input will convert to a digital value of 122 (i.e.,
0.6 V/4.9 mV)。 If you reduce the VCC by half (2.5 V), then each bit
of the ADC now represents 2.5 mV (i.e.,2.5 V/1,024)。 And that 0.6-V
input converts to a digital value of 240 (i.e., 0.6 V/2.5 V)。
If VCC could drop to 0.6 V, a conversion would produce a maximum
value of 1,023 because the 0.6-V input equals the reference. You
can see that as the reference decreases the conversion value
increases. You just need an equation to convert this data into a
value that represents the actual VCC (reference voltage)。 I‘d like
to get a value that is in tenths of a volt (i.e.,36 = 3.6 V)。 In
this case, you'd want a VCC of 5 V to convert to a value of 50.
What would you need to do to a conversion value of 120 (VCC of 5 V)
to get a value of 50? Divide it into 6,100 (i.e., 6,100/122 = 50).
Let‘s look at this process with a VCC of 3.6 V (charged NiCd
batteries):
And now let's consider a VCC of 2.7 V(discharged NiCd batteries):
Under SPI control, you have access to the 8-bit value periodically
calculated here(the battery voltage in tenths of 1 V).This rate is
presently fixed in about 10-s intervals.
ALARM DRIVERIf the microcontroller had a PWM module, it would make a great
alarm output generator. In fact, the PIC16F687 doesn‘t have this.
(Other 20- pin parts in the PIC16F690 family contain a hardware
PWM.) The piezoelectric element doesn't need duty cycle control, so
a simple output toggle will be sufficient. Timer0 becomes the
frequency control. Choosing a prescale value of 256 for
Timer0 allows an 8-bit value (between 0x40 and 0xA0) to be
reloaded into the TMR0 at each Timer0 overflow to create an output
of 2.4 to 4.6 kHz. An OUTPUT pin is toggled during the interrupt
routine to produce the output used to drive the piezo element.
Although this TMR0 overflow interrupt is continuous, a flag bit is
tested during each interrupt that skips the toggling if you don‘t
want any piezo output (Tog = 0).
Timer1 is used as a duration timer for the alarm frequency. It is
always reloaded with a constant to produce 100-ms interrupts
(overflows)。 Two 8- bit values are used in conjunction with Timer1,
on duration and off duration. These values are used in the Timer1
interrupt to determine when the duration has been reached.
The Tog flag bit that enables frequency output by Timer0 is also
used by Timer1‘s interrupt routine to select either the on or off
duration values. To use this function, the application must select
the appropriate state of the Tog flag, clear the duration
counter,clear any overflows (TMR1IF = 0),and enable Timer1
interrupts(TMR1IE = 1)。 If Tog has been set, the frequency output
is enabled and Timer1 uses the on duration value. At the end of the
duration time, the interrupt clears the Tog flag and disables
additional Timer1 interrupts.
The default operation of the alarm output has an on time of 100 ms
and an off time of 400 ms. That's a 2-Hz beep rate. Under SPI
control, you have control over the three 8-bit values used for
Timer0 and Timer1: the frequency,the on duration, and the off
duration.
SPI
When I choose to use SPI as an interface,I search for low
pin-count microcontrollers with a hardware SPI. If no additional
outputs are necessary(i.e., no LEDs),then this can be implemented
in an 8-pin device. Atmel‘s ATtiny25 microcontroller is a good
choice (see Photo 1).But I wanted to offer LEDs, so I went with a
higher pin-count microcontroller like the PIC16F687. The SPI
interface can be configured as a fourwire interface (using *SS as a
chip select), a three-wire interface (using separate data direction
paths SDI and SDO), or a two-wire interface (tying SDI and SDO
together)。 The four-wire implementation allows multiple SPI devices
to be connected to the microcontroller. Each device has its own
chip select associated with it.

The data format is an 8-bit command byte followed by optional
bytes. The command byte performs a number of functions. The most
significant bit of the command requests a single beep from the
piezo element. Its duration is based on a user-programmed variable,
one of 8 bytes available to the user (more on these in a
minute)。Bit 4 is a read/write bit that‘s used with the 3 least
significant bits. These 3 bits indicate the register of interest.
Table 1 is a list of registers. Note that a register like the
battery voltage has no meaningful write function. When a register
needs to be read or written, an additional byte must be sent from
the master. When writing data to a register, the byte sent holds
this value. When reading a register, a dummy data byte is sent so
that the master can clock the requested data out of this circuit.
Drop *SS (chip select) before transmitting any command or data from
the master. Raise *SS after any command and optional data has been
transmitted.

Registers 5 through 7 are used to enable or disable various
functions. When register 5 contains a nonzero value, the piezo
element is enabled using the value from the frequency register. The
tone remains continuous until this register is written with a zero
value. Similarly, when register 6 contains a nonzero value, the
piezo element is enabled using the value from the frequency
register. In this mode, however, the on and off duration values are
used. The beeping continues until this register is written with a
zero value. Finally, when register 7 contains a nonzero value, the
alarm function monitors the PWRGOOD input and enters Alarm mode
until the register is written with a zero value.
Simply applying power won‘t turn off the alarm. Register 7 must be
written with zero to turn off the alarm (and disable it)。 Writing a
nonzero value to register 7 can rearm the alarm. To prevent the
circuit from activating Alarm mode when power is purposely removed,
the master should disable the alarm before you remove power.
LEDsSometimes an audible alarm isn't sufficient. The alarm circuit
contains eight LEDs that can be used by the master application to
indicate modes or functions of the main application. These are bit
controlled by the data written to LED register 3. To reduce the
operating current, only a single LED is enabled at a time.
Persistence of vision allows the multiplexing to become invisible.
During an alarm condition, the LED data alternates between 0x55 and
0xAA. The duration of each is controlled by the on and off duration
values (registers 1 and 2) along with the beeping of the piezo
element.
CONSUMPTION
When power is removed while the alarm is enabled, the PwrGood
signal drops to logic 0 and sends the alarm application into Alarm
mode. When powered by a battery, the circuit will draw a few
milliamperes (depending on the LED current)。 That‘s days of active
alarming using a 300-mAh NiCd replacement portable phone battery
pack.
A few safety precautions should be implemented with this type of
circuit. First, you should use brownout protection. Many
microcontrollers have this built right in, but some may not have
user programmable set points. A brownout circuit will hold the
microcontroller in reset until there is ample voltage applied by
the power supply(whether it's system power or battery power)。 If
this brownout level is set at 4 V, then a 3.6-V battery voltage
will never be high enough to overcome this protection. Although the
PIC16F687 doesn‘t have a programmable set point,its level is down
at 2 V, which is great for this application, especially because you
don't want the NiCd pack to discharge any more than that amount.
A watchdog timeout could act as a second form of protection. If the
application should ever get stuck in a loop waiting for something
to happen(which never will for some unexpected reason), the
microcontroller will reset. This gives the application a method for
restarting automatically. Be careful when placing the watchdog
clear instructions within the program so that the watchdog timer
can be periodically cleared (preventing a timeout and reset)。
However, a watchdog clear instruction placed inside a potential
loop will continue to clear the watchdog timer and never allow it
to perform its intended function.
Jeff Bachiochi (pronounced BAH-key- AH-key) has been writing for
Circuit Cellar since 1988. His background includes product design
and manufacturing. He may be reached at
jeff.bachiochi@circuitcellar.com.
PROJECT FILESTo download the code,go to
ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2006/194.
SOURCESATtiny25 Microcontroller
Atmel Corp.
www.atmel.com
PIC16F687 Microcontroller
Microchip Technology, Inc.
www.microchip.com