Download 1-Wire bus

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Transistor–transistor logic wikipedia , lookup

Index of electronics articles wikipedia , lookup

CMOS wikipedia , lookup

Power MOSFET wikipedia , lookup

UniPro protocol stack wikipedia , lookup

Valve RF amplifier wikipedia , lookup

Power electronics wikipedia , lookup

Surge protector wikipedia , lookup

Resistive opto-isolator wikipedia , lookup

Integrated circuit wikipedia , lookup

Switched-mode power supply wikipedia , lookup

Opto-isolator wikipedia , lookup

Microcontroller wikipedia , lookup

Rectiverter wikipedia , lookup

Bus (computing) wikipedia , lookup

MIL-STD-1553 wikipedia , lookup

Immunity-aware programming wikipedia , lookup

Transcript
FEATURE ARTICLE
by Steve Hendrix
1-Wire in the Real World (Part 1)
The Challenges
Steve explains the challenges of taking a 1-Wire deicing system for small aircraft from a laboratory prototype to a real-world application.The ThermaWing Deice System relies on a proprietary
algorithm requiring tight control of surface temperatures to enable the system to melt ice.
A
s a general aviation enthusiast, cerof milliseconds to a few seconds. Relays
out in “RTCA/DO-178: Software Contified flight instructor, and former U.S.
would clearly be a bad substitute for the
siderations in Airborne Systems and
Air Force flight instructor, I’m always
IGBTs. But, if we could move each indi- Equipment Certification,” but I had neihappy to work on a project that comvidual IGBT out next to the heater conther the plans nor budget for a parallel
bines my two favorite fields. Many years
trols, we could distribute the heat. That effort for another piece of software to
would also reduce the amount of heavy
run in a remote switch module. Thus, I
ago, I was in an aircraft accident when
power wiring, and weight is expensive
needed a way to remotely control the
the small aircraft I was flying was
in any aircraft installation. More
switches and monitor the temperature
brought down by in-flight structural
importantly, we could dissipate the
of the heater surface and the switch
icing. Now I work as an independent
itself (for diagnostics) via a remote comelectrical engineering consultant. Thus, I heat into one of the best heatsinks
imaginable—an aircraft skin with ice
munications link, all without requiring
jumped at the request from what is now
frozen to the other side and belowa local processor and the attendant softKelly Aerospace Thermal Systems to
freezing air blowing past at a couple
ware.
take a deicing system for small aircraft
hundred knots!
from a laboratory prototype into the real
I have considerable experience with
world. Photo 1 shows a sneak peek at
Dallas Semiconductor 1-Wire bus and
the ThermaWing Deice System. A clean
chips, both on a board level in embedWORLD OF BUREAUCRACY
wing is in the protected area, while there
ded systems and on a longer bus of tens
The Federal Aviation Administration
is significant ice accumulation on the
of meters. The 1-Wire protocol and
(FAA) requires an extensive certification
unprotected landing light lens.
some of the early chips were described
process for every piece of software used.
in great detail by Jeff Bachiochi in
I was already planning a software certifiIt quickly became clear that the
“Dallas 1-Wire Devices” (Circuit Celcation effort for the controller, as spelled
electric deicing system required some
lar 105 and 106, 1999). I have
form of distributed switching to
the original Dallas Semiconducspread out the thermal load of
tor promotional 1-Wire weather
the switches. The heat resulting
station, and I have expanded it to
from rapidly switching 7,500 W
include a number of extra temamong six to 12 heaters or more
perature sensors, a barometer, a
is quite substantial. The laborarain gauge, humidity sensors,
tory prototype attempted to do
and more. Based on my experiall of the switching in one box,
ence with the reliability of 1but a brief test simulating a realWire in that application, it was
world operation ended with the
with some trepidation that I
heatsinks hotter than a Texas
introduced the idea of using 1tarmac in the summertime.
Wire in this application.
The power switches were big,
insulated-gate bipolar transistors
(IGBT) because mechanical relays
APPLICATION
lacked ruggedness when they
Reliability is clearly
Photo 1—The protected area covered by the gray heater is clean, while the
were switched rapidly. The sysrequired. Turning a 7,500-W
unprotected landing light lens shows the severity of the icing where the test
tem requirements mandate that
heater on when it should be off
flight took place. (Popsicles fly poorly!) Also note the “nose caps” of ice on
the heaters repeatedly switch at
could do nasty things to an airthe wheel fairings, and the chunks of ice that are falling on the ramp as the
intervals ranging from a few tens
frame. Less obviously perhaps,
unprotected areas of the airframe warm up after landing.
58
Issue 205 August 2007
CIRCUIT CELLAR®
www.circuitcellar.com
turning it off with high current flowing from a highly inductive source (the
alternator) could cause voltage spikes
in hundreds of volts. Such voltage
spikes could do considerable damage
to the electronics or even cause electrical arcing. After switching to my
pilot hat, it was clear that reliability
would be a very high priority.
Accurately sensing the heater’s surface temperature is almost as important
as the switching. The system relies on a
proprietary algorithm requiring tight
control of surface temperatures. The
algorithm makes the system shed ice
from the aircraft skin without melting a
significant quantity of ice, which would
become liquid and run back from the
leading edges where ice forms, to
refreeze in unprotected areas.
Taking a laboratory demonstration out
into the real world also requires some
serious considerations of protection
against voltage spikes and other electrical problems. Although the system specification doesn’t require the electronics
to survive a direct hit from a lightning
bolt, the voltage spike tests in
“RTCA/DO-160E: Environmental Conditions and Test Procedures for Airborne
Equipment” anticipate a near-miss lightning bolt that induces substantial voltage and current for a brief interval.
TEMP-SENSING SWITCH
A number of 1-Wire chips include
some form of internal temperature sensing. I selected a Maxim Integrated Products DS2751 multichemistry battery fuel
gauge for the temperature-sensing section of the remote-switch architecture.[1]
The chip includes an internal temperature sensor with 0.125°C resolution, a
single-ended voltage-sense input with
4.88-mV resolution from 0 to 4.75 V, and
a differential current-sense input intended for use with an external current-sensing resistor over a range of ±64 mV with
a resolution of 15.625 μV. The chip
also includes 32 bytes of lockable EEPROM that could be used to store configuration information.
Our original intent was to laminate
this or a similar 1-Wire chip directly into
each heater to allow us to read the heater
temperature directly without external
analog electronics, and to couple the
EEPROM contents with one specific
www.circuitcellar.com
Figure 1—LED D20 provides the visual indication of heater switching for troubleshooting and R10/D10 provide protection
from incoming transients. Temperature is sensed via REXT, a 100-Ω platinum RTD. The DS2751 voltage sense input confirms and corrects for current variations, while the current-sense input measures the actual voltage developed across the
RTD. Ohm’s law yields the RTD resistance and firmware converts the measured resistance to heater temperature.
heater. This tight coupling would also
allow us to store the heater’s serial
number and other characteristics (i.e.,
total area and nominal resistance) to
help adjust applied power and diagnostics. Although this approach was elegant, it exposed the chip and interconnections directly to the hazards of
impact damage on the leading edges of
airfoil surfaces.
Therefore, I chose to sense temperature using a rugged 100-Ω platinum
resistance temperature device (RTD)
laminated into the heater, with the
chip cowering safely inside the potting
in the switch enclosure mounted
inside the wing. Turning the chip’s
logic upside down, I chose to use the
voltage-sense input to confirm current
through the RTD and use the currentsense input to measure the resulting
voltage. The VDD of 5 V nominal
excites the series string of R40, R41,
and the RTD (Rext) (see Figure 1). The
RTD resistance can range from 84 to
133 Ω over the temperature range of
interest. Thus, the voltage measured
at the top of R41 is applied to a total
resistance ranging from 10,084 to
10,133 Ω. If the firmware blithely
assumes 10,100 Ω and divides the
sensed voltage at VIN by this resistance, the computed current will be in
error by no more than 0.3% due to the
change in RTD resistance. If we needed more accuracy, a bit of algebra
would correct this error, but the error
is so small relative to the other errors
CIRCUIT CELLAR®
(notably the use of 1% resistors) that it
is negligible. However, we can use the
VIN voltage to correct for any reasonable
variation in VDD. We also could have
used a four-wire sensing arrangement to
correct for resistance in the wires to the
RTD, but the wires are short and the
resistances are small and predictable,
so we simply allow for that resistance
and apply a correction in firmware.
By applying a nominal 5 V to the
12,100-Ω string (2 kΩ plus 10 kΩ plus
the 100-Ω RTD), we achieve a nominal
current of 413 µA. At the coldest operating point of –40°C, the RTD resistance of 84 Ω produces a sense voltage of
34.7 mV. At the hottest operating point
of 85°C, the RTD produces 133 Ω and
55 mV. The 15.625-µV resolution
yields 1,300 measurable steps between
the endpoints for a resolution of just
over 10 steps per degree centigrade.
Linearity is good, but not perfect. The
system spec, however, requires good
accuracy at only a single point (freezing)
and allows degraded accuracy as the
temperature moves away from freezing.
The software provides for a single-point
offset calibration to achieve the required
accuracy at freezing, with the offset constant stored in the DS2751E’s EEPROM.
The calibration data is thus tightly coupled to a specific heater and RTD. Note
the combination of surge protection and
antialias filtering provided by the combination of R42/C42/R43/C43.
To allow for the rapid and repeated
reading of a single temperature while
Issue 205 August 2007
59
one heater is in operation, I placed a
Maxim Integrated Products DS2409
MicroLAN U10 between the main 1Wire bus and the DS2751E U40.[2] With
all the temperature-sensing sections
similarly behind such a coupler, the
software can select a single sensor on
the bus and repeatedly read the temperature without going through the complete addressing protocol for each reading. This is a useful technique in any 1Wire design that requires bursts of
readings from a specific sensor. More
importantly, the DS2409 also provides a
single bit of digital output, which the
system uses to enable the IGBT driver
and turn on the heater. The digital output is an open-drain output that can
sink current to ground and drive an
optocoupler (see Figure 1). The balance
of the circuit beyond the optocoupler
is proprietary and includes transient
protection and the IGBT driver. Isn’t it
amazing how this heater power switching, the primary function of the circuit,
appears as almost an afterthought to all
the ancillary functions, such as temperature sensing?
1-WIRE BUS PROTECTION
Maxim Integrated Products touts
the fact that 1-Wire chips can run
from “parasite power.” That is, each
chip includes a diode and enough
capacitance to maintain a workable
internal supply voltage by stealing
power from the data line during its
logic-one state. When the data line is
high, the current flows through the
diode to power the chip and charge the
capacitor. When the data line is low,
the reserve charge in the capacitor is
sufficient to run the chip. The protocol guarantees that the data line
should never go low for longer than
the “ride-through” of the capacitor,
except in the case of a deliberate reset
signal. This scheme works well when
only a few chips use parasite power
and the data line is completely contained within a circuit board or other
well-controlled enclosure.
Protection is required to prevent
transients from damaging either the
master or the slaves where the data
line travels through hostile territory.
Protection components limit the
amount of energy that can transfer on
60
Issue 205 August 2007
Figure 2—A simple and robust microcontroller to 1Wire bus interface. R1 limits the available fault current
into or out of the microcontroller pin, while dual-diode
D1 clamps the pin voltage between the supply rails. R2
provides a very weak bus pull-up when the microcontroller is not providing an active pull-up, such as during
microcontroller reset and firmware start-up.
the data line. With multiple slaves
attempting to share the data line, reliability suffers. Because this application
required regulated power within each
enclosure for other purposes, I chose to
ignore the parasite-power capability
and provided separate power directly to
each chip on its dedicated VDD pin.
Having eliminated the requirement
to provide parasite power, we can
afford more resistance in the data line.
The data line just has to supply
enough current to charge the cable
capacitance plus the chip-input capacitance of 50 to 60 pF per chip during
transitions and enough steady current
to feed the 1 to 5 µA of leakage at
each chip’s input. A simple 1-kΩ resistor R1, where the 1-Wire data line
departs each enclosure, limits the
amount of fault current. Schottky
clamp diodes D1 to the supply rails
then limit the maximum voltage that
can be applied to the sensitive inputs
of the 1-Wire chips and the microcontroller. Figure 2 shows the complete 1Wire connection between the microcontroller port pin and the external
bus. Although it is simple, the protection allows the hardware to survive
applications of full aircraft bus voltage
(even if it is reversed) for an extended
time and short spikes of a few hundred volts with no hardware damage.
Also, note the 1,000-pF capacitor C1
from the data line to ground. This
capacitor aids in slew-rate limiting
and helps absorb fast transients until
the clamp diodes have time to switch,
but it looks a little odd between the
port pin and the resistor. You might
expect to see such a filter arrangement
reversed with the resistor between the
port pin and the capacitor. But we
CIRCUIT CELLAR®
must be aware of what we’re trying to
filter. We are primarily concerned
with keeping transients induced on
the line from getting to the electronics. Reducing the slew rate of the signal we place onto the line is a secondary consideration and helps reduce
radiated emissions. Here, the limited
current available from the microcontroller port (approximately 20 mA)
limits the slew rate to about 20 V per
microsecond, preventing significant
radiated energy above a handful of
megahertz while still keeping signaltransition times under 1 µs.
But wait. R2 provides the 1-Wire
bus passive pull-up, and it’s shown as
100 kΩ. Maxim Integrated Products
recommends a pull-up of 5 kΩ. With
several chips on the bus, we could
have leakage current in the tens of
microamps, and our pull-up would
have a volt or more of drop, so the
positive swing of the data line would be
severely limited. Even worse, the rise
time of the data line with this weak passive pull-up will run into the hundreds
of microseconds—and we need to be
able to distinguish between pulses of
approximately 1, 60, and 120 µs. Just
how can we make this work reliably?
I’m gl-a-a-a-a-a-d you asked that
question. By making the hardware and
the software sing together, we can do
magic. Here’s how.
BITS AND PIECES
First, bury the archaic idea that a
microcontroller output pin must be
either high or low, or even that it
must be either an output or an input.
Virtually all modern microcontrollers
have the capability to float an output
pin. I have implemented 1-Wire masters using both the Freescale Semiconductor 68HC family and the
Microchip Technology PIC family,
both of which have this capability and
have made very nice 1-Wire masters
for me. Usually, the documentation
describes this as changing the direction of the pin from Output to Input
mode, but that mode of thinking is for
the digital-only guys. We need to put
on our analog hats and see an output
port as a complementary pair of MOSFETs that can be controlled independently. After looking at the implemenwww.circuitcellar.com
Photo 2—The driver’s 1-kΩ impedance interacts with cable capacitance to produce a very slow R-C waveform. The
slow edge rates can combine with noise to cause false edges. The long delay to reach valid logic levels causes
serious timing problems with the 1-Wire protocol.
tation of a general-purpose port pin
(watch out for special cases, such as port
A on the PIC family), we see that the pin
is always an input pin and the controller
can read the state of the pin at any time.
We configure a pin as an output by storing a zero into a TRISx register on a PIC
or a one into a DDRx on a Freescale
Semiconductor microcontroller. Making
the pin an output does not change the
input function. It simply guarantees that
one or the other drive transistors will be
turned on depending on whether you
have written a one or a zero to that port
pin’s data register. Thus, we can very rapidly change a port pin between driving
low, floating, and driving high.
The 1-Wire protocol is defined so
each unit, master, or slave asserts the
bus low to actively place data on the
bus and allows the bus to float high via
a passive pull-up when it is not actively driving the bus. The master is also
allowed to actively drive the bus high
at certain times in order to augment
the passive pull-up and provide additional parasite power.
Dallas Semiconductor almost got this
Save Up To 60% On
Electronic Components
Exciting New Mini-Boards
Wide Range Including,
• Real Time Clocks (DS1307)
• Memory Cards
• Power Supplies
• DC Motor, Stepper Motor
and More
ONL
$6.9 Y
0
Powerful New ATMega Controller
• Includes ATMega128
Microcontroller
• High-Speed Operation
• Heaps of I/O
• In-Circuit Programming
• Ideal Embedded Controller
ON
$28 LY
.90
Save Heaps on Components
ONL
$4.9 Y
0
We carry a wide range of
Integrated Circuits, Microcontrollers, Capacitors, LED's
and LCD's.
All at very competitive prices.
We are your one-stop shop for Microcontroller Boards,
PCB Manufacture and Electronic Components.
www.futurlec.com
www.circuitcellar.com
CIRCUIT CELLAR®
Issue 205 August 2007
61
Photo 3—The master attempts to drive the line low at T. The reflection on the 500′ cable returns at 1.6 μs, as
marked by the first cursor, and returns a second time after another 1.6 μs, at the second cursor.
right. A number of e-mail interest groups
have sprung up around the 1-Wire bus
and their promotional “1-Wire Weather
Station” in particular. A number of
extended discussions on these groups
have focused on the reliability problems
with extended cable lengths, as well as
the ramifications of branches in the line.
One common thread in most of these
discussions is a general susceptibility to
reflections developed in long cables.
Take a look at the actual reflections
in real cables in a controlled environment. Photo 2 shows the 1-Wire waveform with our protected driver
attempting to access a bus containing a
single device with a 500′ tail consisting
of a box of Cat5E cable. The dominant
feature is the extremely slow R-C time
constant as the 1-kΩ driver attempts to
discharge the cable capacitance. The
waveform takes approximately 15 µs to
fall past the guaranteed-zero threshold
of 0.8 V. The 1-Wire slave must see this
valid zero before it begins the 15-µs
timing to the sampling point. That
delay is going to wreak havoc with the
synchronization between master and
slave. Reflections? What reflections?
In my college days, the late Capt.
62
Issue 205 August 2007
Grace Hopper gave a talk on the history of computers, the development of
COBOL, and other topics. One thing
that has always stuck with me came
when she promised to pass out nanoseconds to each student since none of us
had ever seen a nanosecond. She passed
out pieces of AWG #30 wire-wrap wire
cut to exactly 11.8″, the distance light
or any electromagnetic wave travels in a
nanosecond. Although the illustration
was graphic (and lasting), there’s a slight
inaccuracy: propagation at the speed of
light applies only in a vacuum. In real
wires or on real circuit boards, speed is
slowed by a factor that depends on the
surrounding medium—the insulation on
a wire, the core material on a PCB. If we
were to assume a factor of about 0.66
the round trip on a 500′ wire (1,000′
total) should take about 1.5 µs. See
those tiny steps right at the beginning of
the falling waveform?
Photo 3 expands the tiny steps for better visibility. The first step lasts 1.6 µs.
When the reflection returns, the voltage
steps down again as the attempt to drive
the line low is reinforced by the reflection. After another 1.6-µs passes, this
reflected step has made another round
CIRCUIT CELLAR®
trip, and we see another (less pronounced) step in the waveform. By the
third round trip, the reflections are just
barely visible and they essentially die
out completely after that.
A 1-Wire master with sufficient drive
to provide parasite power to the slaves
will, of course, provide much faster
edges as well—if the slaves do not further burden the line. But even in this
extreme case, with 500′ of cable, the
reflections are completely finished within 3 µs, well before there should be any
sampling going on. With old-time, full
5-V logic, we should have plenty of
noise margin against any noise picked
up on that long line. So why do long
lines cause such a problem?
As noted in the documentation of the
DS2480 used in 1-Wire masters, the
Maxim Integrated Products master drives
the bus low to produce a 1-µs pulse, then
releases the bus and watches to see if a
slave replies with a zero or a one.[3] A
slave replying with a zero will hold the
bus low for at least 60 µs, whereas a
slave replying with a one allows the passive pull-up to pull the bus high within
15 µs. Because the recommended 5-kΩ
pull-up provides a relatively slow rise
when asked to charge up the capacitance
of a significant amount of cable, their
master watches the line to see if it’s rising. If the line rises above a defined
threshold voltage of approximately 1.2 V,
the master assumes the slave is returning a “one” and switches to an active
pull-up to “help” the line return to a
high (logic one) state. All was well and
good until users started deploying 1-Wire
weather stations with a couple hundred
feet of cable.
With a significant cable length, echoes
occur. But more importantly, the cable
capacitance smears out the signal edges
and the cable itself picks up noise.
Because of the reduced-threshold voltage
of 1.2 V, these unwanted signals can fool
the active pull-up into driving the line
high while a slave attempts to drive the
line low. Such contention continues
through the sample point of the master,
yielding an undefined voltage when the
bit is sampled. Thus, very frequent
errors occur, to the extent that communication essentially ceases.
With the bus protection in place, there
is a 1-kΩ resistor between each active
www.circuitcellar.com
device and the bus. In the worst-case
contention situation, the master drives
high while the slave is driving low. Both
ends then see a fairly reasonable 2-kΩ
load resistance and the bus goes to a
well-defined voltage at one-half the supply voltage. However, even though the
slave is driving the line to ground to
present a logic zero, the master is driving
the line high with the active pull-up on
the same side of the protection resistors
as the sampling point. The master reads
a logic one even though the slave is presenting a logic zero. All we need to provoke the situation is 1.2 V of noise,
minus the residual voltage on the stillsettling cable at the sample point. Thus,
our noise margin is reduced to much less
than the 1.2-V threshold of the “helper”
detector, rather than the full 3.5-V
(70% of VDD) logic-one threshold we
might expect from other digital inputs.
Now, we have the information needed
to build a truly robust master that can
drive any reasonable length of cable.
I’m out of space for this month, so I’ll
give you time to think about how this
all fits together. Next month, we’ll see
64
Issue 205 August 2007
how a more detailed view of an output
pin enables us to write a firmware 1Wire master that avoids some of the
noise-susceptibility problems that can
make the Maxim Integrated Products 1Wire masters appear to be less than
robust. We’ll then build on that foundation to see how neatly 1-Wire fits into the
application. I
Steve Hendrix, P.E., CFIAI, lives with his
wife Kathy and their five children ages
three through 21 next to Cuyahoga Valley National Park in Ohio. When he isn’t
busy hiking with them in the Park, leading Boy Scouts, foster parenting, or ringing handbells, he runs Hx Engineering,
LLC. Steve has designed software and
hardware for projects including Space
Station Freedom, vibration analysis,
IEEE-488 bus hardware, biomedical sensing (including wireless EEG, EKG, and
EMG recorders), industrial instrumentation, and phototherapy equipment.
PROJECT FILES
To download code, go to ftp://ftp.
CIRCUIT CELLAR®
circuitcellar.com/pub/Circuit_Cellar/
2007/205.
REFERENCES
[1] Maxim Integrated Products,
“DS2751 Multichemistry Battery
Fuel Gauge Datasheet,” 0201005,
http://datasheets.maxim-ic.com/en
/ds/DS2751.pdf.
[2] Maxim Integrated Products, “DS2409
MicroLAN Coupler Datasheet,”
111901, http://datasheets.maximic.com/en/ds/DS2409.pdf.
[3] Maxim Integrated Products, “Serial 1Wire Line Driver with Load Sensor,”
DS2480B, http://datasheets.maximic.com/en/ds/DS2480B.pdf.
SOURCE
DS2409 MicroLAN coupler, DS2480B
serial 1-Wire line driver, and DS2751E
gauge
Maxim Integrated Products, Inc.
www.maxim-ic.com
www.circuitcellar.com
FEATURE ARTICLE
by Steve Hendrix
1-Wire in the Real World (Part 2)
The Solutions
Steve continues explaining how he turned a laboratory prototype into an electrically powered
ice protection system for aircraft. He describes how he built a 1-Wire master and then covers some of the application structures that take full advantage of the 1-Wire bus.
L
ast month, I discussed some of the
challenges associated with taking a laboratory prototype into the real world
and turning it into what is now the
ThermaWing system, which is an electric ice protection system for small to
medium aircraft. This month, I’ll put
the pieces together and describe how to
build a 1-Wire master by making the
hardware and firmware play nicely.
Then, I’ll look at some of the application
structures that build on that foundation
to take full advantage of the 1-Wire bus
(and the available slave chips) to address
many of the application challenges.
FIRMWARE TECHNIQUES
Before I dive into the code, I will
explain some coding techniques so you
can understand the listings. I use slightly unconventional techniques that
make for more readable and maintainable code. The techniques also make it
easier to get it right the first time.
I’ve learned to write my firmware (and
all of my design documentation) with
the “cement mixer syndrome” in mind.
That comes from a former boss who
insisted that I always document my
work just in case I get hit by a cement
mixer and somebody else has to continue
onward. As a consultant, I see the value
in this approach every time I’m called in
to solve a problem where the original
developers are long gone. I sometimes
get a call to do the next revision of a
product that I designed for a company
two acquisitions and a couple of years
ago. The value of clear documentation
becomes obvious at that point as well!
I have a few standard definitions
that I automatically insert into either
42
Issue 206 September 2007
a header file or directly into the C
source, depending on the size of the
project. C language defaults the common variable types to signed, but my
need for signed variables in embedded
designs is fairly rare. First, I create
shorthand definitions for unsigned
variables by prefixing a lowercase u,
yielding uchar, uint, and ulong
types. My lengthof macro is safer
than sizeof to determine index limits for arrays, and it is lower maintenance than declaring a macro or constant for each size. It also works on
multiply-dimensioned arrays, arrays of
structures, and so on. If I declare
ulong A [4] [7] [123] [12], then
lengthof (A [1] [2]) returns 123,
the correct number of entries for the
next index.
In any project involving communication between two devices, you will
need to pick variables and structures
apart into bytes. The lobyte, hibyte,
loword, and hiword macros provide an
intuitive and portable way to extract
pieces of variables up to 32 bits long. As
a bonus, most compilers allow them on
the left-hand side of an assignment. To
adapt these macros when changing
between Little Endian and Big Endian
processors, you need only to swap the
0 and 1 subscripts. The offsetin
macro uses the compiler to derive the
exact memory offset to locate a particular item within a structure in a way
that is guaranteed by the language to be
consistent with whatever address assignment the compiler has generated. The
macro is highly useful when you need to
generate a numeric EEPROM address to
be passed to read and write routines.
To allow temporarily suspending
interrupts during a critical code section,
the SuspendInts and RestoreInts
macros provide a consistent way to
save and restore the interrupt state
and help keep the bookkeeping
straight. Note the unmatched opening
brace in SuspendInts. The opening
brace enables you to declare a local
auto variable where you save the
interrupt context and forces the compiler to help you match it with the
similarly unmatched closing brace in
RestoreInts. You can circumvent
Listing 1—Here are some 1-Wire family codes. Note the use of a C language enum construction rather than
a more conventional series of #define declarations.
typedef enum
{
fcDS2401
fcDS2423
fcDS2409
fcDS2450
fcDS2438
fcDS18B20
fcDS2751
fcUnknown
}
FamilyCodeT;
=
=
=
=
=
=
=
=
0x01,
0x1D,
0x1F,
0x20,
0x26,
0x28,
0x51,
0xFF,
CIRCUIT CELLAR®
www.circuitcellar.com
Listing 2—Check out the 1-Wire bit-level routines. Four macros handle all the microcontroller-specific
manipulations. The ReadBit and WriteBit routines control the timing with very short delay loops
that must be adjusted for clock speed and processor efficiency. Above this level all of the code is completely portable.
// Low-level 1-Wire Access
#define OneWireSet()
{OneWire = 1; OneWireTris = 0;}
#define OneWireClr()
{OneWire = 0; OneWireTris = 0;}
#define OneWireFloat()
{OneWireTris = 1;}
#define OneWirePullup()
{OneWireSet (); OneWireFloat ();}
// OneWire Bus Write a bit
// This routine specifically uses only the LSB of B
void OneWireWriteBit (uchar B)
{
uchar i; // used for delay loops; adj as needed for processor & clock rate
OneWireSet ();
SuspendInts;
OneWireClr ();
if (B & 1)
{
for (i = 5; i; —i);
OneWireSet ();
for (i = 55; i; —i);
}
else
{
for (i = 55; i; —i);
OneWireSet ();
for (i = 5; i; —i);
}
OneWireFloat ();
RestoreInts;
}
// OneWire Bus Read a bit
uchar OneWireReadBit (void)
{
uchar i; // used for delay loops; adj as needed for processor & clock rate
uchar Result;
OneWireSet ();
// Ensure bus recovery time
SuspendInts;
// Timing is critical here
OneWireClr ();
// Leading edge of bit time
for (i = 2; i; —i);
// Delay
OneWirePullup ();
// Assist the passive pullup
for (i = 8; i; —i);
// Delay
Result = OneWire;
// Sample state of bit
OneWireTris = 0; OneWire = 0;OneWireTris = 1; // sample time marker
// useful for troubleshooting
for (i = 42; i; —i);
// Wait for end of read slot
OneWirePullup ();
RestoreInts;
// End of critical section
return Result;
}
// OneWire Bus Reset
// Return true in case of an error (no devices, or bus shorted)
bool OneWireReset (void)
{
uint i; // used for delay loops; adj as needed for processor & clock rate
uchar LastLow;
OneWireSet ();
// Drive bus high to start
for (i = 240; i; —i);
// Delay
SuspendInts;
// Critical timing
OneWireClr ();
// Send out reset pulse
for (i = 160; i; —i);
// Delay
OneWirePullup ();
// Recover to high state
for (i = 160; i; —i)
// Watch for presence pulse
if (OneWire == 0) break;
RestoreInts;
// Done with critical timing
if (!i)
// Handle exception case
{
printf (“No 1-wire devices\n\r”);
(Continued)
www.circuitcellar.com
CIRCUIT CELLAR®
the protection by branching out of the
construction in the middle, but being
a good structured programmer, I
wouldn’t do such a thing, would I?
The C language enum declaration is
underused. I use it in the downloadable
1-Wire code to provide a number of useful identifiers. For instance, Listing 1
shows how I declare the family codes,
which comprise a portion of each 1-Wire
serial number. Other declarations in
the downloadable code provide readable identifiers for each of the 1-Wire
ROM commands and function commands. I abhor the all-too-common
lists of #define declarations to provide readable identifiers for port assignments, hardware registers, and so on.
When I declare an enumerated type
that might be used as an array index
or I have to iterate over the type or
check limits, I declare the enum with
an extra member specifying the number of valid entries, like I do with the
Branches member of this enum that
supports iteration:
typedef enum {brMain, brAux, Branches}
BranchT;
I can then iterate over the group with a
construction (i.e., i = 0; i < Branches;
++i) and the compiler keeps everything neatly sorted out, even if I add
or remove items in the enum.
Finally, I have a pet peeve against
those who declare arrays using a plural name for the identifier. Although
it’s natural to call it “Devices” at the
point of declaration because the programmer is thinking of a collection of
information about all the “Devices,”
the declaration appears once, whereas
the name is used many times in the
code. At those numerous points of
use, I am almost always referring to a
single device, such as Device [3],
which is then readily pronounced
“Device 3.” That is much closer to
the real meaning than “Devices 3,”
which doesn’t make grammatical
sense. I reserve the plural form of the
identifier for the count of how many
entries are present in the array, most
often when the number of valid
entries changes dynamically (the
lengthof macro takes care of the
static case). Thus, I can iterate across
Issue 206 September 2007
43
the array (i = 0; i < Devices; ++i).
This consistency in variable naming
helps keep everything straight.
LOW-LEVEL 1-WIRE ROUTINES
Listing 2 shows my implementation
of the low-level routines to read or write
a single bit on the 1-Wire bus. All code
listings in this article are for the HITECH Software PICC-18 compiler, but
they also port directly to other readily
available embedded C compilers. If you
are compiling for a Big Endian processor,
such as one from Freescale Semiconductor, change the declarations for
high/low byte/word (as noted in the
comments) and check the compiler
options to be sure that an enum will
compile to a 1-byte object. There is no
embedded assembly language, although
the lowest-level routines include a couple of timing loops that must be adjusted for a specific clock rate and processor. Above the bit level, everything is
completely generic.
Note that I cannot publish the complete application code. As a work for
hire, it belongs to my client. The code
I show here reflects my toolkit-level
routines that I incorporated into the
“work for hire” in the interest of saving my client time and money.
Sending a bit from the master to a
slave is straightforward and matches
the datasheet description. That is, for
a “1” bit, drive the line low for at
least 1 µs and drive it active high
within 15 µs. For a “0” bit, drive the
line active low for at least 60 µs and
then active high. In each case, you
must observe the minimum datasheet
time with the line high before driving
the line low again to start the next bit.
To receive a bit, however, I deviate
slightly from the datasheet recommendations and overcome the reflection and noise problems I described last
month. The master drives the line low
for 2 µs to generate the start pulse of a
read bit timeslot. It then drives the bus
high for 1 µs and finally releases the line
to a floating state by setting the pin as
an input. If the slave returns a “0” bit,
the bus is momentarily in contention
and at an intermediate (invalid) voltage, but neither the master nor a slave
looks at the bus during this interval
(see Photo 1). The slave is driving the
44
Issue 206 September 2007
Listing 2—Continued.
return 1;
}
// Wait for all devices to end presence pulse, with debounce
for (i = LastLow = 500; i && i + 20 > LastLow; —i)
{
if (OneWire == 0) LastLow = i;
}
OneWirePullup ();
// Clean finish
if (!i)
// Handle another exception case
{
printf (“1-wire bus stuck low\n\r”);
return 1;
}
return 0;
// Reset completed okay
}
line low during this time. As soon as
the master releases the line, the active
slave vigorously returns the bus to a
valid low state, which remains stable
throughout the master’s sampling time.
If, on the other hand, the slave returns
a “1” bit, the master has already stabilized the line at a high-level voltage (see
Photo 2). When the bus is released, it is
already high and stable long before the
master samples the state. You can gain
the rapid settling time of a bipolar driver
while still retaining the ability to share
the bus among multiple units. Simply
use a passive pull-up and active-low
drivers, with only the master providing
an active-high drive at exactly the right
times and never being fooled by a line
reflection or noise.
This active pull-up method will corrupt a bus reset. Therefore, it is not
usable during a reset. Many units can
listen on the bus during a reset. If the
master attempts to drive the line high
and then releases it while a slave is
still asserting the line low, other
slaves may see the signal as the start
of a read bit slot and things get completely wrapped around the axle. So,
for reset, you must rely completely on
the passive bus pull-up, resulting in
the waveform shown in Photo 3. The
slower bus-rise time causes no problem for reset because the reset opera-
Listing 3—Here are some byte transfers on the 1-Wire bus. Bytes are transferred LSB first. The Write routine
shifts bits out of its LSB, while the Read routine enters bits into the MSB, shifting the previously read bits right
as each new bit arrives.
///////////////////////////////////////////////////////////////
// OneWire Write Byte
void OneWireWrite (uchar B)
{
uchar i;
for (i = 8; i; —i)
{
OneWireWriteBit (B);
B >>= 1;
}
}
///////////////////////////////////////////////////////////////
// OneWire Read Byte
uchar OneWireRead (void)
{
uchar i;
uchar Result;
for (i = 8; i; —i)
{
Result >>= 1;
if (OneWireReadBit ()) Result |= 0x80;
}
return Result;
}
CIRCUIT CELLAR®
www.circuitcellar.com
!#$%
’“7”•–O—˜™7šG›Q•qœ
ZžŸk qž¡7š¢š£™Zž
576#89;:/<-=>?<#@4AB:C 6*D&E F#C 6GE @-H=94=>/6#I
J 8K4L8<&IMI6&8N:KO8QPE R8K-RS&E JMTVU >I6&C
PXWZY7=[\=6&8E <&C^]&]&_-`#aPX= Tcb C <4=S
_-`#aPX=d[OA-6*e-E Rd6-=XfgE >Shi Ukj?l WN_-mn7=d[
PXWZY7=[ b _ jNU =[ b _ jNU _-`&aPo=[qp p p r
sQt4u^vxw HQy-@&E zOy*6{C K4LE R|<&@<&C 9}6#8
~ so€V‚„ƒo…Q† ‡qˆ ‰QŠ-‹OŒ/‹O  Ž*(dŽOŒ‘ ‹O
!#" $&%('*) +-,/. $&$*0 )*1 2$43
ZZZDVL[WRROVFRP
Photo 1—Note the bus contention for 6 µs as the master provides an active pull-up. The slave returns the line to a solid
“zero” at the sampling time marked by the right cursor, and the slow rise thereafter is provided by the weak passive pullup. The bus is finally returned to a solid “one” condition as the master terminates the bit slot with an active pull-up.
tion is much rarer and longer than the
normal bit slots.
BYTES AND MESSAGES
With the foundation in place, you
can send a bit of either value and read
a bit returned by a slave. Because the
1-Wire protocol performs almost all
transfers as 8-bit bytes (least-significant bit first), the extension to reading
and writing bytes is straightforward
(see Listing 3). Messages are built of
bytes, with some examples of specific
message types shown in the code available on the Circuit Cellar FTP site.
ENUMERATION
The 1-Wire search algorithm is not as
straightforward. All 1-Wire slaves have a
unique 64-bit address and they all support the 1-Wire search algorithm.
Because 1-Wire was designed to support
the unannounced appearance and disappearance of units that may or may
not have ever been seen previously, you
need a way to search for an unknown
device. Even if (and that’s a highly
unlikely “if”) you could test 1 million
addresses per second, a brute-force
www.circuitcellar.com
search of the 64-bit address space
would take almost 600 kiloyears. That’s
a trifle longer than most of my designs
will tolerate! The clever 1-Wire search
algorithm supports searching the entire
address space in such a way that completely enumerating all devices present
on the bus can be done in less than 25 ms
per attached device. The algorithm is
described in the datasheets. More subtle points aren’t always obvious.
The heart of the 1-Wire search algorithm, along with the nitty-gritty
exception cases that Murphy’s Law
always throws in my face in the real
world, are shown in Listing 4. In a
nutshell, the master broadcasts a command to all units on the bus,
announcing that you are searching for
addresses. The master then provides
two read slots. Each device replies
with its first address bit in the first
read slot, and the complement in the
second read slot. Because the bus is
passive high and active low, the zeros
always win out in case there are two
devices with different address bits. If
the first read slot returns a zero, there
is some device present and active on
CIRCUIT CELLAR®
Issue 206 September 2007
45
the algorithm is simple in principal,
it’s dastardly difficult to get exactly
right. The difficulty for me was in the
bookkeeping required to ensure that I
traversed every valid branch of the
address tree without either getting
stuck repeatedly traversing the same
address or missing a branch.
After bench-testing the routines
with a limited sample set of slave
devices, I spent several days troubleshooting the wiring in the test aircraft before discovering that adding a
device over here could disrupt the traversal in such a way that another
device over there would disappear
from the search. The clue that finally
pinpointed the search problem was
that attaching unit X would always
cause unit Y to disappear, even when
they were on separate buses. (The
application implementation used four
microcontroller port pins to provide
four electrically independent buses.)
Photo 2—The active pull-up provided by the master guarantees a clean reading at the sampling point shown by the cursor.
the bus whose address has a zero in this
position. If the second read slot (the
complement of the address bit) returns a
zero, an active device has a one in this
bit position. If you look at the two bits
another way, the master can detect four
separate cases: 00 means at least one
active device has a “zero,” and another
has a “one” in this bit position. 01
means all active devices have a “zero” in
this bit position. 10 means all active
devices have a “one” in this bit position.
11 means no active devices are present
on the bus (an error condition unless a
device has been disconnected from the
bus in the middle of the search).
The master then answers the 25 cent
(2-bit) sequence by writing either a
“zero” bit or a “one” bit to the bus. All
slaves whose address matches the written bit remain active. All others go to
sleep and do not further participate in
the search. The master then issues two
more read slots to search on the next
address bit, repeating for each of the
64 bits. At the end of the search, the
master has discovered the complete
64-bit address of one device on the bus.
The complete downloadable code
implements the search with a Reset
46
Issue 206 September 2007
Search routine, which establishes the
initial conditions, and a SearchNext
routine, which returns one complete
address each time it is called. Although
DISTRIBUTED CONFIGURATION
As I stated in my introduction, a
key issue favoring the 1-Wire bus is a
desire to avoid extra software-certification efforts to support different configurations. Therefore, I tried as much as
possible to localize any information that
Photo 3—This is a reset waveform. Note the nice square 480-µs minimum reset pulse from the master, terminated
by an active pull-up. This is followed by the presence pulse from one or more slaves with the slow-rising, trailing
edge provided by the weak passive pull-up.
CIRCUIT CELLAR®
www.circuitcellar.com
would be specific to a particular model.
The system design was generic to
virtually all small aircraft, but there
were small differences that I would
have to accommodate for different aircraft makes and models. System limitations combined with the proprietary
ice-removal algorithm to dictate the
constraints on the minimum and maximum size of any one heater. Any aircraft model has a total amount of iceprotection area, as well as mechanical
constraints on how that area can be
serviced. For instance, a landing light
can’t be covered up by a heater, which
means one aircraft may require six,
nine, or up to 14 separate heaters for
bigger aircraft. The heater characteristics dictate that the resistance of a
heater will be different than another
with different dimensions. The system
measures the heater resistance to
detect shorts, opens, or damage to the
heater, so the software needs to know
the nominal resistance of each heater
for comparison. All the configuration
information could be stored in the
central controller’s nonvolatile memo-
48
Issue 206 September 2007
Listing 4—The core of the algorithm finds a single attached device by serial number. The routine iterates
across the 64 bits of the address using a switch statement to sort out the various conditions possible with zero,
one, or many slaves present on the bus and participating in the search.
///////////////////////////////////////////////////////////////
// Search next device on the 1-wire bus
// Start from SearchSerial and search for next higher address
// Leave SearchSerial set to the found address
void SearchNext (void)
{
uchar Bit;
uchar ZeroDecision;
uchar Result;
ZeroDecision = 0xFF;
if (OneWireReset ())
{
ResetSearch ();
SearchComplete = 1;
return;
}
OneWireWrite (owSearchRom);
for (Bit = 0; Bit < 8 * sizeof SearchSerial; ++Bit)
{
//////////// begin interrupt-blocked section ///////////////
SuspendInts;
Result = OneWireReadBit (); Result <<= 1;
Result += OneWireReadBit ();
switch (Result)
{
case 0: // both bits zero
// differing address bits at this position
if (LastZeroDecision < 8 * sizeof SearchSerial &&
Bit < LastZeroDecision)
{
if (!SearchBit (Bit)) ZeroDecision = Bit;
OneWireWriteBit (SearchBit (Bit));
(Continued)
CIRCUIT CELLAR®
www.circuitcellar.com
ry, but that would mean the controller
could not be generic across all models of
aircraft. Instead, I chose to place the configuration information in the nonvolatile
memory of a Maxim Integrated Products
DS2751 multichemistry battery fuel
gauge, which is used to sense heater
temperature, because it would be permanently attached to a particular heater.
Listing 5 is an excerpt from the code
posted on the Circuit Cellar FTP site.
The code enables you to use a high-level
language construction, such as a C language structure, as an overlay on the
memory space in a DS2751. The DS2751
includes a block of special function registers as well as two banks of uncommitted EEPROM and some static RAM. The
typedef for DS2751RegT enables you to
lay out the internal register arrangement
as a C language structure. The structure
can then be used as a member of a larger
structure that may include an array of
bytes covering EEPROM or other structure members defining specific allocations of variables. Thus, with care, I can
declare structures and regular C language variables within the memory
50
Issue 206 September 2007
Listing 4—Continued.
}
else if (Bit == LastZeroDecision)
{
OneWireWriteBit (1);
SearchBitSet (Bit);
}
else // Bit > LastZeroDecision
{
ZeroDecision = Bit;
OneWireWriteBit (0);
SearchBitClr (Bit);
}
break;
case 1: // all active devices have 0 in this bit position
OneWireWriteBit (0);
SearchBitClr (Bit);
break;
case 2: // all active devices have 1 in this bit position
OneWireWriteBit (1);
SearchBitSet (Bit);
break;
case 3: // there are no active devices on the bus (error)
printf (“\n\rNo dev at bit %d\n\r”, Bit);
ResetSearch ();
SearchComplete = 1;
Bit = 0xFE;
break;
}
//////////// end interrupt-blocked section/////////////////
RestoreInts;
}
if (ZeroDecision == 0xFF) SearchComplete = 1;
LastZeroDecision = ZeroDecision;
printf (“\n\r”);
ShowOneWireSerial (&SearchSerial);
}
CIRCUIT CELLAR®
www.circuitcellar.com
Listing 5—This is a C language construction for the DS2751 registers. This structure was extended in the final
application to include configuration information stored in the DS2751’s EEPROM. The structure declaration supports the use of the offsetin macro, described above, to generate a numeric address for issuance in a 1-Wire
command or to read or write within the DS2751 address space.
typedef struct
{
uchar
uchar
uchar
uchar
uchar
uchar
uchar
uchar
uchar
uchar
uchar
uchar
int
int
int
int
int
int
int
int
int
int
}
DS2751RegT;
Reserved00;
Status;
Reserved02;
Reserved03;
Reserved04;
Reserved05;
Reserved06;
Eeprom;
SpecialFeature;
Reserved09;
Reserved0A;
Reserved0B;
Voltage ; // units of 152.588 µV (±5 V FS)
Current ; // units of 1.953125 µV (±64 mV FS)
CurrAccum; // units of 6.25 µVH (±204.8 mVH FS)
Reserved12;
Reserved14;
Reserved16;
Temperature; // units of 1/256 ºC (±128ºC FS)
Reserved1A;
Reserved1C;
Reserved1E;
map of such an external device.
The primary caveats to this
approach are that the compiler issues
no warning if your structure exceeds
the available memory or if it is misaligned with the actual registers, and
that different compilers may use different physical memory sizes for the
same variable types. All the compilers
I’ve used on small embedded projects,
however, treat a char as 8 bits, an
int as 16 bits, and a long as 32 bits.
Where a variable is larger than 1 byte,
the programmer also needs to be aware
of the allocation strategy used by the
compiler to create multibyte variables.
Such a variable can have the least significant byte at the lowest memory
address or the most significant byte at
the lowest memory address. These
arrangements are commonly referred to
as Little Endian or Big Endian. Processor architecture guides but rarely mandates the choice. Compilers targeting
Freescale Semiconductor processors
typically use Big Endian, while compilers targeting Microchip Technology
processors usually use Little Endian.
As a side note, the technique is
highly useful any time I need to allocate addresses in a separate address
space. I can use this method to allocate
www.circuitcellar.com
space for variables and clean, readable
access to those variables. One example is
EEPROM that is either at a specified
offset within the main address space (as
on the Freescale Semiconductor microcontrollers) or that lives in a completely independent address space (as on the
Microchip microcontrollers). Another is
memory-mapped or even I/O-mapped
registers. Also note that my “offsetin”
macro provides a portable method of converting a structure member’s name into a
numeric address offset to be passed to
the 1-Wire bus, to an EEPROM access
routine, or as a numeric port address.
The deice system application includes
an expanded version of the DS2751’s
structure covering the nonvolatile memory included in the chip. Additional
fields are included there to specify the
resistance, maximum power, actuation
sequence, manufacture date, and other
information pertinent to the switching
of the particular heater. One oddball
configuration item is the total number
of heaters expected in the system.
Unlike the other parameters that are
specific to one heater, this parameter
applies to the system as a whole and not
to any one heater. I decided to store the
expected number of heaters in every
switch and to verify, as the system is iniCIRCUIT CELLAR®
tialized, that all modules agree on the
expected number of heaters. Any disagreement clearly indicates a problem,
whether it’s an installation error or corrupted memory. As long as all the
switches agree on the number of switches that should be present, the controller can signal a fault if the configured number of heaters doesn’t appear
during the search of the 1-Wire bus.
IMPROVEMENTS
The 1-Wire communication protocol
seems to lack a reputation for reliability. With proper techniques in the master end, however, it can be made quite
reliable even on long wires in a hostile
electrical environment. The added benefits of a guaranteed (by Maxim Integrated Products) unique serial number
for traceability and distributed configuration information storage made 1-Wire
an ideal fit for this application. Someday I’ll get one of those “round tuits”
and be able to implement a few of the
dozens of 1-Wire projects that I keep
thinking of as I read the newsgroups! I
Steve Hendrix, P.E., CFIAI, lives with
his wife Kathy and five children, ages
three through 21, next to Cuyahoga
Valley National Park in Ohio. When
he isn’t busy hiking with them in the
Park, leading Boy Scouts, foster parenting, or ringing handbells, he runs
Hx Engineering, LLC. Steve has
designed software and hardware for
various projects: Space Station Freedom, vibration analysis, IEEE-488 bus
hardware, biomedical sensing (including wireless EEG, EKG, and EMG
recorders), industrial instrumentation,
and phototherapy equipment.
PROJECT FILES
To download code, go to ftp://ftp.circuit
cellar.com/pub/Circuit_Cellar/2007/206.
SOURCES
PICC-18 Compiler
HI-TECH Software
www.htsoft.com
DS2751 Multichemistry battery fuel gauge
Maxim Integrated Products, Inc.
www.maxim-ic.com
Issue 206 September 2007
51