You are on page 1of 24

Application Note 112

March 2007
Developments in Battery Stack Voltage Measurement
A Simple Solution to a Not So Simple Problem
Jim Williams and Mark Thoren
Automobiles, aircraft, marine vehicles, uninterruptible
power supplies and telecom hardware represent areas
utilizing series connected battery stacks. These stacks
of individual cells may contain many units, reaching potentials of hundreds of volts. In such systems it is often
desirable to accurately determine each individual cells
voltage. Obtaining this information in the presence of the
high common mode voltage generated by the battery
stack is more difcult than might be supposed.

volts in a large series connected battery stack such as


is used in an automobile. Such high voltage operation is
beyond the voltage breakdown capabilities of most practical semiconductor components, particularly if accurate
measurement is required. The switches present similar
problems. Attempts at implementing semiconductor based
switches encounter difculty due to voltage breakdown

The Battery Stack Problem

commentary on some typical approaches.

, LT, LTC and LTM are registered trademarks of Linear Technology Corporation.
All other trademarks are the property of their respective owners.
1See Appendix A, A Lot of Cut Off Ears and No Van Goghs for detail

The battery stack problem has been around for a long


time. Its deceptively simple appearance masks a stubbornly
resistant problem. Various approaches have been tried,
with varying degrees of success.1

Figure 1s voltmeter measures a single cell battery. Beyond


the obvious, the arrangement works because there are no
voltages in the measurement path other than the measurand. The ground referred voltmeter only encounters the
voltage to be measured.

Figure 2s stack of series connected cells is more complex


and presents problems. The voltmeter must be switched
between the cells to determine each individual cells
voltage. Additionally, the voltmeter, normally composed
of relatively low voltage breakdown components, must
withstand input voltage relative to its ground terminal.
This common mode voltage may reach hundreds of
VOLTMETER

and

N CELLS

+
VOLTMETER

+
+

BATTERY
STACK

GND

+
SWITCH
CONTROL
GND

+
+
+

SINGLE CELL
BATTERY

GND
AN112 F02

AN112 F01

Figure 1. Voltmeter Measuring Ground Referred Single Cell is


Not Subjected to Common Mode Voltage

Figure 2. Voltmeter Measuring Cell in Stack Undergoes


Increasing Common Mode Voltage as Measurement Proceeds
Up Stack. Switches and Switch Control Also Encounter High
Voltages
an112f

AN112-1

Application Note 112


and leakage limitations. What is really needed is a practical
method that accurately extracts individual cell voltages
while rejecting common mode voltages. This method
cannot draw any battery current and should be simple
and economically implemented.
Transformer Based Sampling Voltmeter
Figure 3s concept addresses these issues. Battery voltage
(VBATTERY) is determined by pulse exciting a transformer
(T1) and recording transformer primary clamp voltage after
settling occurs. This clamp voltage is predominately set by
the diode and VBATTERY shunting and similarly clamping
T1s secondary. The diode and a small transformer term
constitute predictable errors and are subtracted out, leaving VBATTERY as the output.
Detailed Circuit Operation
Figure 4 is a detailed version of the transformer based
sampling voltmeter. It closely follows Figure 3 with some
minor differences which are described at this sections
conclusion. The pulse generator produces a 10s wide
event (Trace A, Figure 5) at a 1kHz repetition rate. The
pulse generators low impedance output drives T1 via a
10k resistor and also triggers the delayed pulse generator.

T1s primary (Trace B) responds by rising to a value representing the sum of VDIODE + VBATTERY along with a small
xed error contributed by the transformer. T1s primary
clamps at this value. After a time (Trace C) dictated by
the delayed pulse generator a pulse (Trace D) closes S1,
allowing C1 to charge towards T1s clamped value. After a
number of pulses C1 assumes a DC level identical to T1s
primary clamp voltage. A1 buffers this potential and feeds
differential amplier A2. A2, operating at a gain near unity,
subtracts the diode and transformer error terms, resulting
in a direct reading VBATTERY output.
Accuracy is critically dependent on transformer clamping
delity over temperature and clamp voltage range. The
carefully designed transformer specied yields Figure 6s
waveforms. Primary (Trace A) and secondary (Trace B)
clamping detail appear at highly expanded vertical scale.
Clamping atness is within millivolts; trace center aberrations derive from S1 gate feedthrough. Tight transformer
clamp coupling promotes good performance. Circuit accuracy at 25C is 0.05% over a 0V to 2V battery range with
120ppm/C drift, degrading to 0.25% at VBATTERY = 3V.
2Battery stack voltage monitor development is aided by the oating,
variable potential battery simulator described in Appendix B.

PULSE
GENERATOR

DELAYED PULSE
GENERATOR

T1

DIODE

+
+

PULSE
GENERATOR
N CELLS

T1
PRIMARY

VBATTERY

DELAYED
PULSE

VBATTERY + DIODE
AND T1 ERROR

N CELLS

DC POTENTIAL =
T1S CLAMP VALUE
ANALOG INPUT
SAMPLING
VOLTMETER
SAMPLE COMMAND

DIODE TRANSFORMER
ERROR TERMS
SUBTRACTION

OUTPUT = VBATTERY
AN112 F03

Figure 3. Transformer-Based Sampling Voltmeter Operates Independently of High Common Mode Voltages. Pulse
Generator Periodically Activates T1. Delayed Pulse Triggers Sampling Voltmeter, Capturing T1s Clamped Value.
Residual Error Terms are Corrected in Following Stage

an112f

AN112-2

Application Note 112


5V

OUT
IN
LT1761-5
GND

12VIN
= 1/6 74HC04

5V, 10s, 1kHz


= 2N3904 MATCH VBE
1mV AT 200A
= VN2222

PULSE GENERATOR

T1 = PULSE ENGINEERING PA2100NL OR PA2101NL


* = 1% RESISTOR

DIODE

10k*

SAMPLING VOLTMETER
(SAMPLE-HOLD)

Q1
T1

VBATTERY

12V

10F

S1
1/4 CD4016

6.34M*

A1
LTC1050

10k

+
A2
LT1789

C1
0.001F

4.7k
Q2

12V

OUTPUT =
VBATTERY
A = 1.03

22k
5V
5V

DELAYED
PULSE

7.5k*

ERROR SUBTRACTION

Q3

100pF

511*

5V

AN112 F04

VCC RC1 C1 Q1 Q2 CL2 B2

A2
DELAYED
PULSE
GENERATOR

74HC123
A1 B1 CL1
5V

C2 RC2 G
270pF

DELAY TIME

14.7k*
5V

Figure 4. Transformer Fed Sampling Voltmeter Schematic Closely Follows Figure 3s Concept. Error Subtraction Terms
Include Q3 Compensating Q1 and Resistor/Gain Corrections for Errors in T1s Clamping Action. Q1-Q3 Transistors
Replace Diodes for More Consistent Matching. Q2 Prevents T1s Negative Recovery Excursion from Inuencing S1

A = 5V/DIV
B = 2V/DIV

A = 2mV/DIV
ON 2.2V STEP

C = 5V/DIV
D = 5V/DIV
B = 2mV/DIV
ON 2.2V STEP

2s/DIV

AN112 F05

Figure 5. Figure 4s Waveforms Include Pulse Generator


Input (Trace A), T1 Primary (Trace B), 74HC123 Q2 Delay
Time Output (Trace C) and S1 Control Input (Trace D). Timing
Ensures Sampling Occurs When T1 is Settled in Clamped State

2s/DIV

AN112 F06

Figure 6. T1 Primary (Trace A) and Secondary (Trace B)


Clamping Detail. Highly Expanded Vertical Scale Shows
Primary and Secondary Clamping Flatness Within Millivolts.
Trace Center Aberrations Derive from S1 Gate Feedthrough
an112f

AN112-3

Application Note 112


Several details aid circuit operation. Transistor VBEs, substituted for diodes, provide more consistent initial matching
and temperature tracking. The 10F capacitor at Q1 maintains low impedance at frequency, minimizing cell voltage
movement during the sampling interval. Finally, synchronously switched Q2 prevents T1s negative recovery excursion from deleteriously inuencing S1s operation.
This approachs advantage is that its circuitry does not
encounter high common mode voltagesT1 galvanically isolates the circuit from common mode potentials
associated with VBATTERY. Thus, conventional low voltage
techniques and semiconductors may be employed.
Multi-Cell Version
The transformer-based method is inherently adaptable to
the multi-cell battery stack measurement problem previously described. Figure 7s conceptual schematic shows a
multi-cell monitoring version. Each channel monitors one
cell. Any individual channel may be read by biasing its appropriate enable line to turn on a FET switch, enabling that
particular channels transformer. The hardware required
for each channel is typically limited to a transformer, a
diode connected transistor and a FET switch.
TO PULSE
GENERATOR

TO
SAMPLE-HOLD

BATTERY
STACK

ENABLE
LINES

AN112 F07

N SECTIONS

Figure 7. Multiple Channels are Facilitated by Adding


Enable Lines and Transistor Switches

Automatic Control and Calibration


This scheme is suited to digitally based techniques for
automatic calibration. Figure 8 uses a PIC16F876A microcontroller, fed from an LTC1867 analog to digital converter,
to control the pulse generators and channel selection. As
before, even though the cell stack may reach hundreds of
volts, the transformer galvanic isolation allows the signal
path components to operate at low voltage.
A further benet of processor driven operation is elimination
of Figure 4s VBE diode matching requirement. In practice, a
processor-based board is tested at room temperature with
known voltages applied to all input terminals. The channels
are then read, furnishing the information necessary for the
processor to determine each channels initial VBE and gain.
These parameters are then stored in nonvolatile memory,
permitting a one-time calibration that eliminates both VBE
mismatch and gain mismatch induced errors.
Channels 6 and 7 provide zero and 1.25V reference voltages
representing cell voltage extremes. The room-temperature
values are stored to nonvolatile memory. As temperature
changes occur, readings from channel 6 and 7 are used to
calculate a change in offset and a change in gain that are
applied to the six measurement channels. The calibration is
maintained as temperature varies because each channels
2mV/C VBE drift slopes are nearly identical. Similarly,
gain errors from channel to channel are nearly identical.
Since the gain and offset are continuously calibrated, the
gain and offset of the LTC1867 drop out of the equation. The
only points that must be accurate are the 0V measurement
(easy, just short the channel 6 inputs together) and the
1.25V reference voltage, provided by an LT1790-1.25. The
LTC1867 internally amplies its internal 2.5V reference to
4.096V at the REFCOMP pin, which sets the full scale of
the ADC (4.096V when it is congured for unipolar mode,
2.048V in bipolar mode). Thus the absolute maximum
cell voltage that can be measured is 3.396V. And since the
offset measurement is nominally 0.7V at the ADC input
it is never in danger of clamping at zero. (A zero reading
will result if a given LTC1867 has a negative offset and
the input voltage is any positive voltage less than or equal
to the offset.)
Accuracy of the processor-driven circuit is 1mV over a
0V to 2V input range at 25C. Drift drops to less than
50ppm/Calmost 3x lower than Figure 4.
an112f

AN112-4

Application Note 112


10k

OFFSET

10k

2N3904

T1

74HC14

ADC_CH7
EN0

4.7k
VN2222

RB0/EXCITATION
ENABLE
LINES

74HC574
DB0
DB1
DB2
PROCESSOR DB3
DATA BUS DB4
DB5
DB6
DB7
RB1/LATCH

1D
2D
3D
4D
5D
6D
7D
8D
CLK

1Q
2Q
3Q
4Q
5Q
6Q
7Q
8Q

74HC00
EN0
EN1

10k

GAIN

10k
EN2
EN3
EN4
EN5
EN6
EN7

2N3904

T2

74HC14
ADC_CH6

TO OTHER
CHANNELS

EN1

VREF

10F

4.7k
VN2222

RB0/EXCITATION
74HC00

5V

IN
OUT
LT1790-1.25

OC

5V

0.1F
2.2F

ADC_CH0
ADC_CH1
ADC_CH2
ADC_CH3
ADC_CH4
ADC_CH5
ADC_CH6
ADC_CH7
10F

1F

VCC
LTC1867
VREF
CH0
CH1
CH2
CH3
CH4
CH5
CH6
CH7
REFCOMP
GND

SIX IDENTICAL CHANNELS


10k
10k

RB5/CS
RC3/SCK
RC5/MOSI
RC4/MISO

T3

74HC14

2N3904

ADC_CHX
PROCESSOR
SPI BUS

10F

4.7k

ENX
RB0/EXCITATION

VN2222

CHX+
INPUT
CHX

74HC00

AN112 F08a

Figure 8a. Pulse Generators, Calibration Channels, Measurement Channels.


ADC Calibration Channels Eliminate VBE Matching Requirement and
Compensate for Temperature Dependent Errors

an112f

AN112-5

Application Note 112


5V

PIC16LF877A-I/PT
0.1F

0.1F

VDD

5V
LTC1799CS5
V+

0.1F
5k

OUT

GND

OSCIN
22.1

SET DIV
20MHz
SUPERVISOR
5V

0.1F

14k
102k

0.1F

2200pF

10k

10k

VCC25 VCC3 VCCA


SYSTEM RST#
RT

100pF

22.1

RST
MMBT3904

LTC1726EMS8-2.5
WT

GND

PGD/RB7
PGC/RB6
RB5
RB4
RB3
OSCOUT RB2
RB1
INT/RB0
RX/RC7
TX/RC6
MOSI/RC5
MISO/RC4
SCK/RC3
RC2
RC1
MCLR
RC0

WDI

WT

RE2
RE1
RE0

EN
5V
DIS
OPT

VDD
2N7002

PRE
Q

PRE
Q

VCC
D

CLR

RD7
RD6
RD5
RD4
RD3
RD2
RD1
RD0
VDD

RA5
RA4/ISO PWR SHDN
USB TXE#
USB WR CLK
USB RXF#
USB RD CLK#
1.5k

CLK
GND

CLR

VCC
RESET VIA USB

5V

RC7/RX
RC6/TX
RC5/MOSI
RC4/RISO
RC3/SCK
RC2
RC1
RC0
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0

USB
COMMAND

49.9k
IN-CIRCUIT
PROGRAMMING
PORT

475
USB RXF#

RB7
RB6
RB5/CS
RB4
RB3
RB2
RB1/LATCH
RB0/EXCITATION

SPI BUS

INDICATORS
5V

5V

+
475
PROCESSOR
DATA BUS

5V

RC2

+
475

RC1

475
RC0

USB RD
CLK#

74HC74PW

74HC74PW
Q

VCC

VDD
RA5
RA4
RA3
RA2
RA1
RA0

AN112 F08b

CLK
GND

5V

0.1F
SYS
22.1 10MHz

10M

NC7SP17P5X

Figure 8b. Microcontroller and Reset

an112f

AN112-6

Application Note 112


0.1F

475

0.1F

5V

USB5V

0.1F

10F
6.3V

0.1F

USB5V
0.1F

PROCESSOR
DATA BUS

AVCC VCC VCC VCCIO


USBDM
D7
D6
USBDP
D5
D4
FT245BM
D3
D2
RSTOUT#
D1
EECS
D0

DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0

USB_RD_CLK#
USB_WR_CLK
USB_TXE#
USB_RXF#

RD#
WR
TXE#
RXF#
10k
22.1

XTIN

SW/WU
TEST
PWREN#
RST#
AGND GND GND

USB5V
LTC6905CS5-96
V+

47pF

USB-B
CONNECTOR

0.1F USB5V

3V3VOUT

XTOUT

0.1F

47pF

1.5k

10k

EEDATA

USB5V
10k

22.1k

EESK

48MHz
10k

1
2
3
4

22.1k

47pF

10k

VCC

DO

CS

VSS

CLK

2.21k

DI

93LC46BT-1/OT
EE
EN
DIS

AN112F08c

OUT

GND
SET

DIV

Figure 8c. USB Interface (for Development Only)

Firmware Description
The complete rmware code listing is in Appendix C. The
code for this circuit is designed to be a good starting point
for an actual product. Data is displayed to a PC via an
FTDI FT242B USB interface IC. The PC has FTDIs Virtual
Com Port drivers installed, allowing control through any
terminal program. Data for all channels is continuously
displayed to the terminal, and simple text commands
control program operation.
A timer interrupt is called 1000 times per second. It controls the pulse generators and ADC, and stores the ADC
readings to an array that can be read at any time. Thus if
the main program is reading the buffer, the most out-ofdate any reading will be is 1ms.
Automatic calibration routines are also included. Two
functions store a zero reading and a full-scale reading for

all channels, including the calibration voltages applied to


channels 6 and 7, to nonvolatile memory. These are subsequently used to calibrate out the initial gain and offset
errors as well as temperature dependent errors. The entire
procedure is to apply zero volts to all inputs and issue a
command to store the zero calibration, then apply 1.25V
to all inputs and issue a command to store the full-scale
calibration. Note that this is no more complicated than a
basic functionality test that would be part of any manufacturing process. The 1.25V factory calibration source can
be from a voltage calibrator, or from a selected golden
LT1790-1.25 that is kept at a stable temperature.
A digital lter is also included for testing purposes. The
lter is a simple exponential IIR (innite impulse response)
lter with a constant of 0.1. This reduces the noise seen
in the readings by a factor of 10.
an112f

AN112-7

Application Note 112


Measurement Details
To take a reading from a given channel, the processor must
apply the excitation to the transformer, wait for the voltage
signal to settle out, take a reading with the ADC, and then
remove the excitation. This is driven by an interrupt service routine that is called once every millisecond. Refer to
Appendix C for the code listing. Figure 9 shows the digital
signals, excitation pulse, and clamp voltage at the ADC input
along with the C code that performs these operations.3

Individual channels are enabled by loading an 8 bit byte


with one bit set high into the 74HC574 latch.
Note that the excitation is applied after 8 bits of the
LTC1867 data are read out. This is perfectly acceptable,
since there is no conversion taking place and all of the
data in the LTC1867 output register is static. Depending on
the specic timing of the processor being used, excitation
may be applied before reading any data, in the middle of
reading data, or after reading the data but before initiating
a conversion. If the serial clock is very slow1MHz for
instance, applying excitation before reading any data would
result in the excitation being applied for 16s which is too
long. The only constraint is that the voltage at the ADC
input must have enough time to settle properly and that
the excitation is not left on for too long. Figure 10 shows
the same signals over the entire interrupt service routine.
There are similar analog signals at each transformer and
the other LTC1867 inputs.

output_high (CS);

output_low (EXCITATION);

lowbyte = spi_read (0);

delay_us (delay);

output_high (EXCITATION);

highbyte = spi_read (LTC1867CONFIG[j]);

output_high (LATCH);
output_low (LATCH);
output_low (CS);

output_d (LATCHWORD [j]);

AN112 F09

Figure 9. Pulse Generator and ADC Sequencing

Adding More Channels


There are lots of ways to add more channels to this circuit. Figure 11 shows a 64 channel concept. Figure 11
decodes the 64 channels into eight banks of eight channels using 74HC138 address decoders. The selected bank
corresponds to one LTC1867 input that is programmed
through the SPI interface. The additional analog multiplexing is done with 74HC4051 8:1 analog switches. A single
74HC4051 feeding each LTC1867 input gives 64 inputs.
The LTC1867 is still a great choice in high channel count
applications, rather than a single channel ADC, because
it is good idea to break up multiplexer trees into several
stages to minimize total channel capacitance. The LTC1867
takes care of the last stage. And with a maximum sample
rate of 200ksps, it can digitize up to 200 channels at the
maximum 1ksps limitation of the sense transformer. Thats
a lot of batteries.
3Sometimes a jack-of-all-trades is exactly what you need. A high speed

i = 7;

i = 6;

i = 5;

i = 4;

i = 3;

i = 2;

i = 1;

i = 0;

AN112 F10

digital designer would never dream of trading a good logic analyzer for
a mixed-signal oscilloscope to test signal integrity across a complicated
backplane. And its 100MHz analog channels pale in comparison to a good
four channel, half-gig scope. But for testing a circuit with a microcontroller
and data converters up to a few megasamples per second, a good mixed
signal oscilloscope is the master of the trade.

Figure 10. ISR Scanning 8 Channels

an112f

AN112-8

Application Note 112


74HC4051
X

A
B
C
INH

X0
X1
X2
X3
X4
X5
X6
X7

10k
10k

74HC138
A
B
C
LTC1867_CH7
LTC1867
INPUTS

EXCITATION

G1
G2A
G2B

74HC14

2N3904

4.7k

10F

VN2222

Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7

10k
10k
74HC14

CH63

6 ADDITIONAL
CIRCUITS PER
BANK
2N3904

4.7k

LTC1867_CH0
CHANNEL
SELECTION
WITHIN BANK
74HC138N
BANK SELECTION
(FOLLOWS SELECTED
LTC1867 INPUT)
EXCITATION

A
B
C
G1
G2A
G2B

Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7

74HC4051
X

A
B
C
INH

10k
10k

A
B
C
EXCITATION

G1
G2A
G2B

CH56

60 ADDITIONAL CIRCUITS

X0
X1
X2
X3
X4
X5
X6
X7

74HC138

CH56+
10F

VN2222

6 ADDITIONAL
BANKS

CH63+

74HC14

2N3904

4.7k

10F

VN2222

Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7

10k
10k
74HC14
4.7k
VN2222

CH7+
CH7

6 ADDITIONAL
CIRCUITS PER
BANK
2N3904

CH0+1
10F
CH01
AN112 F11

Figure 11. 64-Channel Concept

an112f

AN112-9

Application Note 112


REFERENCES
1. Williams, Jim, Transformers and Optocouplers Implement Isolation Techniques, Isolated Temperature Measurement, pp.116-117. EDN Magazine (January 1982)

5. Sheingold, D. H., Transducer Interfacing Handbook,


Isolation Ampliers, pp. 81-85. Analog Devices Inc.
(1980)

2. Williams, Jim, Isolated Temperature Sensor, LT198A


Data Sheet. Linear Technology Corporation (1983)

6. Williams, Jim, Signal Sources, Conditioners and Power


Circuitry, 0.02% Accurate Instrumentation Amplier with
125 VCM and 120dB CMRR, pp. 11-13. Linear Technology
Corporation, Application Note 98 (November 2004)

3. Dobkin, R. C., Isolated Temperature Sensor, LM135


Data Sheet. National Semiconductor Corporation (1978)
4. Williams, Jim, Isolation Techniques for Signal Conditioning, Isolated Temperature Measurement, pp.1-2.
National Semiconductor Corporation, Application Note
298 (May 1982)

an112f

AN112-10

Application Note 112


APPENDIX A
A Lot of Cut Off Ears and No Van Goghs
Things That Dont Work
The battery stack problem has been around a long
time. Various approaches have been tried, with varying
degrees of success. The problem appears deceptively
simple; technically and economically qualied solutions
are notably elusive. Typical candidates and their difculties
are presented here.
Figure A1 presumably solves the problem by converting
cell potentials to current, obviating the high common
mode voltages. Op amps feed a multiplexed input A/D; the
decoded A/D output presents individual cell voltages. This
approach is seriously awed. Required resistor precision
and values are unrealistic, becoming progressively more
unrealistic as the number of cells in the stack increases.
Additionally, the resistors drain current from the cells, a
distinct and often unallowable disadvantage.
An isolation amplier based approach appears in Figure A2.
Isolation ampliers feature galvanically oating inputs, fully
isolated from their output terminals. Typically, the device
N CELLS

contains modulation-demodulation circuitry and a oating


supply which powers the signal input section4. The amplier
inputs monitor the cell; its isolation barrier prevents battery stack common mode voltage from corrupting output
referred measurement results. This approach works quite
well but, requiring an isolation amplier per cell, is complex
and quite expensive. Some simplication is possible; e.g.,
a single power driver servicing many ampliers, but the
method remains costly and involved.
Figure A3 employs a switched capacitor technique to
measure individual cell voltage while rejecting common
mode voltage. The clocked switches alternately connect
the capacitor across its associated cell and discharge
it into an output common referred capacitor.5 After a
number of such cycles the output capacitor assumes the
cell voltage. A buffer amplier provides the output. This
arrangement rejects common mode voltages but requires
many expensive high voltage switches, a high voltage level
shift and nonoverlapping switch drive. More subtly, switch
leakage degrades accuracy, particularly as temperature
4See reference 5 for details on isolation ampliers.
5Old timers amongst the readership will recognize this conguration as a
derivative of the venerable reed switched ying capacitor multiplexer.

N AMPLIFIERS

MULTIPLEXER

A/D

DECODE

DATA
OUTPUT

N CELLS,
GND REFERRED

AN112 FA01

N AMPLIFIERS

Figure A1. Unworkable Scheme Suppresses High Common Voltages by Converting Cell Potentials
to Current. Circuit Decodes Amplier Outputs to Derive Individual Cell Voltages. Required
Resistor Precision and Values are Unrealistic. Resistors Draw Current from Cells
an112f

AN112-11

Application Note 112


N ISOLATION
AMPLIFIERS

N CELLS

ISOLATION
AMPLIFIER

ISOLATION BARRIER

POWER IN
FLOATING
POWER
SUPPLY
POWER COMMON

AMP

POWER DRIVER

FLOATING INPUT
BATTERY
STACK

OUTPUT

DEMODULATOR
FLOATING COMMON

MODULATOR

AN112 FA02

OUTPUT COMMON

ISOLATION AMPLIFIER
(DETAIL)

ISOLATION
AMPLIFIER

N CELLS

N ISOLATION
AMPLIFIERS

Figure A2. Isolation Ampliers Galvanically Floating Input Eliminates Common Mode Voltage Effects.
Approach Works, but is Complex and Expensive Requiring Isolation Amplier per Cell

an112f

AN112-12

Application Note 112


rises. Optically driven switches, particularly those available as conveniently packaged LED driven MOSFETS, can
simplify the level shift but expense, voltage breakdown
and leakage concerns remain6.

N SWITCH-CAP
SECTIONS
N CELLS
OUT

Switch related disadvantages are eliminated by Figure A4s


approach. Each cells potential is digitized by a dedicated
A/D converter. A/D output is transmitted across an isolation barrier via a data isolator (optical, transformer). In its
most elementary form, each A/D is powered by a separate,
isolated power supply. This isolated supply population is
reducible, but cannot be eliminated. Constraints include
cell voltage and the A/Ds maximum permissible supply
and input common mode voltages. Within these limitations,
several A/D channels are serviceable by one isolated supply. Further renement is possible through employment of
multiplexed input A/Ds. Even with these improvements,
numerous isolated supplies are still mandated by large
battery stacks. Although this scheme is technologically
sound, it is complex and expensive.

OUTPUT
COMMON

BATTERY
STACK

OUT

SWITCH
DRIVE
LEVEL
SHIFT

OUTPUT
COMMON
OUT

AN112 FA03

OUTPUT
COMMON

N CELLS
N SWITCH-CAP
SECTIONS

Figure A3. Switched Capacitor Scheme Rejects Common Mode


Voltage but Requires High Voltage Switches, Nonoverlapping
Drive and Level Shift. Switch Leakage Degrades Accuracy.
Optically Driven Switches Can Simplify Level Shift but
Breakdown and Leakage Issues Remain

6An optically coupled variant of this approach is given in Reference 6.

ISOLATED
SUPPLY DRIVE
ISOLATION
BARRIER
N CELLS

N A/D SECTIONS
ISOLATED
SUPPLY

POWER
SUPPLY

TO OUTPUT
COMMON
REFERRED LOADS
DATA
ISOLATOR

A/D

DATA OUT
OUT COMMON

ISOLATED
SUPPLY
BATTERY
STACK

DATA
ISOLATOR

A/D

DATA OUT
OUT COMMON

ISOLATED
SUPPLY

A/D

DATA
ISOLATOR

DATA OUT
OUT COMMON
AN112 FA04

N CELLS

N A/D SECTIONS

ISOLATION
BARRIER

Figure A4. A/D per Cell Requires Isolated Supplies and Data Isolators. Multiplexed Input A/Ds
can Minimize A/D Usage. Isolated Supply Population is Reducible, but Cannot be Eliminated
an112f

AN112-13

Application Note 112


APPENDIX B
A Floating Output, Variable Potential
Battery Simulator
Battery stack voltage monitor development is aided by a
oating, variable potential battery simulator. This capability
permits accuracy verication over a wide range of battery
voltage. The oating battery simulator is substituted for a
cell in the stack and any desired voltage directly dialed out.
Figure B1s circuit is simply a battery-powered follower
(A1) with current boosted (A2) output. The LT1021 reference and high resolution potentiometric divider specied
permits accurate output settling within 1mV. The composite
amplier unloads the divider and drives a 680F capacitor
to approximate a battery. Diodes preclude reverse biasing

2 9V

1 9V

+
+

the output capacitor during supply sequencing and the


1F-150k combination provides stable loop compensation. Figure B2 depicts loop response to an input step;
no overshoot or untoward dynamics occur despite A2s
huge capacitive load. Figure B3 shows battery simulator
response (trace B) to trace As transformer clamp pulse.
Closed-loop control and the 680F capacitor limit simulator
output excursion within 30V. This error is so small that
noise averaging techniques and a high gain oscilloscope
preamplier are required to resolve it.

18V

+
9V
75k*
50k

18V

IN

TRIM THIS VALUE


FOR THIS VOLTAGE

TRIM
LT1021 OUT
GND
10.000V

BAT85
18V

100k**

1k

A1 LT1012

* = 1% METAL FILM RESISTOR


** = ESI DP-1311 KELVIN-VARLEY DIVIDER

OUTPUT

A2 LT1010
1F
150k

9V
1N4001

+
680F
AN112 FB01

Figure B1. Battery Simulator Has Floating Output Settable Within 1mV.
A1 Unloads Kelvin-Varley Divider; A2 Buffers Capacitive Load

an112f

AN112-14

Application Note 112

A = 5V/DIV
0.5V/DIV
B = 50V/DIV
NOISE AVERAGED

20ms/DIV

AN112 FB02

Figure 2B. 150k-1F Compensation Network Provides Clean


Response Despite 680F Output Capacitor

2s/DIV

AN112 FB03

Figure 3B. Battery Simulator Output (Trace B) Responds to


Trace As Transformer Clamp Pulse. Closed-Loop Control and
680F Capacitor Maintain Simulator Output Within 30V. Noise
Averaged, 50V/Division Sensitivity is Required to Resolve
Response

APPENDIX C
Microcontroller Code Listing
The microcontroller code consists of three les:
Battery_monitor.c contains the main program loop, including calibration and temperature correction, and support
functions.

Interrupts.c is the code for the timer2 interrupt that drives


the transformer excitation and controls the LTC1867
ADC.
Battery monitor.h contains various denes, global variable
declarations and function prototypes.

an112f

AN112-15

Application Note 112


/*******************************************************************************
battery_monitor.c
Six Channel Battery Monitor with continuous gain and offset
correction. Includes a factory calibration feature. On first power up,
apply zero volts to all inputs, allow data to settle, and type o.
Next apply 1.25V to all inputs, allow data to settle, and type p.
This calibrates the circuit, and it is ready to run.
Offset correction technique:
Present offset correction = init_offset[7] - voltage[7]
Hotter = less counts on voltage[7] so correction goes POSITIVE,
so ADD this to voltage[i]
voltage[i] = voltage[i] - init_offset[i] + present_offset
Slope correction Technique:
Initial slope = init_fs[6] - init_offset[7] counts per 1.25V
Present slope = voltage[6] - voltage[7] counts per 1.25V
Keyboard command summary:
a: increment conversion period (default is 1ms)
z: decrement conversion period
s: increment by 10
x: decrement by 10
d: increment pulse-convert delay (default is 2us)
c: decrement pulse-convert delay
f: increment pulse-convert delay by 10
v: decrement pulse-convert delay by 10
n: Calculate voltages for display
m: Display raw ADC values
t: Echo text to terminal so you can insert comments into
data that is being captured. Terminate with !
k: Disable digital filter
l: Enable digital filter
o: Store offsets to nonvolatile memory
p: Store full-scale readings to nonvolatile memory
Written for CCS Compiler Version 3.242
Mark Thoren
Linear Technology Corporation
January 15, 2007
*******************************************************************************/
#include battery_monitor.h
#include interrupts.c
void main(void)
{
int8 i;
unsigned int16 adccode;
float temp=0.0, offset_correction, slope, slope_correction;
initialize();
rx_usb();
print_cal_constants();

// Initialize hardware
// Wait until any character is received
// display calibration constants before starting.

while(1)
{
if(usb_hit()) parse(); // get keyboard command if necessary
for(i=0; i<=7; ++i)
// Read raw data first
{
readflag[i] = 1;
// Tell interrupt that were reading!!
an112f

AN112-16

Application Note 112


adccode = data[i];
readflag[i] = 0;
temp = (float) adccode; // convert to floating point
if(filter)
// Simple exponential IIR filter
{
voltage[i] = 0.9 * voltage[i];
voltage[i] += 0.1* temp;
}
else
{
voltage[i] = temp;
}
}
if(calculate) // Display temperature corrected voltages
{
// Calculate Corrections.
// offset correction is stored CH7 reading minus the present reading
offset_correction = read_offset_cal(7) - voltage[7];
// Slope correction is the stored slope based on initial CH6 and CH7
// readings divided by the present slope. Units are (dimensionless)
slope_correction = (float) read_fs_cal(6) (float) read_offset_cal(7); // Initial counts/1.25V
slope_correction = slope_correction / (voltage[6] - voltage[7]);
for(i=0; i<=5; ++i)
// Print Measurement Channels
{
// Units on slope are volts per ADC count
slope = 1.25000 / ((float) read_fs_cal(i) // Inefficient but
(float) read_offset_cal(i)); // we are RAM limited
// Correct for initial offset and temperature dependent offset.
// units on temp are ADC counts
temp = voltage[i] - (float) read_offset_cal(i) + offset_correction;
// Correct for initial slope
temp = temp * slope;
// Units on temp is now volts
// Correct for temperature dependent slope
temp = temp * slope_correction;
busbusy = 1;
printf(tx_usb, %1.5f, , temp);
busbusy = 0;
}
busbusy = 1;
// Print to terminal
printf(tx_usb, %1.6f, %1.1f, , slope_correction, offset_correction);
busbusy = 0;
}
else // Display raw ADC counts
{
for(i=0; i<=7; ++i)
{
busbusy = 1;
// Print to terminal
printf(tx_usb, %1.0f, , voltage[i]);
busbusy = 0;
}
}
busbusy = 1;
printf(tx_usb, D:%d, P:%d\r\n, delay, period); // print period and delay
busbusy = 0;
// Delay and blink light
delay_ms(100); output_high(PIN_C0); delay_ms(100); output_low(PIN_C0);
} //end of loop
} //end of main
an112f

AN112-17

Application Note 112


/*******************************************************************************
Parse keyboard commands
arguments: none
returns: void
*******************************************************************************/
void parse(void)
{
char ch;
switch(rx_usb())
{
case a: period += 1; break;
// increment period
case z: period -= 1; break;
// decrement period
case s: period += 10; break;
// increment by 10
case x: period -= 10; break;
// decrement by 10
case d: delay += 1; break;
// increment pulse-convert delay
case c: delay -= 1; break;
// decrement pulse-convert delay
case f: delay += 10; break;
//

by 10
case v: delay -= 10; break;
//

by 10
case n: calculate = 1; break; // Calculate voltages
case m: calculate = 0; break; // Display raw values
case t:
// Echoes text to terminal so you can insert comments into
{
// data that is being captured. Terminate with !
busbusy = 1;
printf(tx_usb, enter comment\r\n);
while((ch=rx_usb())!=!) tx_usb(ch);
tx_usb(\r);
tx_usb(\n);
busbusy = 0;
} break;
case k: filter = 0; break;
// Disable filter
case l: filter = 1; break;
// Enable Filter
case o: write_offset_cal(); break;
// Store offset to nonvolatile mem.
case p: write_fs_cal(); break;
// Store FS to nonvolatile mem.
}
setup_timer_2(T2_DIV_BY_16,period,8);
// Update period if necessary
}
/*******************************************************************************
write offset and full-scale calibration constants to non-volatile memory
arguments: none
returns: void
*******************************************************************************/
void write_offset_cal(void)
{
int i;
unsigned int16 intvoltage;
for(i=0; i<=7; ++i)
{
intvoltage = (unsigned int16) voltage[i];
// Cast as unsigned int16
write_eeprom (init_offset_base+(2*i), intvoltage >> 8); // Write high byte
delay_ms(20);
write_eeprom (init_offset_base+(2*i)+1, intvoltage); // Write low byte
delay_ms(20);
}
}
void write_fs_cal(void)
{
int i;
unsigned int16 intvoltage;
for(i=0; i<=7; ++i)
{
an112f

AN112-18

Application Note 112


intvoltage = (unsigned int16) voltage[i];
// Cast as unsigned int16
write_eeprom (init_fs_base+(2*i), intvoltage >> 8); // Write high byte
delay_ms(20);
write_eeprom (init_fs_base+(2*i)+1, intvoltage); // Write low byte
delay_ms(20);
}
}
/*******************************************************************************
read offset and full-scale calibration constants from non-volatile memory
arguments: none
returns: void
*******************************************************************************/
unsigned int16 read_offset_cal(int channel)
{
return make16(read_eeprom(init_offset_base+(2*channel)),
read_eeprom(init_offset_base+(2*channel)+1));
}
unsigned int16 read_fs_cal(int channel)
{
return make16(read_eeprom(init_fs_base+(2*channel)),
read_eeprom(init_fs_base+(2*channel)+1));
}
/*******************************************************************************
Print calibration constants (raw ADC counts)
arguments: none
returns: void
*******************************************************************************/
void print_cal_constants(void)
{
int i;
for(i=0; i<=7; ++i)
{
printf(tx_usb, ch%d offset: %05Lu, fs: %05Lu\r\n
, i, read_offset_cal(i),read_fs_cal(i));
}
}
/*******************************************************************************
Interface to the FT24BM USB controller
usb_hit()
arguments: none returns: 1 if data is ready to read, zero otherwise
rx_usb() arguments: none returns: character from USB controller
tx_usb() argments: data to send to PC, returns: void
*******************************************************************************/
char usb_hit(void)
{
return !input(RXF_);
}
char rx_usb(void)
{
char buf;
while(input(RXF_)) {} // Low when data is available, wait around
output_low(RD_);
delay_cycles(1);
buf=input_d();
output_high(RD_);
return(buf);
}
an112f

AN112-19

Application Note 112


void tx_usb(int8 value)
{
while(input(TXE_))
//Low when FULL, wait around
{
}
output_d(value);
output_high(WR);
delay_cycles(1);
output_low(WR);
input_d();
}
/*******************************************************************************
Hardware initialization
arguments: none
returns: void
*******************************************************************************/
void initialize(void)
{
output_high(ISO_PWR_SD_); //turn on power
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_CONFIG);
CKP = 0; // Set up clock edges - clock idles low, data changes on
CKE = 1; // falling edges, valid on rising edges.
output_low(I2C_SPI_);
output_low(AUX_MAIN_); // SPI is only MAIN
setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,period,8);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
output_low(PIN_C0);
delay_ms(100);
output_high(PIN_C0); // Turn off LEDs
output_high(PIN_C1);
output_high(PIN_C2);
// I/O Initialization
input(RXF_);
input(TXE_);
output_high(RD_);
output_low(WR);
delay_ms(100);
output_low(CS);
delay_us(5);
output_high(CS);
// Turn on interrupts (only one)
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
}

an112f

AN112-20

if(!busbusy) // If main() is using the bus, do nothing.


{
for(j=0; j<=7; ++j)
{
output_d(LATCHWORD[j]);
// Place excitation data on the bus
output_high(LATCH);
// Latch in data
output_low(LATCH);
output_low(CS);
// Enable LTC1867 serial interface
highbyte = spi_read(LTC1867CONFIG[j]); // Read out high byte.
// Acquisition begins on 6th falling clock edge
output_high(EXCITATION);
// Apply transformer excitation
delay_us(delay);
// Wait for analog signal to settle
lowbyte = spi_read(0);
// Finish reading data. Input is also settling
// During this time.
output_high(CS);
// Start conversion!!!
output_low(EXCITATION);
// Remove excitation. One instruction cycle is plenty
// of analog hold time
if(!readflag[j]) data[j] = make16(highbyte, lowbyte); // Dont write if main() is reading!!
// This is a simple anti-collision technique. The worst
// case latency is a single reading, or 1ms.
}//end of for loop
}//end of if(!busbusy)
}// end of ISR

/*******************************************************************************
Timer 2 Interrupt
This interrupt service routine does all of the work of controlling transformer
excitation and controlling the LTC1867.
*******************************************************************************/
#int_TIMER2
// Tell compiler that this is the Timer 2 ISR
TIMER2_isr()
{
static int8 ledstatus;
int8 j, highbyte, lowbyte;
if(++ledstatus == 0x80) output_low(LED);
// Blink light every 256 calls
if(ledstatus == 0x00) output_high(LED);

Application Note 112

an112f

AN112-21

Application Note 112


/*******************************************************************************
battery_monitor.h
defines, global variables, function prototypes
*******************************************************************************/
#include <16F877A.h>
// Standard header
#device adc=8
#use delay(clock=20000000) // Clock frequency is 20MHz
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
#define SPI_CONFIG SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4
// 5MHz SPI clk when
// master clk = 20MHz
//#fuses NOWDT,RC, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, LVP, NOCPD, NOWRT
// This is less confusing - set up configuration word with #rom statement
//
Bit
13 12
11
10
9
8
7
6
5 4
3
2
1
0
// Function CP -- DEBUG WRT1 WRT0 CPD LVP BOREN - - PWRTEN# WDTEN FOSC1 FOSC0
//
#rom 0x2007 = {0x3F3A}
/////////////////////////////////////
// Battery Monitor Project Defines //
/////////////////////////////////////
// Global variables
int16 data[8];
// Raw data from the LTC1867
int8 readflag[8];
// Tells ISR that main is reading data, do not write
int1 busbusy = 0;
// Tells ISR that main is talking on the bus
int1 calculate = 1;
// Send calculated voltages to terminal when asserted
int1 filter = 1;
// Enables digital filter when asserted
unsigned int8 period = 40; // Period between reads
unsigned int8 delay = 2;
// Additional settling time after applying excitation
float voltage[8];
// Holds floating point calculated voltages
// Non-volatile memory base addresses for calibration constants
#define init_offset_base 0
#define init_fs_base 16
// First, define the SDI words to be sent to the LTC1867
// All are Single ended, unipolar, 4.096V range.
#define LTC1867CH0
0x84
#define LTC1867CH1
0xC4
#define LTC1867CH2
0x94
#define LTC1867CH3
0xD4
#define LTC1867CH4
0xA4
#define LTC1867CH5
0xE4
#define LTC1867CH6
0xB4
#define LTC1867CH7
0xF4
// Excitation enable lines. Write this to the 574 register
// before enabling excitation pulse.
#define EXC0
0x01
#define EXC1
0x02
#define EXC2
0x04
#define EXC3
0x08
#define EXC4
0x10
#define EXC5
0x20
#define EXC6
0x40
#define EXC7
0x80

an112f

AN112-22

Application Note 112


// Now define two lookup tables such that the excitation signal lines up with
// the selected LTC1867 input.
byte CONST LTC1867CONFIG [8] = {LTC1867CH1, LTC1867CH2, LTC1867CH3, LTC1867CH4,
LTC1867CH5, LTC1867CH6, LTC1867CH7, LTC1867CH0};
byte CONST LATCHWORD [8] = {EXC6, EXC5, EXC4, EXC3, EXC2, EXC1, EXC0, EXC7};
//Pin Definitions
#define EXCITATION
#define LATCH
#define LED

PIN_B0
PIN_B1
PIN_C1

#define
#define
#define
#define
#define
#define
#define

PIN_A0
PIN_A1
PIN_A2
PIN_A3
PIN_A4
PIN_A5
PIN_B5

RD_
RXF_
WR
TXE_
ISO_PWR_SD_
LCD_EN
CS

#define AUX_MAIN_
#define I2C_SPI_
#byte SSPCON
#byte SSPSTAT
#bit CKP
#bit CKE

// Enables excitation to the selected channel


// 74HC573 latch pin
// Spare blinky light

PIN_E1
PIN_E2

= 0x14
= 0x94
= SSPCON.4
= SSPSTAT.6

// Function Prototypes
void parse(void);
void write_offset_cal(void);
void write_fs_cal(void);
unsigned int16 read_offset_cal(int channel);
unsigned int16 read_fs_cal(int channel);
void print_cal_constants(void);
char usb_hit(void);
void initialize(void);
void tx_usb(int8 value);
char rx_usb(void);

an112f

Information furnished by Linear Technology Corporation is believed to be accurate and reliable.


However, no responsibility is assumed for its use. Linear Technology Corporation makes no representation that the interconnection of its circuits as described herein will not infringe on existing patent rights.

AN112-23

Application Note 112

an112f

AN112-24

Linear Technology Corporation

LT 0307 PRINTED IN USA

1630 McCarthy Blvd., Milpitas, CA 95035-7417


(408) 432-1900 FAX: (408) 434-0507

www.linear.com

LINEAR TECHNOLOGY CORPORATION 2007

You might also like