This project shows how to
communicate with multiple 1-wire devices on a 1-wire network, and how the
PicBasic Pro MODE commands affect 1-wire communications.
The Schematic
Shown above is a simple
schematic for a 1-wire network. This shows how you might connect multiple
1-wire components on a small network such as the bread board, or short
wire network.
Notice from the schematic
how the DS2405 addressable switch outputs are connected to 2N3904 NPN
transistors. This is because the DS2405 outputs can only provide about 4mA
sink [ground] output current. The 2N3904 NPN transistors allow the DS2405
limited capacity outputs to easily control higher current devices.
Since the open-drain outputs
of the DS2405 addressable switches cannot produce a logic 1 output, the
10K pull-up resistors are included to pull the NPN transistor base to
logic 1, and turn on the LEDs. When the DS2405 output is on, it will apply
ground to the base of the NPN transistors, turning the LEDs off.
PicBasic
Pro 1-Wire Command Mode Switches
The 1-wire
commands in PicBasic Pro include mode switches for controlling the reset
pulses, and data formats for the 1-wire bus. The printed PBP manual shows
the mode configurations like this:
Mode Bit Number |
Effect |
0 |
1 = send
reset pulse before data |
1 |
1 = send
reset pulse after data |
2 |
0 =
byte-sized data, 1 = bit-sized data |
Some people seem confused by
this, so I'll show it in a different format like this:
Mode Bit Number |
Decimal Value |
Effect |
2 |
1 |
0 |
0 |
0 |
0 |
0 |
Byte-sized data, no reset pulse |
0 |
0 |
1 |
1 |
Send
reset pulse before byte-sized data |
0 |
1 |
0 |
2 |
Send
reset pulse after byte-sized data |
0 |
1 |
1 |
3 |
Send
reset pulse before & after byte-sized data |
1 |
0 |
0 |
4 |
Bit-sized
data, no reset pulse |
1 |
0 |
1 |
5 |
Send
reset pulse before bit-sized data |
1 |
1 |
0 |
6 |
Send
reset pulse after bit-sized data |
1 |
1 |
1 |
7 |
Send
reset pulse before & after bit-sized data |
This effectively gives us 8
possible
modes of operation with the PicBasic Pro 1-wire commands. Here's why we
would want separate modes when communicating with 1-wire
components.
Once we have established
communications with a specific 1-wire device on the network by issuing the
Match ROM command, followed by the unique 64-bit ROM code for a specific
1-wire component, the rest of the 1-wire devices on the network will
ignore all data placed on the 1-wire communications bus until a 1-wire bus
RESET has been issued.
Reset,
Bit, and Byte Modes & Why We Need Them
The reset pulse is used to
end communications with a specific device on the network, and also to get
the attention all 1-wire devices on the network. Think of a reset pulse as
being OK, we're finished, now everyone else listen up. Byte-sized data
informs the compiler that all data being sent/received on the 1-wire
network will be in byte-sized data packets.
The reset pulse simply
resets all 1-wire devices on the network, and gets them all to ready
receive commands.
Example:
OWOUT DQ, 1, [$33] ' Read ROM command,
byte-sized data, reset before data
This
will reset the 1-wire bus, [Send reset pulse before byte-sized data], and
issue the byte-sized Read ROM command. This will work [only] if there is a
single 1-wire device on the network. If there are more than a single
1-wire device on the network, we need to do the following:
Switch_1:
OWOUT DQ, 1, [$55,$05,$C5,$C3,$08,$00,$00,$00,$CD]'
Match ROM, byte-sized, reset before
OWIN DQ, 4, [Stat]' Get bit-sized response,
no reset pulse
IF Stat = 0 THEN
DEBUG Ins, Line2, "Switch #1 = OFF"
ELSE
DEBUG Ins, Line2, "Switch #1 = ON "
ENDIF
The
example above shows how to individually address 1 DS2405 addressable
1-wire switch on the network. Notice we have substituted the Read ROM
command with the Match ROM command. The red hexadecimal number
$55
is the command for Match
ROM. The blue hexadecimal numbers
$05,$C5,$C3,$08,$00,$00,$00,$CD
are the unique 64-bit
ROM code numbers inside the specific DS2405 addressable 1-wire switch
we're trying to communicate with.
What
we're doing with -->
OWOUT DQ, 1, [$55,$05,$C5,$C3,$08,$00,$00,$00,$CD]is:
Attention, Match the following ROM code. Were leaving the 1-wire bus open
for communications since we didn't RESET the 1-wire bus after we
have sent several byte-sized data packets containing the ROM code. The device
matching the ROM code [as shown in blue above], will respond if it's
present on the 1-wire bus.
What
we're doing with -->
OWIN DQ, 4, [Stat]is: Reading the
bit-sized data from the 1-wire bus into the bit-sized variable
Stat, without issuing a reset pulse. The DS2405 will return a logic 0 on
the 1-wire bus if its switch output PIO is ON or at logic 0. If the switch
output is OFF, the DS2405 will return bit-sized data at logic 1,
indicating to the Master controller that its switch output is OFF. Refer
to the schematic at top again, and you'll notice that logic 0 will turn
the NPN transistors OFF, and logic 1 will turn them ON again.
If you
jumped into this page without reading the previous article showing how to
read individual ROM codes from 1-wire components, visit this link
HERE to see how this is done. You'll need to
individually identify each of the 1-wire component unique 64-bit ROM codes
before you can make sense of this article. Knowing the unique 64-bit ROM
codes for all devices you're using [if you're building this project], is
essential.
Let's
move on to more of the mode switches, and see how they work with the
DS18B20 temperature sensor on the 1-wire network.
Temp_1:
OWOUT DQ, 1, [$55,$28,$B1,$FE,$22,$00,$00,$00,$5D,$44]
W1:
OWIN DQ, 4, [Stat]' Check for still busy converting
IF Stat = 0 THEN W1' Still busy?, then loop
OWOUT DQ, 1,[$55,$28,$B1,$FE,$22,$00,$00,$00,$5D,$BE]
OWIN DQ, 2, [Temp.LOWBYTE,Temp.HIGHBYTE]' Read two bytes, then end communications
GOSUB Convert_Temp
DEBUG Ins,Line1, "Temp #1 = ", Sign, DEC (Temp / 100),".", DEC2 Temp, Deg, "F "
Notice
from the code sample above that we have again issued the Match ROM command
$55,
and left the 1-wire bus open
for communications. We next use mode 4 [bit-sized data, no reset pulse],
and
OWIN
command to read the bit-sized response from the device addressed with the
unique 64-bit ROM code
$28,$B1,$FE,$22,$00,$00,$00,$5D .
Did
you notice that the
$44
is missing from end
of the original first line of code?
$44
is the last byte of
data sent to the DS18B20 after the ROM code, and is telling the DS18B20 to
begin a temperature conversion. I have made commands
RED,
and data BLUE
for easy recognition.
What
we're doing here -->
OWIN DQ, 4, [Stat] :
is reading the bit-sized response from the DS18B20.
A logic 0 means the DS18B20 is still performing the
temperature conversion, so we wait until it's finished before proceeding.
Notice
how mode 4 allows us to read single-bit responses from the 1-wire bus
without resetting the bus. This is important to remember if you're going
to build a reliable 1-wire network. Sometimes the Master 1-wire controller
will be required to read single-bit data, and be able to control [reset or
no reset] the 1-wire bus as necessary. That's why it's important to
carefully read the datasheet for any 1-wire device you're planning to use,
and learn how to use the PicBasic Pro 1-wire command mode switches.
Now
We'll Use Mode 2
Remember how mode 2 will send a reset pulse after sending data, and
mode 1 sends the reset pulse before sending data? This is
important, and here's why:
The
reset pulse gets the attention of each device on the 1-wire network, and
also terminates any communications with a previous device. The next couple
lines of code perform the following tasks.
|
Task #1 - Mode #1
[byte-sized data, reset pulse
before data]
|
Reset
the 1-wire bus, and end communications with any previous 1-wire devices.
|
|
Get
the attention of all 1-wire devices present on the bus.
|
|
Issue
the Match ROM command
$55
|
|
Send
ROM code of
$28,$B1,$FE,$22,$00,$00,$00,$5D
|
|
Issue
the Read Scratchpad Memory command
$BE
to the DS18B20
|
|
OWOUT DQ, 1,[$55,$28,$B1,$FE,$22,$00,$00,$00,$5D,$BE]
|
Task #2 - Mode #2
[byte-sized data, reset pulse
after data]
|
Read
"only" two bytes, then end communications immediately
|
|
OWIN DQ, 2, [Temp.LOWBYTE,Temp.HIGHBYTE]' Read two bytes, then end communications
The
sample does pretty much the same thing we have been doing previously with
the first line of code, but does something a little different in line #2.
If you look at the datasheet for the DS18B20, you'll notice that once the
Read Scratchpad Memory command is issued, the DS18B20 will output all
9-bytes of data in the scratchpad memory, [unless] the master issues a
reset pulse during the transaction. Once the master issues the reset
pulse, the device will end communications.
We're
only concerned with the first two data-bytes [as shown below] containing
the temperature results, so we end communications after reading only these
two bytes by issuing the reset pulse [after reading two bytes].
Mode
#2 allows reading only as much data from a device as necessary for a
specific operation, then terminating communications with the 1-wire
component. Mode 2 can cut down the time required for 1-wire bus
communications, and is handy to remember. No sense reading 7 additional
bytes of data if we really don't need it for a specific task.
That pretty
much covers it. Examine the complete code sample below, and you'll see how
first knowing the unique 64-bit numbers [ROM Code] contained within each Dallas
1-wire component comes in handy for accessing each device on the 1-wire
network individually.
The code
sample below has several features.
|
It converts
temperatures from °C to °F for display on the serial 20 x 4 LCD
|
|
It will
display - °F temperatures
|
|
It toggles
both DS2405 switch outputs turning each LED ON/OFF
|
|
It displays
the temperature of both DS18B20 temperature sensors
|
|
It displays
the ON/OFF status of each DS2405 addressable switch on the network in
real-time
|
Possible
uses for this project include, but are not limited to:
|
Zoned damper
control for two individual rooms with temperature & damper status display.
|
|
Displaying
temperatures in two separate zones.
|
|
Remote
control of two independent addressable networked switches.
|
|
Ceiling fan
control to equalize temperatures in lower room. Turn on ceiling fan when
temperature is above a certain temperature to move warm air to the lower
section of the
room.
|
|
A starting
point for a much larger networked temperature & control system.
|
Get
creative......!
Connections to the PIC
|
PortC.0 to
1-Wire Data Bus connection as shown in schematic
|
|
PortB.0 to
serial LCD data input-pin
|
Notes:
|
If you're not using the meLabs boot-loader, remove the line
DEFINE loader_used 1
|
|
If you're not using a serial LCD, you can remove all
of the lines between the Stat & Sign variables.
|
|
Change the oscillator speed setting in this line if you're not using a
4MHz oscillator DEFINE osc 4
|
|
If you don't own the PicBasic Pro
compiler, and want to get in on this action, we have them
HERE.
|
Have
fun with the project. You may want to visit the Dallas/Maxim web site, and
download datasheets for each 1-wire device you're using. You can find this
information here http://www.maxim-ic.com
I most highly recommend downloading every datasheet for the 1-wire devices
you're using, and thoroughly reading each one to become familiar with
specific register settings, and the specifics for each 1-wire component.
Explaining this all in detail here would take me months....;o]
The
Code
'****************************************************************
'* Name : 1-WireT.Bas *
'* Author : Bruce Reynolds *
'* Date : 11/26/2001 *
'* Version : 1.0 *
'* Notes : 1-Wire Temperature & Addressable Switch Sample *
'* : Uses 20 x 4 Serial LCD for Display *
'****************************************************************
DEFINE LOADER_USED 1 ' Boot loader is being used
DEFINE DEBUG_MODE 1 ' Send Inverted serial data with debug
DEFINE DEBUG_REG PortB ' Debug Port = PortB
DEFINE DEBUG_BIT 0 ' Debug.bit = PortB.0
DEFINE DEBUG_BAUD 9600 ' Default baud rate = 9600
DEFINE OSC 4 ' We're using a 4 MHz oscillator
DQ VAR PortC.0 ' One-wire data pin "DQ" on PortC.0
Stat VAR BIT ' Busy or not bit
Deg CON 223 ' Data to display "Deg" symbol
Clr CON 1 ' Serial LCD commands
LINE1 CON 128 ' Line #1 of serial LCD
LINE2 CON 192 ' Line #2 of serial LCD
LINE3 CON 148 ' Line #3 of serial LCD
LINE4 CON 212 ' Line #4 of serial LCD
Ins CON 254 ' End serial LCD commands
Sign VAR BYTE ' + or - temp indicator
Temp VAR WORD ' Temp storage
Begin:
PAUSE 500 ' Wait .5 [1/2] seconds
DEBUG Ins,Clr ' Clear LCD on power-up
Switch_1:
OWOUT DQ, 1, [$55,$05,$C5,$C3,$08,$00,$00,$00,$CD]
OWIN DQ, 4, [Stat]' Check switch status ON/OFF
IF Stat = 0 THEN
DEBUG Ins, Line2, "Switch #1 = OFF"
ELSE
DEBUG Ins, Line2, "Switch #1 = ON "
ENDIF
PAUSE 500
Switch_2:
OWOUT DQ, 1, [$55,$05,$B3,$BF,$08,$00,$00,$00,$AB]
OWIN DQ, 4, [Stat]' Check switch status ON/OFF
IF Stat = 0 THEN
DEBUG Ins, Line4, "Switch #2 = OFF"
ELSE
DEBUG Ins, Line4, "Switch #2 = ON "
ENDIF
PAUSE 500
Temp_1:
OWOUT DQ, 1, [$55,$28,$B1,$FE,$22,$00,$00,$00,$5D,$44]
W1:
OWIN DQ, 4, [Stat]' Check for still busy converting
IF Stat = 0 THEN W1' Still busy?, then loop
OWOUT DQ, 1,[$55,$28,$B1,$FE,$22,$00,$00,$00,$5D,$BE]
OWIN DQ, 2, [Temp.LOWBYTE,Temp.HIGHBYTE]' Read two bytes, then end communications
IF Temp.bit15 = 1 THEN Below_32 ' Check for temp below 0°C
W2: Sign = "+"
Temp = ((((Temp >> 4) + 50) * 9) /5) -58
DEBUG Ins,Line1, "Temp #1 = ", Sign, DEC Temp,".", DEC2 Temp, Deg, "F "
Temp_2:
OWOUT DQ, 1, [$55,$28,$C1,$03,$23,$00,$00,$00,$00,$44]
W3:
OWIN DQ, 4, [Stat]' Check for still busy converting
IF Stat = 0 THEN W3' Still busy?, then loop
OWOUT DQ, 1, [$55,$28,$C1,$03,$23,$00,$00,$00,$00,$BE]
OWIN DQ, 2, [Temp.LOWBYTE,Temp.HIGHBYTE]' Read two bytes, then end communications
IF Temp.bit15 = 1 THEN Below_32B ' Check for temp below 0°C
W4: Sign = "+"
Temp = ((((Temp >> 4) + 50) * 9) /5) -58
DEBUG Ins,Line3, "Temp #2 = ", Sign, DEC Temp, ".", DEC2 Temp, Deg, "F "
GOTO Switch_1
Below_32:
Temp = ~Temp >> 4
Temp = (((-Temp + 50)* 9) /5) - 58
DEBUG Ins,Line1, "Temp #1 = ", Sign, DEC Temp,".", DEC2 Temp, Deg, "F "
GOTO Temp_2
Below_32B:
Temp = ~Temp >> 4
Temp = (((-Temp + 50)* 9) /5) - 58
DEBUG Ins,Line3, "Temp #2 = ", Sign, DEC Temp,".", DEC2 Temp, Deg, "F "
GOTO Begin
END
There are several calculations you can use for converting °C to °F, but the limitations of integer math, and no floating
point results are somewhat inefficient. Displaying the temperature in °F means loosing accuracy. In °C you can maintain
accuracy.
These °C to °F conversions will work also with limitations. For the DS18B20, shift the middle 8-bits of Temp right by 4
or extract them directly. For the DS1820 or DS18S20, just use the lower byte. Bit.15 for this series temp sensor indicates
below 0°C [1] or above 0°C [0]. Temp = ((((Temp >> 4) + 50) * 9) /5) -58 ' for above 0 °C
Sign = "+"
debug Sign, dec Temp," F" and temperatures below 0 °C [This works down to -17 °C or 1.4 °F] Temp = ~Temp >> 4
Temp = ((((-Temp + 50)* 9) /5) -58)
Sign = "+"
debug Sign, dec Temp," F",10,13 For the DS18B20 and DS18S20 temperature results held in internal registers are inverted for below 0°C. The DS18B20
has up to 12-bit resolution. The DS18S20 has up to 9-bit resolution. Refer to the datasheet for detailed explanations.
The main code for this project assumes you're using the DS18B20, and requires modification for use with the DS1820
or DS18S20. Temp >> 4 shifts the middle 8-bits of the DS18B20 temperature result into the lower 8-bit position of the variable,
discarding the lower 4-bit result before the conversion. For 100% precise results in °F, you need a lookup table. For
°C it's much easier.
Note: Project #3 in this series shows how to get very precise calculations from °C to °F, will display the full-range
of temperatures from +125 to -55 °C, and converts the full-range from °C to °F. Project #3 is located here. The Results
Here's what your serial LCD display will show [if you're using a 20 x 4 serial LCD], and using this code unmodified,
with 2 x DS18B20 temperature sensors, and 2 x DS2405 addressable switches.
The switch status displays will alternate from ON - OFF, and the LEDs' will blink for visual status indication of each
switch output. The temperatures will change when you touch individual DS18B20's. This project would be easy to
modify, and have the switches close or open based on temperature readings for zoned damper controls, and more. Project #3 HERE goes into detail on how to display the full-range of temperatures with the DS18B20 in °C & °F with
a nifty trick using the PicBasic Pro DIV32 function. This project code shows very precise conversions of [1/16 °C]
resolution, and can easily be integrated into this project with multiple 1-wire devices. |