* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download 1-Wire bus
Survey
Document related concepts
Transistor–transistor logic wikipedia , lookup
Index of electronics articles 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
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 !#$% 7O7GQq Zk 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 ~ soVo Q q Q-O/O *(dO 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