Developments in Battery Stack Voltage Measurement

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 cell’s
voltage. Obtaining this information in the presence of the
high “common mode” voltage generated by the battery
stack is more difficult 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 difficulty 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 1’s 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 2’s “stack” of series connected cells is more complex
and presents problems. The voltmeter must be switched
between the cells to determine each individual cell’s
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 3’s 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
T1’s 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 section’s
conclusion. The pulse generator produces a 10μs wide
event (Trace A, Figure 5) at a 1kHz repetition rate. The
pulse generator’s low impedance output drives T1 via a
10k resistor and also triggers the delayed pulse generator.
T1’s primary (Trace B) responds by rising to a value representing the sum of VDIODE + VBATTERY along with a small
fixed error contributed by the transformer. T1’s 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 T1’s clamped value. After a
number of pulses C1 assumes a DC level identical to T1’s
primary clamp voltage. A1 buffers this potential and feeds
differential amplifier 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
fidelity over temperature and clamp voltage range. The
carefully designed transformer specified yields Figure 6’s
waveforms. Primary (Trace A) and secondary (Trace B)
clamping detail appear at highly expanded vertical scale.
Clamping flatness is within millivolts; trace center aberrations derive from S1 gate feedthrough. Tight transformer
clamp coupling promotes good performance. Circuit accuracy at 25°C 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 floating,
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 =
T1’S 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 T1’s 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, 10μs, 1kHz
= 2N3904 MATCH VBE
1mV AT 200μA
= VN2222
PULSE GENERATOR
T1 = PULSE ENGINEERING PA2100NL OR PA2101NL
* = 1% RESISTOR
DIODE
10k*
SAMPLING VOLTMETER
(SAMPLE-HOLD)
Q1
T1
•
•
VBATTERY
12V
+
+
10μF
+
S1
1/4 CD4016
6.34M*
A1
LTC1050
10k
+
A2
LT1789
–
C1
0.001μF
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 3’s Concept. Error Subtraction Terms
Include Q3 Compensating Q1 and Resistor/Gain Corrections for Errors in T1’s Clamping Action. Q1-Q3 Transistors
Replace Diodes for More Consistent Matching. Q2 Prevents T1’s Negative Recovery Excursion from Influencing 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
2μs/DIV
AN112 F05
Figure 5. Figure 4’s Waveforms Include Pulse Generator
Input (Trace A), T1 Primary (Trace B), 74HC123 ⎯Q⎯2 Delay
Time Output (Trace C) and S1 Control Input (Trace D). Timing
Ensures Sampling Occurs When T1 is Settled in Clamped State
2μs/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 VBE’s, substituted for diodes, provide more consistent initial matching
and temperature tracking. The 10μF capacitor at Q1 maintains low impedance at frequency, minimizing cell voltage
movement during the sampling interval. Finally, synchronously switched Q2 prevents T1’s negative recovery excursion from deleteriously influencing S1’s operation.
This approach’s advantage is that its circuitry does not
encounter high common mode voltages—T1 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 7’s 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 channel’s 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 benefit of processor driven operation is elimination
of Figure 4’s 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 channel’s 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 channel’s
–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 LT®1790-1.25. The
LTC®1867 internally amplifies 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 configured 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 25°C. Drift drops to less than
50ppm/°C—almost 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
•
10μF
4.7k
VN2222
RB0/EXCITATION
74HC00
5V
IN
OUT
LT1790-1.25
OC
G
G
5V
0.1μF
2.2μF
ADC_CH0
ADC_CH1
ADC_CH2
ADC_CH3
ADC_CH4
ADC_CH5
ADC_CH6
ADC_CH7
10μF
1μF
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
10μF
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.1μF
0.1μF
VDD
5V
LTC1799CS5
V+
0.1μF
5k
OUT
GND
OSCIN
22.1Ω
SET DIV
20MHz
SUPERVISOR
5V
0.1μF
14k
102k
0.1μF
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
D
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
Q
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.1μF
SYS
22.1Ω 10MHz
10M
NC7SP17P5X
Figure 8b. Microcontroller and Reset
an112f
AN112-6
Application Note 112
0.1μF
475Ω
0.1μF
5V
USB5V
0.1μF
10μF
6.3V
0.1μF
USB5V
0.1μF
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.1μF USB5V
3V3VOUT
XTOUT
0.1μF
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 firmware 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 FTDI’s 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 filter is also included for testing purposes. The
filter is a simple exponential IIR (infinite impulse response)
filter with a constant of 0.1. This reduces the noise seen
in the readings by a factor of √⎯1⎯0.
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 specific 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 slow—1MHz for
instance, applying excitation before reading any data would
result in the excitation being applied for 16μs 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. That’s
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
10μF
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+
10μF
VN2222
•• 6 ADDITIONAL
•• BANKS
•
CH63+
74HC14
2N3904
4.7k
10μF
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
10μF
CH0–1
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 Amplifiers,” 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 Amplifier 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 Don’t 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 qualified solutions
are notably elusive. Typical candidates and their difficulties
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 flawed. 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 amplifier based approach appears in Figure A2.
Isolation amplifiers feature galvanically floating inputs, fully
isolated from their output terminals. Typically, the device
N CELLS
contains modulation-demodulation circuitry and a floating
supply which powers the signal input section4. The amplifier
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 amplifier per cell, is complex
and quite expensive. Some simplification is possible; e.g.,
a single power driver servicing many amplifiers, 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 amplifier 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 amplifiers.
5Old timers amongst the readership will recognize this configuration as a
derivative of the venerable reed switched “flying 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 Amplifier 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 Amplifier’s Galvanically Floating Input Eliminates Common Mode Voltage Effects.
Approach Works, but is Complex and Expensive Requiring Isolation Amplifier 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 A4’s
approach. Each cell’s 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/D’s maximum permissible supply
and input common mode voltages. Within these limitations,
several A/D channels are serviceable by one isolated supply. Further refinement 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
floating, variable potential battery simulator. This capability
permits accuracy verification over a wide range of battery
voltage. The floating battery simulator is substituted for a
cell in the stack and any desired voltage directly dialed out.
Figure B1’s circuit is simply a battery-powered follower
(A1) with current boosted (A2) output. The LT1021 reference and high resolution potentiometric divider specified
permits accurate output settling within 1mV. The composite
amplifier unloads the divider and drives a 680μF capacitor
to approximate a battery. Diodes preclude reverse biasing
2 × 9V
1 × 9V
+
+
the output capacitor during supply sequencing and the
1μF-150k combination provides stable loop compensation. Figure B2 depicts loop response to an input step;
no overshoot or untoward dynamics occur despite A2’s
huge capacitive load. Figure B3 shows battery simulator
response (trace B) to trace A’s transformer clamp pulse.
Closed-loop control and the 680μF capacitor limit simulator
output excursion within 30μV. This error is so small that
noise averaging techniques and a high gain oscilloscope
preamplifier 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
1μF
150k
–9V
1N4001
+
680μF
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 = 50μV/DIV
NOISE AVERAGED
20ms/DIV
AN112 FB02
Figure 2B. 150k-1μF Compensation Network Provides Clean
Response Despite 680μF Output Capacitor
2μs/DIV
AN112 FB03
Figure 3B. Battery Simulator Output (Trace B) Responds to
Trace A’s Transformer Clamp Pulse. Closed-Loop Control and
680μF Capacitor Maintain Simulator Output Within 30μV. Noise
Averaged, 50μV/Division Sensitivity is Required to Resolve
Response
APPENDIX C
Microcontroller Code Listing
The microcontroller code consists of three files:
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 defines, 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 we’re 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); // Don’t 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