• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

DS18B20 – Reading from Multiple Sensors

    Blog entry posted in 'Electronics and Other Ramblings...', November 22, 2012.

    I’ve been meaning to work with the DS18B20 1Wire device from Maxim for a while now. During an information exchange with a fellow user on the forum on reading multiple DS18B20s I decided to take the plunge. I ordered 10 devices from some “reputable” far east vendor on eBay. The parts (along with some much needed relays) came in a short 10days.

    Parts came in right before the Thanksgiving holiday (what a break). What are we supposed to do but give them a try. I checked each of them and all seem to operate ok. To address multiple 1Wire DS18B20 devices using an MCU a few options are available:
    • connect each device to individual pins on the MCU,
    • connect all devices to one pin through a multiplexer (two or more extra MCU pins are required for addressing),
    • connect all devices to one pin an address each through 1Wire commands.

    To address all DS18B20 using the same MCU pin, I followed the guidelines from Reynolds Electronics to read the ROM from each device so each device could be addressed on the same bus (credit also to Heckler@PBP). After reading the ROM code for each of the individual DS18B20, each can then be addressed through the 1Wire commands.

    Three sensors were connected and their ROM codes read.
    sensor1
    FC = 28h, CRC = 89h
    S/N = 2A 83 4E 04 00 00
    ROM CODE: 28 2A 83 4E 04 00 00 89


    sensor2
    FC = 28h, CRC = FFh
    S/N = 64 50 4E 04 00 00
    ROM CODE: 28 64 50 4E 04 00 00 FF


    sensor3
    FC = 28h, CRC = 7Ch
    S/N = 6B 0A 4F 04 00 00
    ROM CODE: 28 6B 0A 4F 04 00 00 7C


    The code to measure the temperature was updated to address each sensor, and the temperature read.
    T = +26.2
    T = +26.1
    T = +26.1


    Below is the code used to read the ROM code from each device (using PIC18F1320 and Oshonsoft).

    Code:
    'Port I/O definition
    Symbol io_rs232 = RB7

    'variable definition
    Dim temp_w As Word
    Dim temp_b As Byte
    Dim romdata(8) As Byte
    Dim cnt As Byte

    'constant definition
    Const readrom = $33 'read ID, serial num, CRC
    Const matchrom = $55 'look for specific device
    Const skiprom = $cc 'skip rom (one device)
    Const converttemp = $44 'do temperature conversion
    Const readscratch = $be 'read DS1820 scratchpad

    main:
    AllDigital
    'setup port B for 1-wire use
    Define 1WIRE_REG = PORTB
    Define 1WIRE_BIT = 0

    'setup rs232 output
    Config io_rs232 = Output

    WaitMs 5000
    Serout io_rs232, 9600, "Start...", CrLf

    'acquire ROM data
    Serout io_rs232, 9600, "1Wire Init...", CrLf
    1wireInit
    1wireSendByte readrom
    For cnt = 0 To 7
    1wireGetByte romdata(cnt)
    Next cnt

    'display on rs232
    Serout io_rs232, 9600, "FC = "
    temp_b = romdata(0)
    temp_w = byte2hex(temp_b)
    Serout io_rs232, 9600, temp_w.HB, temp_w.LB, "h, CRC = "
    temp_b = romdata(7)
    temp_w = byte2hex(temp_b)
    Serout io_rs232, 9600, temp_w.HB, temp_w.LB, "h", CrLf
    Serout io_rs232, 9600, "S/N = "
    For cnt = 1 To 6 Step 1
    temp_b = romdata(cnt)
    temp_w = byte2hex(temp_b)
    Serout io_rs232, 9600, temp_w.HB, temp_w.LB, " "
    Next cnt
    Serout PORTB.1, 9600, "h", CrLf

    End

    'Convert byte to HEX for ASCII display
    Function byte2hex(num As Byte) As Word
    Dim hexh As Byte
    Dim hexl As Byte
    hexh = num And 0xf0
    hexh = ShiftRight(hexh, 4)
    byte2hex.HB = nibble2hex(hexh)
    hexl = num And 0x0f
    byte2hex.LB = nibble2hex(hexl)
    End Function

    'Convert HEX nibble to ASCII and display
    Function nibble2hex(num As Byte) As Byte
    If num <= 9 Then
    nibble2hex = num + 30h
    Else
    nibble2hex = num + 37h
    Endif
    End Function


    Following is the code used to read the temperature from each of the three DS18B20s connected to the same MCU pin (using PIC18F1320 and Oshonsoft).
    Code:
    'variable definition
    Dim temperature As Word
    Dim frac_d1 As Word
    Dim cnt As Byte
    Dim sign_char As Byte
    Dim sign_bit As Bit
    Dim finish As Bit

    'Port I/O definition
    Symbol io_rs232 = RB7

    'constant definition
    Const readrom = 0x33 'read ID, serial num, CRC
    Const matchrom = 0x55 'look for specific device
    Const skiprom = 0xcc 'skip rom (one device)
    Const converttemp = 0x44 'do temperature conversion
    Const readscratch = 0xbe 'read DS1820 scratchpad

    main:
    AllDigital
    'setup port B for 1-wire use
    Define 1WIRE_REG = PORTB
    Define 1WIRE_BIT = 0

    'setup rs232 output
    Config io_rs232 = Output

    WaitMs 5000
    Serout io_rs232, 9600, "Start...", CrLf

    read_temp:
    'request temperature conversion
    Serout io_rs232, 9600, "1Wire Init...", CrLf
    Dim temperature_array(3) As Word
    For cnt = 0 To 2
    1wireInit
    If cnt = 0 Then
    1wireSendByte matchrom, 0x28, 0x2a, 0x83, 0x4e, 0x04, 0x00, 0x00, 0x89, converttemp
    Endif
    If cnt = 1 Then
    1wireSendByte matchrom, 0x28, 0x64, 0x50, 0x4e, 0x04, 0x00, 0x00, 0xff, converttemp
    Endif
    If cnt = 2 Then
    1wireSendByte matchrom, 0x28, 0x6b, 0x0a, 0x4f, 0x04, 0x00, 0x00, 0x7c, converttemp
    Endif

    finish = 0
    wait:
    1wireGetBit finish
    If finish = 0 Then Goto wait
    'request temperature byte
    1wireInit
    If cnt = 0 Then
    1wireSendByte matchrom, 0x28, 0x2a, 0x83, 0x4e, 0x04, 0x00, 0x00, 0x89, readscratch
    Endif
    If cnt = 1 Then
    1wireSendByte matchrom, 0x28, 0x64, 0x50, 0x4e, 0x04, 0x00, 0x00, 0xff, readscratch
    Endif
    If cnt = 2 Then
    1wireSendByte matchrom, 0x28, 0x6b, 0x0a, 0x4f, 0x04, 0x00, 0x00, 0x7c, readscratch
    Endif

    1wireGetByte temperature.LB, temperature.HB
    temperature_array(cnt) = temperature
    Next cnt

    'display temperature
    For cnt = 0 To 2
    temperature = temperature_array(cnt)
    'sign bit
    sign_bit = temperature.11
    If sign_bit = True Then
    temperature = Not temperature
    frac_d1 = ((temperature Mod 16) * 10 + 8) / 16 'adds 8 to the mod result to round-up
    temperature = temperature / 16
    sign_char = "-"
    Else
    temperature = temperature And 0b0000011111111111
    frac_d1 = ((temperature Mod 16) * 10 + 8) / 16 'adds 8 to the mod result to round-up
    temperature = temperature / 16
    sign_char = "+"
    Endif

    'display on rs232
    Serout io_rs232, 9600, "T = ", sign_char, #temperature, ".", #frac_d1, CrLf
    Next cnt

    Goto read_temp
    End


    Connection diagram shown below for reference.
    70216

    Comments
    Micheal_Up, December 03, 2012
    The [URL="http://www.hqew.net/product-data/DS18B20/"]DS18B20[/URL] digital thermometer provides 9-bit to 12-bit Celsius temperature measurements and has an alarm function with nonvolatile user-programmable upper and lower trigger points. More information about at [URL="http://www.hqew.net/product-data/DS18B20/DS18B20-DataSheet.html"]Datasheet[/URL]. More information about at [URL="http://www.hqew.net/product-data/DS18B20/DS18B20-CircuitDiagram.html"]Circuit Diagram[/URL].
 

EE World Online Articles

Loading

 
Top