Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

1-Wire USB Interface

4.81/5 (11 votes)
16 Feb 2010CPOL3 min read 111.6K   5.4K  
1-wire USB interface to read the temperature from a DS18B20 sensor in VB6.
Basic application view:

proge.JPG

Introduction

I did not find any USB based 1-wire interface on the net, so I read the instructions and made one. Originally I wrote the code in C, but because I needed an interface in VB6, I rewrote it. The idea behind this is to use a USB-to-RS232 adapter and the copyrighted 'IBFS32.dll' from Maxim 1-Wire SDK. All you need is two transistors and two resistors to make it work. The adapter I use is a 'USB-Serial CH340' which is very cheap, and I made a virtual COM17 port. I was able to power up a 1-wire device from my USB adapter (GRD, 5VDC from computer) and using RX, TX from RS232 (pin2 and pin3). Also, I soldered the oscillator crystal to the other side of the board.

IMG003_s.JPG

More pictures: prototype board1, board2, board3.

Schematics:

Schematic2.JPG

Background

Using the Code

As this was a cheap adapter, it was not possible to use COM17. Instead, I opened COM3, and there you go. I was able to read temperature from the 18b20.

VB
RetValue = TMReadDefaultPort(PortNum, PortType)
If (RetValue < 1) Then
    PortNum = 3  '// COM 3
    PortType = 1 '// DS9097E style adapter
End If

When executing the program from command line, you can modify the port number and port type like this:

'DS18b20.exe <portnumber> <porttype> '. ('DS18b20.exe 3 1')

The available options for the type are in 'OneWire.h':

OW_ADAPTER_DS9097 = 1,  (we are really using only this one)
OW_ADAPTER_DS1413 = 2,
OW_ADAPTER_DS9097E = 3,
OW_ADAPTER_DS9097U = 4,
OW_ADAPTER_DS9097U9 = 5,
OW_ADAPTER_DS1411 = 6,
OW_ADAPTER_DS1410D = 7,
OW_ADAPTER_DS1410E = 8

Because virtual adapters are not implemented for OW_ADAPTER_DS9097, we can only use numbers that are less then 15. When reading the sensor, we can also use interrupts to determine when the data is ready. To use this feature, we must power the sensor with power 5VDC (not with parasite power). In parasite power mode, the sensor is not sending the data ready signal to be processed. Instead, data from the sensor is read using time slots, which depends on the temperature accuracy used:

to accuracy 0.5°C - 93,75 ms, 0.25°C - 187,5 ms,
0.125°C - 375 ms,
and for 0.0625°C - 750 ms

In the FindDevices procedure, we can read familycode from the ROM last byte: which in DS18b20 is '28h', DS18s20 is '10h', and 'DS2780' accordingly '32h' etc.

VB
Public Function FindDevices() As Integer
    Dim didsetup As Integer, result As Integer, DevId As Integer, i As Integer
    ReDim ROM(8) As Integer
    If SHandle > 0 Then
        result = TMSetup(SHandle)
    If Not (result = 1) Then FindDevices = 1
    ' only get the next rom after setup complete
    result = TMNext(SHandle, state_buffer(0))
    If result > 0 Then
        SelectROM(0) = 0
        result = TMRom(SHandle, state_buffer(0), SelectROM(0))
        For i = 0 To 7
                Debug.Print "SelectROM(" & i & ") = " & SelectROM(i)
        Next i
        If SelectROM(0) = 40 Then Debug.Print "DS18b20 detected"
        If SelectROM(0) = 50 Then Debug.Print "DS2780 detected"
            FindDevices = 0
        End If
    Else
        FindDevices = 1
    End If
End Function

So by modifying the code, we can read any sensor data and write it to EEPROM. Like in DS18b20, we can alter the precision of the temperature.

The resolution of the temperature sensor is user-configurable to 9, 10, 11, or 12 bits, corresponding to increments of 0.5°C, 0.25°C, 0.125°C, and 0.0625°C, respectively. The default resolution at the power-up is 12-bit.

VB
If Not (res = DS18B20_RES_10) Then
    WriteScratchpad DS18B20_RES_10, 0, 20
    CopyScratchpadToEEPROM
End If

The command to do this is in the WriteScratchPad() function:

VB
Select Case res
     Case DS18B20_RES_9: TMTouchByte SHandle, 31
     Case DS18B20_RES_10: TMTouchByte SHandle, 63
     Case DS18B20_RES_11: TMTouchByte SHandle, 95
     Case DS18B20_RES_12: TMTouchByte SHandle, 127
     Case Else: TMTouchByte SHandle, 31
End Select

Points of Interest

When using Jakub Piwowarczyk's code, I wondered about the CPU process usage when the reading temperature from the sensor reached 50%. When I substituted the function 'GetTickCount()' with 'MsgWaitForMultipleObjects()', I got the process usage down to 1%. This is a known bug in asynchronous processing, when processes are halted from running.

Now I can attach my devices that use the 1-Wire protocol to my computer USB port.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)