Parts: 1-Wire temperature sensor (DS1822)

1wire

Download: buspirate.v0d.zip

Dallas/Maxim’s 1-Wire protocol is the most requested addition to the Bus Pirate.  We finally got some 1-Wire parts, and today we’ll demonstrate the DS1822 1-Wire digital thermometer. Grab the datasheet (PDF) and follow along.

This post is accompanied by release v.0d of the Bus Pirate firmware for hardware version 0. This includes the new 1-Wire protocol library, more configuration options, and other improvements.

DS1822 Economy Digital Thermometer (Digikey #DS1822+-ND, $3.87) We found a footprint in the 1-wire library for Eagle on the Cadsoft download page.

The 1-Wire protocol uses a single wire for data transfer, and sometimes power. Data is transferred in time-sensitive ‘slots’ because there isn’t a separate clock to delineate bit periods.

ds1822cct

Bus Pirate
DS1822
SDA
DQ
+5volts Vdd
Ground
GND

The DS1822 connections are shown in the table. We used the Bus Pirate’s 5volt supply to power the DS1822, but it also works at 3.3volts. A resistor (R1, ~5K) holds the bus high.

All 1-Wire commands start with a reset procedure, followed by one of five ROM commands.

Command Description
0x33 READ ROM. Read single device address.
0x55 MATCH ROM. Match device address, followed by 64bit address.
0xCC SKIP ROM. Address all devices together.
0xEC ALARM SEARCH. Search for alarm condition.
0xF0 SEARCH ROM. Part of address enumeration procedure.

ROM commands are described on page 10 of the datasheet. All ROM commands are available as macros in the Bus Pirate 1-Wire library, see (0) for a menu. ROM command macros include the 1-Wire bus reset procedure.

Single device

singli-4501

All 1-Wire devices have a unique 64bit (8 byte) address, and some 1-Wire devices are used exclusively to give electronics a unique tracking number. When a single device is connected to a 1-Wire bus, the READ ROM command will extract its address.

1-WIRE>{ 0x33 r:8 <–command
xxx 1WIRE BUS RESET OK
xxx 1WIRE WRITE: 0x33 <–READ ROM
xxx 1WIRE BULK READ, 0x08 BYTES:
0x22 0x47 0x45 0x22 0x00 0x00 0x00 0x29 <–ID#
1-WIRE>

The command sends a bus reset ({), the READ ROM command (0x33), and reads the 64bit address (r:8, 8 bytes *8bits/byte=64bits).

The first byte (0x22) identifies this as a DS1822 thermometer. The next 6 bytes are unique to this device, and the final byte is a CRC of the previous 7 bytes.

Now we can address the device with the MATCH ROM command and send it further instructions.

1-WIRE>{ 0x55 0x22 0x47 0x45 0x22 0x00 0x00 0x00 0x29 0x44
xxx 1WIRE BUS RESET OK
xxx 1WIRE WRITE: 0x55<–MATCH ROM command
xxx 1WIRE WRITE: 0x22<–start address
xxx 1WIRE WRITE: 0x47
xxx 1WIRE WRITE: 0x45
xxx 1WIRE WRITE: 0x22
xxx 1WIRE WRITE: 0x00
xxx 1WIRE WRITE: 0x00
xxx 1WIRE WRITE: 0x00
xxx 1WIRE WRITE: 0x29
xxx 1WIRE WRITE: 0x44 <–start conversion
1-WIRE>

First, we send the MATCH ROM command (0x55) and the device address (8 bytes).  Next is the CONVERT T command (0x44, datasheet page 11) that starts the temperature conversion.

A second command sequence retrieves the temperature reading from the DS1822.

1-WIRE>{ 0x55 0x22 0x47 0x45 0x22 0x00 0x00 0x00 0x29 0xbe r:9
xxx 1WIRE BUS RESET OK
xxx 1WIRE WRITE: 0x55
xxx 1WIRE WRITE: 0x22
…long 1-Wire address…
xxx 1WIRE WRITE: 0x29
xxx 1WIRE WRITE: 0xBE <–read scratchpad command
xxx 1WIRE BULK READ, 0x09 BYTES:
0x71 0x01 0xFF 0x00 0x7F 0xFF 0x0F 0x10 0xF8
1-WIRE>

The READ SCRATCHPAD command (0xBE, datasheet page 11) returns 9 bytes. We only care about the first two bytes, the rest can be decoded according the the table on page 7 of the datasheet. Temperature is calculated according to page 4 of the datasheet: 0x0171 HEX=369 DEC, 369*0.0625=23C  (74F).

Multiple devices

multi-450

When multiple 1-Wire devices share a bus it’s more difficult to determine all the addresses. The fastest way to find attached devices is with the SEARCH ROM command (0xF0) and a binary branching procedure. The Bus Pirate automates this with macro (240).

1-WIRE>(240) <–macro 240
xxx 1WIRE ROM COMMAND: SEARCH (0xF0)
Found devices at:
Macro     1-WIRE address
1.0×22 0x50 0x28 0x22 0x00 0x00 0x00 0x0A <–address
*DS1822 Econ Dig Therm <–type according to family code
2.0×22 0xD0 0xC7 0x1A 0x00 0x00 0x00 0x01
*DS1822 Econ Dig Therm
3.0×22 0x47 0x45 0x22 0x00 0x00 0x00 0x29
*DS1822 Econ Dig Therm
Found 0x03 devices.
The first 10 device IDs are available by MACRO, see (0).
1-WIRE>

The SEARCH ROM command shows the devices it found, and the type according to the family code.

We think typing 8 byte 1-Wire addresses is really tedious, so the first 10 device addresses are stored in memory and can be accessed with the macros (1)…(10). A buffer for up to 50 device addresses can be defined in the 1-Wire library at compile time. Ideally, this data will be stored in a global scratch buffer shared by all modules in a future firmware update.

1-WIRE>(0) <–show macro list
0.Macro menu
Macro     1-WIRE address <–enumerated device addresses
1.0×22 0x50 0x28 0x22 0x00 0x00 0x00 0x0A
*DS1822 Econ Dig Therm
2.0×22 0xD0 0xC7 0x1A 0x00 0x00 0x00 0x01
*DS1822 Econ Dig Therm
3.0×22 0x47 0x45 0x22 0x00 0x00 0x00 0x29
*DS1822 Econ Dig Therm
1-WIRE ROM COMMAND MACROs:<–normal commands
51.READ ROM (0x33) *for single device bus
85.MATCH ROM (0x55) *followed by 64bit address
204.SKIP ROM (0xCC) *followed by command
236.ALARM SEARCH (0xEC)
240.SEARCH ROM (0xF0)
1-WIRE>

The macro menu (0) will also include the device addresses stored in the roster. Now we can just address devices by macro, rather than typing the whole 64bit address every time.

1-WIRE>(85) (1) 0x44 <–start conversion
xxx 1WIRE BUS RESET OK
xxx 1WIRE WRITE ROM COMMAND: MATCH (0x55) *follow with 64bit address
xxx 1WIRE ADDRESS MACRO 1: 0x22 0x50 0x28 0x22 0x00 0x00 0x00 0x0A
xxx 1WIRE WRITE: 0x44
1-WIRE>(85) (1) 0xbe r:9 <–fetch reading
xxx 1WIRE BUS RESET OK
xxx 1WIRE WRITE ROM COMMAND: MATCH (0x55) *follow with 64bit address
xxx 1WIRE ADDRESS MACRO 1: 0x22 0x50 0x28 0x22 0x00 0x00 0x00 0x0A
xxx 1WIRE WRITE: 0xBE
xxx 1WIRE BULK READ, 0x09 BYTES:
0x81 0x01 0x4B 0x46 0x7F 0xFF 0x0F 0x10 0x71
1-WIRE>

(85) is a shortcut for a bus reset and MATCH ROM command. (1) is the device address macro, and 0x44 is the command to begin a temperature conversion. Retrieving the reading involves the same macros, but substitutes the command to read the device (0xBE) and grabs 9 bytes (r:9). The temperature is 0x0181, or 24C next to the PC fan.

Taking it further

We used the Bus Pirate to give a visual demonstration of the 1-Wire protocol, but the real challenge is integrating it into your own design. Maxim provides example code, Microchip has an app note (PDF), and you can check out the example code we used.

Firmware download: buspirate.vod.zip

Comments

  1. Steve Z says:

    Awesome. Thanks for sharing the knowledge!

  2. Imroy says:

    These sensors are great and there’s lots of software for using them. Even better, Dallas/Maxim will send out “samples” for free – two each of up to four parts. Then all you need to do is wire them up. Don’t forget the USB adaptor (DS9490R).

  3. Rectifier says:

    Hey, neat stuff. You guys have definately gone over the top for this thing, by saving the ROM ids and letting users handle them by macro! Above and beyond the call of duty.

    Now I’ve got to build me a bus pirate. You guys should sell a kit (or at least PCB) for sure – you deserve to get paid for developing this!

  4. fartface says:

    What makes these things a giant PITA is that if you install 2 on the line, now you have to know their serial numbers in order to read them. If you are building a simple one off project, this is not a big deal, if you are building something that you intend to manufacture, now things are a world of hurt. you need a bigger processor and nvram so that upon power up it can read all 1wire serial numbers and ask you, “is this #1? is this #2?” and so on.

    A single device you can use the generic read function. so in a 16 pin pic, you want to read 5 sensors? design it with 5 1wire busses and put 1 device per bus on it.

    1wire parts are very cool but as soon as you scale up past 1 part they become a major PITA when dealing with tiny pic processors.

  5. Malvolio says:

    Any plans to make an AVR version of this for those uninitiated in the world of PIC?!

  6. Steve says:

    I used this sensor with a pic18f4520 to create an automatic water control system. I used this to monitor the temperature of the water, and two stepper motors to adjust the water flow to keep the temperature at whatever the user put in.

  7. Chris says:

    malvolio, I’d suspect that it would not be interesting to duplicate this project on the AVR, if you’ve just developed it for the PIC. Someone else would have to want to do the AVR project for fun.
    -Cheers

  8. Scotty says:

    A onewire network running 16 DS18B20 (DS1822 equiv) is monitoring my water lines for freezing and via X10 turning on the heat tapes. Network distance is over 70 feet. Runs on Aruduino and Sanguino. Full CRC checking is in use. One serious note: See Dallas app note 4255 which tells you to use 1500 ohms instead of 4700 for the pullup resistor with these devices because they need 1.5 ma during conversion. Made whole network become totally reliable. Addresses are hardcoded into the software.

  9. Rectifier says:

    Yep, the one-wire addressing scheme is stupid for real production. I have no idea how it’s actually supposed to be used without reading each device in the factory and hardcoding it. Even if you get them to enumerate themselves, how are you to know which one is where?

    However, for a personal project, the ability to chain a ton of them on a 2-wire bus is pretty useful. And the bus pirate will make collecting the rom ids easy (to hardcode into my pic – heh)

    scotty, your project is a perfect example of how to use these things. how did you deal with the romid issue? did you hard code it too?

  10. Scotty says:

    There is enough code space in the Arduino, and 4X more in the Sanguino, to incorporate the identify, store, and assign routine needed to introduce new devices in the field. In manufacturing engineering, which I’ve many years experience with, several methods come to mind immediately and the problem is more of which to select for efficiency rather than if it can be done well enough to bother, even with a PIC. As for my single prototype two separate programs were created. One obtains the romid that is then hardcoded into the other program by hand. Debugging additonal code for discovery of just 16 devices would not have been efficient. There is enough space for it though. Oh yes.. I’m running the network in parasitic power mode, hence the need for the 1500 ohms. Powered would do fine with the 4700 ohm.

  11. scott says:

    Anyone interested in these really should check out OWFS (One Wire File System) which is a FUSE based wrapper allowing you to read all (supported) 1-Wire devices as if they were files in linux.

    http://www.owfs.org/

  12. GCL says:

    Hello!
    As Scotty has noted it will work doing things that we people types do not want to consider.

    And from personal experience, using the devices does require knowing each one’s serial number, point of fact, that is what happens when you order a batch, you get completely unique serial numbers, and are expected to know what ones you are using.

    In addition the adapter used by the computer host during testing also has one installed to add to the confusing.

  13. DaveUCSD says:

    Awesome work!!

    Can anyone help do this in flash??

    http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1232838392/0#0

  14. acidblue says:

    Keep getting: “no device detected 0x02″
    What do you guys have R1 connected to?
    There is only one 5v wire so I don’t understand why there is two 5+ in the picture.

  15. jc says:

    To all those above concerned about access to multiple devices: it is perfectly possible to connect whatever number of those on the same bus and access them individually without knowing their IDs up front. It uses a very simple and smart detection mechanism. I ordered one and looking forward to it :)

  16. PICman says:

    It is temperature control project http://avtomatchik.com/node/56 . The code is written for the PIC12 microcontroller and can be adapted for the PIC16 or others.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 97,539 other followers