Introduction
This discussion offers a number of techniques to implement various temperature measurement systems using the lowcost PICAXE-08M (nominally $3.25) and the Dallas DS18B20 1-W temperature sensor.
Note that when used with the PICAXE, the DS18B20 must be powered with +5 VDC. My recommendation is to run two twisted pairs to each DS18B20, one to provide +5VDC and GRD and the other DQ and GRD. With the second pair, it is suggested the GRD be grounded only on the PICAXE side and not at the DS18B20 to avoid ground loops. An obvious implementation is to use CAT-5 cable which includes a number of pairs of twisted cable and is readily available and relatively inexpensive.
An obvious question is how far the DS18B20 units may be located from the PICAXE. I have designed manny temperature measurement modules where I had the ability to actually implement the various aspects of the 1-W protocol. In advertising these units, I suggest a maximum of 200 feet as I have tested all of my designs using a length of 200 foot cable and am willing to guarantee operation to this length. If the customer finds they can go two or three times farther, they are happy. In fact, separate runs of 200 feet from a single PICAXE is probably adequate in most installations. If you have to go further, give it a try.
Program DS18B20_08M_1.Bas.
This program interfaces with three DS18B20 sensors on separate twisted pair runs. It performs measurements on each of the three sensors and sends the result in the of the device number (1, 2, 3) and the temperature with two digits after the decimal point. For example;
1 23.76 2 16.97 3 -10.78This data is sent to the PC using the SerTxD command, which is 4800 baud for the PICAXE-08M. Clearly, you could modify this for 2400 using the SerOut command.
In this implementation, the ReadTemp12 command is used to read the temperature into word variable TReading. If the most significant bit is a one, the reading is negative and the twos compliment of the reading is performed. This is then multiplied by 100 times 0.0625. The whole and fractional parts are separated and each is output to the terminal separated by a decimal point.
In this implementation, the three measurements are performed and the results sent to the PC or similar, followed by a pause. I didn't really want to wait around for hours to see the results and thus set the pause for nominally 20 secs. However, once debugged, you can easily modify this for an hour or more. Indeed, the accuracy may not be perfect, but if you want a system to monitor temperatures every hour, do you really care if this is 3605 seconds as opposed to precisely 3600 seconds.
' DS18B20_08M_1.Bas - PICAXE-08M ' ' Illustrates an interface with the DS18B20. ' ' Continually measures the temperature and displays to two significant digits on the ' terminal. This is repeated for DS18B20 temperature sensors on IN1/OUT1, IN2/OUT2 ' and IN4.OUT4. ' ' Note that a 4.7K pullup to +5 VDC is required on each DQ lead. +5 VDC is required on the ' V+ terminal of the DS18B20. ' ' 08M DS18B20 ' ' IO1 (term 7) ------------------ DQ (term 2) ' IO1 (term 6) ------------------ DQ (term 2) ' IO1 (term 3) ------------------ DQ (term 2) ' ' Uses 118 of 256 bytes. ' ' copyright, Peter H Anderson, Baltimore, MD, Sept, '04 Symbol TReading = W0 Symbol Whole = B2 Symbol Fract = B3 Symbol SignBit = B4 Symbol Dig = B5 Symbol TempC_100 = W4 Symbol DevNum = B6 Top: For DevNum = 1 to 3 ' 1, 2, 3 Branch DevNum, (Invalid, Dev1, Dev2, Dev3) Invalid: Dev1: ReadTemp12 1,TReading Goto CalcT Dev2: ReadTemp12 2,TReading Goto CalcT Dev3: ReadTemp12 4,TReading Goto CalcT ' this statement not really necessary CalcT: SignBit = TReading / 256 / 128 If SignBit = 0 Then Positive ' its negative TReading = TReading ^ $ffff + 1 ' take twos comp Positive: TempC_100 = TReading * 6 ' TC = value * 0.0625 TReading = TReading * 25 / 100 TempC_100 = TempC_100 + TReading GoSub DisplayTemp Next Pause 20000 GoTo Top DisplayTemp: SerTxD (#DevNum, " ") Whole = TempC_100 / 100 Fract = TempC_100 % 100 If SignBit = 0 Then DisplayTemp_1 SerTxD ("-") DisplayTemp_1: SerTxD (#Whole, ".") ' be sure the fractional is two digits Dig = Fract / 10 SerTxD (#Dig) Dig = Fract % 10 SerTxD (#Dig, 13, 10) Return
Program DS18B20_08M_2.Bas
This differs from the previous routine in that a single temperature measurment sequence is only performed when the input at Pin3 goes high.
The PICAXE is configured for a polled interrupt, high on Pin3. On interrupt, the program enters the Interrupt routine and waits until Pin3 goes low. Byte variable IntOccurred is then set to 1, the interrupt is again configured and the program return to the main routine. As, variable IntOccurred is at 1, the program breaks out of the loop, clears the IntOccurred variable to zero and performs a single measurement on each of the three DS18B20s and then returns to await another polled interrupt.
My idea in using a logic 1 to cause the interrupt was to provide a simple interface with a PC, which would allow a user to hit a single key and thus cause one measurement sequence to occur.
Thus, one might program the PICAXE-08M with the shunt 10K resistor to ground and series 22K to terminal 2 of the PICAXE.
Once programmed, the connection which was at terminal 2 of the PICAXE, might be moved to terminal 4 (Pin3). Remember to tie the PICAXE programming terminal 2 to ground. Thus, the TxD from the PC is now connected to the PIN3.
Then, use HyperTerm or similar, configured for a direct connection, 4800 baud, no parity and no flow control Normally PIN3 is at a logic zero. When a character a character is received, it momentarily goes high, interrupting the processor and causing a single temperature measurement sequence to be performed.
Note that it is important to use the shunt 10K, series 22K resistor configuration on PIN3 (term 4) as the RS232 levels from the PC are not compatible with PIC.
' DS18B20_08M_2.Bas - PICAXE-08M ' ' Illustrates an interface with a number of DS18B20 temperature sensors. ' ' Uses the polling interrupt to detect a high on Pin3. ' ' Idles until logic one appears on Pin3. ' ' Performs a single temperature measurement and displays to two significant digits on the ' terminal. This is repeated for DS18B20 temperature sensors on IN1/OUT1, IN2/OUT2 ' and IN4.OUT4. ' ' The unit then again idles until a logic one appears on Pin3. ' ' Note that a 4.7K pullup to +5 VDC is required on each DQ lead. +5 VDC is required on the ' V+ terminal of the DS18B20. ' ' 08M DS18B20 ' ' IO1 (term 7) ------------------ DQ (term 2) ' IO1 (term 6) ------------------ DQ (term 2) ' IO1 (term 3) ------------------ DQ (term 2) ' ' Uses 140 of 256 bytes. ' ' copyright, Peter H Anderson, Baltimore, MD, Sept, '04 Symbol TReading = W0 Symbol Whole = B2 Symbol Fract = B3 Symbol SignBit = B4 Symbol Dig = B5 Symbol TempC_100 = W3 Symbol DevNum = B8 Symbol IntOccurred = B9 SetInt %000010000, %000010000 ' Pin 3, High IntOccurred = 0 Top: If IntOccurred = 0 Then Top IntOccurred = 0 For DevNum = 1 to 3 ' 1, 2, 3 Branch DevNum, (Invalid, Dev1, Dev2, Dev3) Invalid: Dev1: ReadTemp12 1,TReading Goto CalcT Dev2: ReadTemp12 2,TReading Goto CalcT Dev3: ReadTemp12 4,TReading Goto CalcT ' this statement not really necessary CalcT: SignBit = TReading / 256 / 128 If SignBit = 0 Then Positive ' its negative TReading = TReading ^ $ffff + 1 ' take twos comp Positive: TempC_100 = TReading * 6 ' TC = value * 0.0625 TReading = TReading * 25 / 100 TempC_100 = TempC_100 + TReading GoSub DisplayTemp Next GoTo Top DisplayTemp: SerTxD (#DevNum, " ") Whole = TempC_100 / 100 Fract = TempC_100 % 100 If SignBit = 0 Then DisplayTemp_1 SerTxD ("-") DisplayTemp_1: SerTxD (#Whole, ".") ' be sure the fractional is two digits Dig = Fract / 10 SerTxD (#Dig) Dig = Fract % 10 SerTxD (#Dig, 13, 10) Return Interrupt: Pause 100 If Pin3 = 1 then Interrupt IntOccurred = 1 SetInt %000010000, %000010000 Return
Program DS18B20_08M_3
Discussion to be added.
' DS18B20_08M_3.Bas - PICAXE-08M ' ' Illustrates an interface with the DS18B20 in monitoring two temperatures. An alarm ' is associated with with one of the temperatures. ' ' Continually measures the temperature and displays to two significant digits on the ' terminal. This is repeated for DS18B20 temperature sensors on IN1/OUT1 and IN2/OUT2. ' ' If the temperature measured on the DS18B20 associated with IN1 is abve HighTrip, a relay ' on Out4 (term 3) is operated. It is released when the temperature falls below LowTrip ' ' Note that HighTrip and LowTrip are specified as the temperature plus 60 degrees C to avoid ' working with negative numbers. ' ' ' Note that a 4.7K pullup to +5 VDC is required on each DQ lead. +5 VDC is required on the ' V+ terminal of the DS18B20. ' ' 08M DS18B20 ' ' IO1 (term 7) ------------------ DQ (term 2) ' IO2 (term 6) ------------------ DQ (term 2) ' ' ALM LED ' OUT4 (term 3) ------- 330 ----->|---- GRD ' ' Uses 138 of 256 bytes. ' ' copyright, Peter H Anderson, Baltimore, MD, Sept, '04 Symbol TReading = W0 Symbol Whole = B2 Symbol Fract = B3 Symbol SignBit = B4 Symbol Dig = B5 Symbol TempC_100 = W3 Symbol DevNum = B8 Symbol Temp_8 = B9 Symbol HighTrip = 90 ' 30 + 60 - adjust as necessary Symbol LowTrip = 88 ' 28 + 60 Low 4 ' turn off alarm Top: For DevNum = 1 to 2 ' 1, 2 Branch DevNum, (Invalid, Dev1, Dev2) Invalid: Dev1: ReadTemp12 1,TReading ReadTemp 1, Temp_8 ' read the high 8 bits Goto CalcT Dev2: ReadTemp12 2,TReading Goto CalcT CalcT: SignBit = TReading / 256 / 128 If SignBit = 0 Then Positive ' its negative TReading = TReading ^ $ffff + 1 ' take twos comp Positive: TempC_100 = TReading * 6 ' TC = value * 0.0625 TReading = TReading * 25 / 100 TempC_100 = TempC_100 + TReading GoSub DisplayTemp Next ' now deal with the alarm Temp_8 = Temp_8 + 60 ' to avoid negative numbers If Temp_8 > HighTrip Then OperateAlarm If Temp_8 < LowTrip Then ReleaseAlarm ' else Goto SequenceDone OperateAlarm: High 4 Goto SequenceDone ReleaseAlarm: Low 4 Goto SequenceDone SequenceDone: Pause 20000 GoTo Top DisplayTemp: SerTxD (#DevNum, " ") Whole = TempC_100 / 100 Fract = TempC_100 % 100 If SignBit = 0 Then DisplayTemp_1 SerTxD ("-") DisplayTemp_1: SerTxD (#Whole, ".") ' be sure the fractional is two digits Dig = Fract / 10 SerTxD (#Dig) Dig = Fract % 10 SerTxD (#Dig, 13, 10) Return