1-wire slave emulator for PIC16 microcontroller – owslave

I have a small 1-wire network running different sensors. The network is connected to a linux box. I needed to add a humidity sensor to the network. There are plenty of different solutions but I found this project that was using PIC microcontroller as a bridge between 1-wire network and Sensirion SHT11 sensor. I thought it was a great idea and also, as I had no experience with µC, a great way to learn something new. My idea was also that this 1-wire slave could serve for communication with other devices using different protocols.

The project that I found was a closed source one, so I decided I should write my own program and make my first µC device. I chose PIC16F84A for my design, as it was cheap, easy to get and easy to program. As I had 10 MHz crystal I decided that I will try to make it work at that frequency, although this chip allows crystals up to 20 MHz. I bought a few needed parts according to PIC datasheet and built a very simple device.


owslave schematic

PIC works in its basic environment: X1 is 10 MHz quartz, C1 and C2 are 27 pF capacitors; MCLR is connected to VDD through R1=10 kΩ resistor; additionally PIC is decoupled with C3=100 nF. Connecting sensors requires a few additional components: two pullup resistors R2=R3=10 kΩ (R2 is optional, required only with SHT2x) and decoupling capacitor C4=100 nF. Operating voltage for SHT1x is 2.4–5.5 V, while for SHT2x it is 2.1–3.6 V (with 5 V described in datasheet as an absolute maximum). I am powering both SHT11 and SHT21 with +5 V and it works ok, but it is probably too much for the latter. I plan to lower supply voltage of SHT21 to 3.3 V. I connect sensor to pins RB4 and RB5 but it may be changed in source file to any other I/O port except RB0/INT which must be reserved for 1-wire data line.


owslave board

I decided I should try to program it in C (although it would probably be much more efficient in assembler). I needed to find a free tool and after some digging I found Hitech PICC compiler which even offered me full code optimization during evaluation period. As I have limited access to machines running MS Windows I was using rather weird set of tools. I was running PICC compiler on OSX writing code in Xcode. I programmed my chip using very cheap programmer JDM 2. It was connected to serial port of a linux machine and driven by WinPic program under wine.

The biggest challenge was to keep up with the master. Each 1-wire operation is initiated by master device pulling the bus low and timings are very tight. If I am not wrong in my calculations my microcontroller running at 10MHz performs 2.5 instructions per microsecond. For example while master reads byte from a slave, the time between master initiates the operation by pulling bus low and the time when master is probing line for 0 or 1 state is 15 µs. We are thus limited to a little more then 30 instructions which should be ok, but as there are many conditions to check on the way and we deal with a poorly optimized C code… Anyway, after lots of debugging it started working and here are results of my work.

Owslave supports following 1-wire commands

ROM commands:

and function commands:

Implemented ROM commands should make it compatible with any 1-wire software. I was testing it with owfs and digitemp on linux and osx as well as with Maxim 1-wire java tools. I use DS9097U compatible interface between PC and 1-wire network. Regarding humidity sensors I tested it with SHT11 and SHT21, as these are the only ones I have. UPDATE: A user reported that he uses owslave sucessfully with SHT71.

The algorithm is very simple: 1-wire master on PC detects owslave (through search ROM procedure) and sends it "convert" command. This makes owslave send analogous command to sensor and read back measurements into its scratchpad. After a while 1-wire master sends "read scratchpad" command and fetches measurments from the slave. It gets raw results from the sensor and all the calculations and crc checking must be done in master software. Owslave returns 7 bytes:

I patched digitemp so that it natively recognizes 1-wire slave emulator by its family code (I chose 0xBF), gets results from sensors, do all the crc checking and calculations. I also patched owfs to support the device, although it was just for testing, as I don't use this program.

Currently owslave supports two types of sensors:

The code for contacting SHT sensors was adopted from samples published on Sensirion webpage. It should be easy to adapt owslave to any other devices communicating with I2C protocol as all the basic functions are already included. Owslave design also facilitates adding support for other devices.

While returning readings from attached sensors to 1-wire master owslave sends also sensor code so that 1-wire master software knows what kind of data to expect. Due to limited program space on PIC16F84A (1024 words) there may be only one type of supported sensor compiled into hex file. That means that one must take a decision which sensor will be be used with given device at the stage of compilation.

Digitemp output:

baf@vatna:~$ digitemp -w DigiTemp v3.6.0 Copyright 1996-2007 by Brian C. Lane GNU Public License v2.0 - http://www.digitemp.com Turning off all DS2409 Couplers ...... Devices on the Main LAN 284E02BC00000078 : DS18B20 Temperature Sensor 2819E5BB000000DE : DS18B20 Temperature Sensor 28E56FBC00000021 : DS18B20 Temperature Sensor 28F3F1BB0000005B : DS18B20 Temperature Sensor BF54594D454B0094 : OWSLAVE BF42415254454BC6 : OWSLAVE baf@vatna:~$ digitemp -a DigiTemp v3.6.0 Copyright 1996-2007 by Brian C. Lane GNU Public License v2.0 - http://www.digitemp.com May 19 00:13:05 Sensor 0 C: 22.12 F: 71.83 May 19 00:13:07 Sensor 1 C: 25.50 F: 77.90 May 19 00:13:08 Sensor 2 C: 15.19 F: 59.34 May 19 00:13:09 Sensor 3 C: 21.12 F: 70.03 May 19 00:13:10 Sensor 4 C: 24.30 F: 75.74 H: 39% May 19 00:13:11 Sensor 5 C: 22.80 F: 73.04 H: 44%

OWFS output (also gives info on type of connected sensor):

baf@vatna:~$ owget / /28.4E02BC000000 /28.19E5BB000000 /28.E56FBC000000 /28.F3F1BB000000 /BF.54594D454B00 /BF.42415254454B /bus.0 /uncached /settings /system /statistics /structure /simultaneous /alarm baf@vatna:~$ owget /BF.54594D454B00 /BF.54594D454B00/SHT1x /BF.54594D454B00/address /BF.54594D454B00/alias /BF.54594D454B00/crc8 /BF.54594D454B00/family /BF.54594D454B00/humidity /BF.54594D454B00/id /BF.54594D454B00/locator /BF.54594D454B00/r_address /BF.54594D454B00/r_id /BF.54594D454B00/r_locator /BF.54594D454B00/sensor_type /BF.54594D454B00/temperature /BF.54594D454B00/type baf@vatna:~$ owget /BF.42415254454B /BF.42415254454B/SHT2x /BF.42415254454B/address /BF.42415254454B/alias /BF.42415254454B/crc8 /BF.42415254454B/family /BF.42415254454B/humidity /BF.42415254454B/id /BF.42415254454B/locator /BF.42415254454B/r_address /BF.42415254454B/r_id /BF.42415254454B/r_locator /BF.42415254454B/sensor_type /BF.42415254454B/temperature /BF.42415254454B/type

Compiling under picc compiler:

mbp:owslave-0.3 baf$ picc --chip=16F84A --outdir=output owslave.c 1wire.c sht1x.c sht2x.c Licensed for evaluation purposes only. This licence will expire on Fri, 29 Apr 2011. HI-TECH C Compiler for PIC10/12/16 MCUs (PRO Mode) V9.81 Copyright (C) 2010 Microchip Technology Inc. owslave.c 1wire.c sht1x.c sht2x.c Memory Summary: Program space used 3C3h ( 963) of 400h words ( 94.0%) Data space used 34h ( 52) of 44h bytes ( 76.5%) EEPROM space used 8h ( 8) of 40h bytes ( 12.5%) Configuration bits used 1h ( 1) of 1h word (100.0%) ID Location space used 0h ( 0) of 4h bytes ( 0.0%)