PicBasic Pro, PicBasic, BASIC Stamp, Microchip PIC, 8051, and Remote Control Projects

-- Communicating With Multiple 1-Wire Devices  --

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.

bullet

Task #1 - Mode #1 [byte-sized data, reset pulse before data]

bullet

Reset the 1-wire bus, and end communications with any previous 1-wire devices.

bullet

Get the attention of all 1-wire devices present on the bus.

bullet

Issue the Match ROM command $55

bullet

Send ROM code of $28,$B1,$FE,$22,$00,$00,$00,$5D

bullet

Issue the Read Scratchpad Memory command $BE to the DS18B20

OWOUT DQ, 1,[$55,$28,$B1,$FE,$22,$00,$00,$00,$5D,$BE]

bullet

Task #2 - Mode #2 [byte-sized data, reset pulse after data]

bullet

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.

bullet

It converts temperatures from °C to °F for display on the serial 20 x 4 LCD

bullet

It will display - °F temperatures

bullet

It toggles both DS2405 switch outputs turning each LED ON/OFF

bullet

It displays the temperature of both DS18B20 temperature sensors

bullet

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:

bullet

Zoned damper control for two individual rooms with temperature & damper status display.

bullet

Displaying temperatures in two separate zones.

bullet

Remote control of two independent addressable networked switches.

bullet

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.

bullet

A starting point for a much larger networked temperature & control system.

Get creative......!

Connections to the PIC

bullet

PortC.0 to 1-Wire Data Bus connection as shown in schematic

bullet

PortB.0 to serial LCD data input-pin

Notes:

bullet

If you're not using the meLabs boot-loader, remove the line DEFINE loader_used 1

bullet

If you're not using a serial LCD, you can remove all of the lines between the Stat & Sign variables.

bullet

Change the oscillator speed setting in this line if you're not using a 4MHz oscillator DEFINE osc 4

bullet

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.

  BASIC Stamp, Microchip PIC, 8051, and Remote Control Mailing-List"Micro-News"BASIC Stamp, Microchip PIC, 8051, and Remote Control Mailing-List
   Micro-Mailing-List

Copyright © 1999-2008 Reynolds Electronics

| Contact Information |