Basic application view:
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.
More pictures: prototype board1, board2, board3.
Schematics:
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.
RetValue = TMReadDefaultPort(PortNum, PortType)
If (RetValue < 1) Then
PortNum = 3
PortType = 1
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.
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
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.
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:
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.