Introduction.
Popular processors such as the Basic Stamp 2 (BS2-IC) and the PICAXE series fetch each command from memory, decode it and then execute it. Thus, they are too slow to meet the stringent requirements required for interfacing with the Dallas 1-W family of devices.
The ONEWIRE Controller permits a conventional Basic Stamp, PICAXE or similar to interface with up to seven Dallas 1-wire devices, with each device on a separate run. Communication between the Stamp and the ONEWIRE Controller uses RS232 serial communication. The baud rate may be set to either 9600 or to 2400 for the PICAXE with a strap.
This design permits the hobbyist to interface with any Dallas 1-wire device including DS18S20, DS18B20, DS1822 temperature sensors, DS2438 temperature and A/D, DS2423 dual 32-bit counter and DS2450 Quad 16-bit A/D.
Each of the seven channels accommodates one Dallas 1-W devices. This design does not support multiple devices on the same channel.
The design consists of a single programmed PIC (14-pin DIP). It is shipped as a kit which includes seven 4.7K resistors used as pullup resistors on each of the 1-wire channels, a status LED, lengths of 22 awg solid suitable for use with a solder less breadboard and a schematic.
This design is now available as a kit. $14.95. See below
Command Set.
The Stamp's command set for interfacing with Dallas 1-W devices is minimal;
Note that the Dallas 1-W channels are 0 through 6.
These commands are then used to interface with virtually any Dallas 1-W device.
The following segment of Basic Stamp 2 code illustrates how these commands may be used to perform a temperature measurement using a DS18B20. The complete routine appears at the bottom of this discussion.
SEROUT 8, BaudMode, 10, ["P0", "W0cc", "S044"] 'perform temp meas ' note strong pullup PAUSE 1100 ' wait for conversion to complete SEROUT 8, BaudMode, 10, ["P0", "W0cc", "W0be"] ' send temperature data SEROUT 8, BaudMode, 10, ["R0"] ' fetch data SERIN 7, Baudmode, 1500, TimeOut, [DEC X.LOWBYTE] PAUSE 100 SEROUT 8, BaudMode, 10, ["R0"] ' fetch data SERIN 7, Baudmode, 1500, TimeOut, [DEC X.HIGHBYTE] PAUSE 100
The design includes a status LED which blips about every second to indicate the processor is alive and running. It rapidly flashes a number of times to indicate data is being sent to the Stamp.
A source of +5 VDC is required. The current drain is less than 10 mA.
+5 VDC ------- ONEWIRE LED ---------->|--- GRD GRD ---------- CONTROLLER 0 -------- To Dallas 1-W devices BAUD --------- 1 -------- RX ----------> 2 -------- TX <---------- 3 -------- 4 -------- /MCLR -------- 5 -------- 6 -------- Baud - Open for 9600 baud, Ground for 2400 /MCLR - Momentarily ground to reset
Routines to interface with a DS18B20 temperature sensor, DS2438 temperature sensors and A/D and DS2423 Dual Counter for the Basic Stamp and the PICAXE-18X appear below.
An excellent tutorial with sample code for the Arduino appears at
Basic Stamp (BS2) Routines
DS18B20_1.BS2
' {$STAMP BS2} ' {$PBASIC 2.5} ' DS18B20_1.BS2 (Basic Stamp 2) ' ' Illustrates the use of the ONEWIRE PIC in interfacing with a DS18B20 on ' Channel 0. ' ' BS2-IC ONEWIRE PIC +5 VDC ' | ' P8 (term 13) -----------------> "RX" (term 5) 4.7K DS18B20 ' P7 (term 12) <----------------- "TX" (term 6) | ' "0" (term 13) ----------------- DQ (term 2) ' OPEN --- "BAUD" GRD ---- (term 1) ' GRD ---- (term 3) ' ' 9600 baud. ' ' Copyright, Peter H. Anderson, Baltimore, MD, Nov 14, '06 BaudMode CON 84 '9600 True X VAR Word Y VAR Word SignBit VAR Byte Whole VAR Byte Fract VAR Byte DIR7 = 0 ' serial input DIR8 = 1 ' serial output OUT8 = 0 ' be sure SerOut pin is stable at zero PAUSE 1000 DO AGN: SEROUT 8, BaudMode, 10, ["P0", "W0cc", "S044"] 'perform temp meas ' note strong pullup PAUSE 1100 ' wait for conversion to complete SEROUT 8, BaudMode, 10, ["P0", "W0cc", "W0be"] ' send temperature data SEROUT 8, BaudMode, 10, ["R0"] ' fetch data SERIN 7, Baudmode, 1500, TimeOut, [DEC X.LOWBYTE] PAUSE 100 SEROUT 8, BaudMode, 10, ["R0"] ' fetch data SERIN 7, Baudmode, 1500, TimeOut, [DEC X.HIGHBYTE] PAUSE 100 ' now do the calculations SignBit = X / 256 / 128 IF SignBit = 1 THEN ' its negative X = X ^ $ffff + 1 ' take the two's comp ENDIF ' multiply by 6.25 - This is 100 * Tc Y = X / 4 ' 0.25 X = X * 6 + Y Whole = X / 100 Fract = X // 100 IF SignBit = 1 THEN DEBUG "-", DEC Whole, ".", DEC2 Fract, CR ELSE DEBUG DEC Whole, ".", DEC2 Fract, CR ENDIF PAUSE 3000 ' wait 3 secs LOOP TimeOut: DEBUG "Timeout Error", CR GOTO AGN
DS2438_1.BS2
' {$STAMP BS2} ' {$PBASIC 2.5} ' DS2438_1.BS2 (Basic Stamp 2) ' ' Illustrates the use of the ONEWIRE PIC in interfacing with a DS2438 A/D and Temperature ' sensor ON Channel 2. ' ' Measures and displays Vdd, Vad and Tc. ' ' BS2-IC ONEWIRE PIC DS2438 ' ' P8 (term 13) -----------------> "RX" (term 5) +5 VDC --- Vdd (term 5) ' P7 (term 12) <----------------- "TX" (term 6) GRD ------ GRD (term 1) ' "2" (term 3) ---------***----- DQ (term 8) ' OPEN ----- "BAUD" Vsensor --- Vad (term 4) ' ' 9600 Baud. ' ' Copyright, Peter H. Anderson, Baltimore, MD, Nov 14, '06 BaudMode CON 84 '9600 True N VAR Byte X VAR Word Y VAR Word SignBit VAR Byte Whole VAR Byte Fract VAR Byte VSource VAR Byte DIR7 = 0 ' serial input DIR8 = 1 ' serial output OUT8 = 0 ' be sure SerOut pin is stable at zero PAUSE 1000 DO VSource = 0 ' Vdd GOSUB MeasVoltage VSource = 1 ' Vad GOSUB MeasVoltage GOSUB MeasTemp PAUSE 5000 LOOP MeasVoltage: SEROUT 8, BaudMode, 10, ["P2", "W2cc", "W24e", "W200"] ' setup for Vdd or A/D IF VSource = 0 THEN SEROUT 8, BaudMode, 10, ["W208"] ' ELSE SEROUT 8, BaudMode, 10, ["W200"] ' ENDIF SEROUT 8, BaudMode, 10, ["P2", "W2cc", "W2b4"] ' perform A/D PAUSE 1000 ' wait for A/D to complete SEROUT 8, BaudMode, 10, ["P2", "W2cc", "W2b8", "W200"] ' recall to scratchpad SEROUT 8, BaudMode, 10, ["P2", "W2cc", "W2be", "W200"] ' read scratchpad FOR N = 1 TO 3 PAUSE 100 SEROUT 8, BaudMode, 10, ["R2"] ' NEXT PAUSE 100 SEROUT 8, BaudMode, 10, ["R2"] ' SERIN 7, Baudmode, 1500, TimeOut, [DEC X.LOWBYTE] PAUSE 100 SEROUT 8, BaudMode, 10, ["R2"] ' SERIN 7, Baudmode, 1500, TimeOut, [DEC X.HIGHBYTE] PAUSE 100 ' now do the calculations Whole = X / 100 Fract = X // 100 IF VSource = 0 THEN DEBUG "Vdd = ", DEC Whole, ".", DEC2 Fract, CR ELSE DEBUG "Vad = ", DEC Whole, ".", DEC2 Fract, CR ENDIF RETURN MeasTemp: SEROUT 8, BaudMode, 10, ["P2", "W2cc", "W24e", "W200"] ' setup for temperature meas SEROUT 8, BaudMode, 10, ["P2", "W2cc", "W244"] ' perform temp measurement PAUSE 1000 SEROUT 8, BaudMode, 10, ["P2", "W2cc", "W2b8", "W200"] ' recall to scratchpad SEROUT 8, BaudMode, 10, ["P2", "W2cc", "W2be", "W200"] ' read scratchpad SEROUT 8, BaudMode, 10, ["R2"] ' PAUSE 100 SEROUT 8, BaudMode, 10, ["R2"] ' SERIN 7, Baudmode, 1500, TimeOut, [DEC X.LOWBYTE] ' byte 2 PAUSE 100 SEROUT 8, BaudMode, 10, ["R2"] ' ' byte 3 SERIN 7, Baudmode, 1500, TimeOut, [DEC X.HIGHBYTE] PAUSE 100 ' now do the calculations signbit = X / 256 / 128 IF SignBit = 1 THEN ' its negative X = X ^ $ffff + 1 ' take the two's comp ENDIF X = X / 8 ' multiply by 3.125 - This is 100 * Tc Y = X / 8 ' 0.125 X = X * 3 + Y Whole = X / 100 Fract = X // 100 DEBUG "Tc = " IF SignBit = 1 THEN DEBUG "-", DEC Whole, ".", DEC2 Fract, CR ELSE DEBUG DEC Whole, ".", DEC2 Fract, CR ENDIF RETURN TimeOut: DEBUG "Timeout Error", CR RETURN
DS2423_1.BS2
' {$STAMP BS2} ' {$PBASIC 2.5} ' DS18B20_1.BS2 (Basic Stamp 2) ' ' Illustrates the use of the ONEWIRE PIC in interfacing with a DS2423 Dual 32-bit ' counter on Channel 1. ' ' BS2-IC ONEWIRE PIC DS2423 ' ' P8 (term 13) -----------------> "RX" (term 5) ' P7 (term 12) <----------------- "TX" (term 6) GRD ---- GRD (term 1) ' "1" -------------------***------- DQ (term 2) ' OPEN ----- "BAUD" +5 VDC --- Vdd (term 3) ' ' 9600 Baud. ' ' Copyright, Peter H. Anderson, Baltimore, MD, Nov 14, '06 BaudMode CON 84 '9600 True N VAR Byte X VAR Word Y VAR Word CounterNum VAR Byte DIR7 = 0 ' serial input DIR8 = 1 ' serial output OUT8 = 0 ' be sure SerOut pin is stable at zero PAUSE 1000 DO CounterNum = 0 GOSUB ReadCounter DEBUG "Counter 0 = ", HEX4 Y, " ", HEX4 X, CR CounterNum = 1 GOSUB ReadCounter DEBUG "Counter 1 = ", HEX4 Y, " ", HEX4 X, CR PAUSE 3000 LOOP ReadCounter: SEROUT 8, BaudMode, 10, ["P1", "W1cc", "W1a5"] IF CounterNum = 0 THEN SEROUT 8, BaudMode, 10, ["W1c0"] ELSE SEROUT 8, BaudMode, 10, ["W1e0"] ENDIF SEROUT 8, BaudMode, 10, ["W101"] FOR N = 1 TO 32 SEROUT 8, Baudmode, 10, ["R1"] PAUSE 100 NEXT SEROUT 8, BaudMode, 10, ["R1"] ' fetch data SERIN 7, Baudmode, 1500, TimeOut, [DEC X.LOWBYTE] PAUSE 100 SEROUT 8, BaudMode, 10, ["R1"] SERIN 7, Baudmode, 1500, TimeOut, [DEC X.HIGHBYTE] PAUSE 100 SEROUT 8, BaudMode, 10, ["R1"] SERIN 7, Baudmode, 1500, TimeOut, [DEC Y.LOWBYTE] PAUSE 100 SEROUT 8, BaudMode, 10, ["R1"] SERIN 7, Baudmode, 1500, TimeOut, [DEC Y.HIGHBYTE] PAUSE 100 RETURN TimeOut: DEBUG "Timeout Error", CR RETURN
PICAXE-18X Routines.
DS18B20_1.BAS
' DS18B20_1.BAS (PICAXE-18X) ' ' Illustrates the use of the ONEWIRE PIC in interfacing with DS18B20s on ' on Channels 0, 4 and 5. ' ' PICAXE-18X ONEWIRE PIC +5 VDC ' | ' Out0 (term 6) ----------------> "RX" (term 5) 4.7K DS18B20 ' In0 (term 15) <---------------- "TX" (term 6) | ' "0" (term 13) ----------------- DQ (term 2) ' GRD --- "BAUD" GRD ---- (term 1) ' GRD ---- (term 3) ' ' (DS18B20s also on Channels 4 and 5) ' 2400 baud. ' ' Copyright, Peter H. Anderson, Baltimore, MD, Nov 14, '06 Symbol H = B0 Symbol L = B1 Symbol SignBit = B2 Symbol Chan = B3 Symbol X = W2 Symbol Y = W3 Symbol Whole = B8 Symbol Fract = B9 High 1 ' Be sure Tx Pin is idle for some time Pause 5000 ' wait for PICAXE LCD to boot Top: Chan = 0 GoSub MeasTemp ' measures and displays temperature Chan = 4 GoSub MeasTemp Chan = 5 GoSub MeasTemp Pause 3000 Goto Top MeasTemp: SerOut 0, T2400, ("P", #Chan, "W", #Chan, "cc", "S", #Chan, "44") 'perform temp meas ' note strong pullup Pause 1100 ' wait for conversion to complete SerOut 0, T2400, ("P", #Chan, "W", #Chan, "cc", "W", #Chan, "be") ' send temperature data SerOut 0, T2400, ("R", #Chan) ' fetch data SerIn 0, T2400, #L Pause 100 SerOut 0, T2400, ("R", #Chan) ' fetch data SerIn 0, T2400, #H Pause 100 ' now do the calculations X = H X = X * 256 + L SignBit = X / 256 / 128 IF SignBit = 1 THEN ' its negative X = X ^ $ffff + 1 ' take the two's comp ENDIF ' multiply by 6.25 - This is 100 * Tc Y = X / 4 ' 0.25 X = X * 6 + Y Whole = X / 100 Fract = X // 100 SerTxD (#Chan, " ") If SignBit = 1 Then SerTxD ("-") EndIf GoSub DisplayDec Return DisplayDec: SerTxD (#Whole, ".") If Fract < 10 Then SerTxD ("0", #Fract) Else SerTxD (#Fract) EndIf SerTxD (10, 13) Return
DS2438_1.BAS
' DS2438_1.BAS (PICAXE-18X) ' ' Illustrates the use of the ONEWIRE PIC in interfacing with a DS2438 A/D and Temperature ' sensor ON Channel 2. ' ' Measures and displays Vdd, Vad and Tc. ' ' PICAXE-18X ONEWIRE PIC DS2438 ' ' Out0 (term 6) ----------------> "RX" (term 5) +5 VDC --- Vdd (term 5) ' In0 (term 15) <----------------- "TX" (term 6) GRD ------ GRD (term 1) ' "2" (term 3) ---------***----- DQ (term 8) ' GRD ----- "BAUD" (term 11) Vsensor --- Vad (term 4) ' ' 2400 Baud. ' ' Copyright, Peter H. Anderson, Baltimore, MD, Nov 14, '06 Symbol H = B0 Symbol L = B1 Symbol N = B2 Symbol SignBit = B3 Symbol X = W2 Symbol Y = W3 Symbol Whole = B8 Symbol Fract = B9 Symbol Vsource = B10 High 1 ' Be sure Tx Pin is idle for some time Pause 5000 ' wait for PICAXE LCD to boot Top: VSource = 0 ' Vdd GOSUB MeasVoltage VSource = 1 ' Vad GOSUB MeasVoltage GOSUB MeasTemp PAUSE 500 Goto Top: MeasVoltage: SerOut 0, T2400, ("P2", "W2cc", "W24e", "W200") If VSource = 0 Then SerOut 0, T2400, ("W208") Else SerOut 0, T2400, ("W200") EndIf SerOut 0, T2400, ("P2", "W2cc", "W2b4") ' perform A/D Pause 1100 ' wait for A/D to complete SerOut 0, T2400, ("P2", "W2cc", "W2b8", "W200") ' recall to scratchpad SerOut 0, T2400, ("P2", "W2cc", "W2be", "W200") ' read scratchpad For N = 1 TO 3 SerOut 0, T2400, ("R2") Pause 100 Next SerOut 0, T2400, ("R2") SerIn 0, T2400, #L Pause 100 SerOut 0, T2400, ("R2") SerIn 0, T2400, #H Pause 100 X = H X = X * 256 + L Whole = X / 100 Fract = X % 100 If VSource = 0 Then SerTxD ("Vdd = ") Else SerTxD ("Vad = ") EndIf GoSub DisplayDec Return MeasTemp: SerOut 0, T2400, ("P2", "W2cc", "W24e", "W200") ' setup for temperature meas SerOut 0, T2400, ("P2", "W2cc", "W244") ' perform temp measurement Pause 1000 SerOut 0, T2400, ("P2", "W2cc", "W2b8", "W200") ' recall to scratchpad SerOut 0, T2400, ("P2", "W2cc", "W2be", "W200") ' read scratchpad SerOut 0, T2400, ("R2") ' Pause 100 SerOut 0, T2400, ("R2") ' SerIn 0, T2400, #L ' byte 2 Pause 100 SerOut 0, T2400, ("R2") ' byte 3 SerIn 0, T2400, #H Pause 100 ' now do the calculations X = H X = X * 256 + L signbit = X / 256 / 128 If SignBit = 1 Then ' its negative X = X ^ $ffff + 1 ' take the two's comp EndIf X = X / 8 ' multiply by 3.125 - This is 100 * Tc Y = X / 8 ' 0.125 X = X * 3 + Y Whole = X / 100 Fract = X // 100 SerTxD ("Tc = ") If SignBit = 1 Then SerTxD ("-") EndIf GoSub DisplayDec Return DisplayDec: SerTxD (#Whole, ".") If Fract < 10 Then SerTxD ("0", #Fract) Else SerTxD (#Fract) EndIf SerTxD (10, 13) Return
DS2423_1.BAS
' DS18B20_1.BS2 (PICAXE-18X) ' ' Illustrates the use of the ONEWIRE PIC in interfacing with a DS2423 Dual 32-bit ' counter on Channel 1. ' ' BS2-IC ONEWIRE PIC DS2423 ' ' Out0 (term 6) ----------------> "RX" (term 5) ' In0 (term 15) <---------------- "TX" (term 6) GRD ---- GRD (term 1) ' "1" -------------------***------- DQ (term 2) ' GRD ----- "BAUD" +5 VDC --- Vdd (term 3) ' ' 2400 Baud. ' ' Copyright, Peter H. Anderson, Baltimore, MD, Nov 14, '06 Symbol H = B0 Symbol L = B1 Symbol N = B2 Symbol CounterNum = B3 Symbol X = W2 Symbol Y = W3 High 1 ' Be sure Tx Pin is idle for some time Pause 5000 ' wait for PICAXE LCD to boot Top: CounterNum = 0 GoSub ReadCounter CounterNum = 1 GoSub ReadCounter Pause 3000 Goto Top: ReadCounter: SerOut 0, T2400, ("P1", "W1cc", "W1a5") If CounterNum = 0 Then SerOut 0, T2400, ("W1c0") Else SerOut 0, T2400, ("W1e0") EndIf SerOut 0, T2400, ("W101") For N = 1 to 32 SerOut 0, T2400, ("R1") Pause 100 Next SerOut 0, T2400, ("R1") ' fetch data SerIn 0, T2400, #L Pause 100 SerOut 0, T2400, ("R1") SerIn 0, T2400, #H Pause 100 X = H X = X * 256 + L SerOut 0, T2400, ("R1") SerIn 0, T2400, #L Pause 100 SerOut 0, T2400, ("R1") SerIn 0, T2400, #H Pause 100 Y = H Y = Y * 256 + L SerTxD (#CounterNum, " ", #Y, " ", #X, 10, 13) Return