2011-01-16 17:40:18 CET
For those, who would like to play with DS18B20 temperature sensor.
It is tested with current GCBASIC.exe 0.9 10/9/2010, graphical program 14/2/2010.
;Variables
Dim TxDta As byte
Dim TEMPH As byte
Dim TEMPL As byte
Dim ACK As byte
Dim Clocks As byte
Dim TH As string
Dim TL As string
Dim Tdec As byte
Dim sign As string
''As inspiration used code of Kent Schafer Feb 12, 2007
''DS18B20 routines for the GCBASIC
''not tested in parasitic mode, tested with pull up resistor 4,7kohm
''tested on PIC16F690 with OSC=INTRC_OSC_NOCLKOUT
''On the same chip it didn't work with xtal 4MHz by the way
''maye be it needs shorter instructions to be able to do correct timing for reading/sending
''because the real code in assembler produced by GCBASIC is a little bit longer,than it appears in GCBASIC
''Distributed with absolutely no warranty, for test purposes
''TEMPH, TEMP are read bytes with temperature in DS18B20 forma
''TH holds integer part of temperature TL holds decimal part of temperature
''Used with 2x16 LCD
CLS
START:
Locate 0, 0
ReadTemperature
If ACK = 255 Then
''the length of both prints is 16 characters
Print "18B20 not found"
Else
''the length of both prints is 16 characters
Print "18B20 present "
End If
Locate 1, 0
''just to clear the line
Print " "
Locate 1, 0
Print "Celsius: "
ConvertTempr
''for testing purposes you can print read TEMPH and TEMPL via LCDHex
''LCDHex(TEMPH)
''LCDHex(TEMPL)
Print sign
Print TH
LCDWriteChar "."
Print TL
Wait 1 s
Goto START
Sub ReadTemperature
MasterRST
PresentPulse
wait 1 ms
WriteByte SkipRom
WriteByte ConvertT
''max time for 12bit resolution is 750ms
wait 1 s
MasterRST
PresentPulse
WriteByte SkipRom
WriteByte ReadScratch
ReadByte
TEMPL = TxDta
ReadByte
TEMPH = TxDta
wait 1 ms
End Sub
'''Master reset low for minimum 480 us
Sub MasterRST
Dir DQ In
Dir DQ Out
Set DQ Off
wait 50 10us
Dir DQ In
''released bus is pulled up by resistor
End Sub
Sub PresentPulse
ACK = 0xff
wait 70 us
If DQ 0 Then
''by ACK = 0 you can test presence of DS18B20
ACK = 0
End if
wait 43 10us
Dir DQ In
End Sub
Sub WriteByte (In Command)
For Clocks = 1 to 8
Dir DQ Out
Set DQ Off
Wait 5 us
''Need to release bus within 5 us
If Command.0 On Then
Dir DQ In
End if
wait 60 us
Dir DQ In
'Bus is still released
wait 3 us
ROTATE Command Right
'The DS18B20 wants data LSB first
Next
End Sub
Sub ReadByte
TxDta = 0
For Clocks = 1 to 8
Rotate TxDta Right
'The DS18B20 transmits data LSB first
Dir DQ Out
Set DQ Off
'Read time slot
Wait 6 us
Dir DQ In
'Release bus for one wire Reception,it means the bus is pulled up by resistor
Wait 9 us
If DQ 1 Then
Set TxDta.7 On
Else
Set TxDta.7 Off
end if
Wait 50 us
Next
End Sub
Sub ConvertTempr
''example of temperature +-48C
''+48C is 0x0300 eg. TEMPH=0x03 TEMPL = 0x00
''-48C is 0xFD00 eg. TEMPH=0xFD TEMPL = 0x00
''sign "+" as default
sign = "+"
''test TEMPH.7 On means, if higher byte of temerature is 0xFxxx, I have to convert negative number to positive
''It means to NEG both bytes TEMPH and TEMPL + add 1
If TEMPH.7 On Then
''sign "-", it is negative temperature
sign = "-"
TEMPH = (255 - TEMPH)
TEMPL = 255 - TEMPL
''Now I have to add +1
If TEMPL = 255 Then
TEMPL = 0
TEMPH = TEMPH + 1
Else
TEMPL = TEMPL + 1
End If
End If
Tdec = TEMPL and 0x0F
TH = str (((TEMPH And 0x0f) * 16) + (TEMPL And 0xf0) /16)
TL = str (100*Tdec/16)
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Tried this program with GCBasic. Got 3 syntax errors. On examination it contains EL:SE statements that GCBasic does not seem to support. Is this program for GCGB which does support ELSE? I'm confused.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Finally got this code working. I'm using a 16f648A with a 16mhz ceramic osc (HS) . Had to change the 4.7K ohm resistor on the 18b20 to a 1.2K ohm. It seems that the DS18b20 requires extra current during the measurement stage.
Also the line
TL = str (100*Tdec/16)
needs to be changed to
TL = str (1000*Tdec/16)
in order to get an accurate output
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello, I am pleased you have tried the code.
To reaction 2. I do not understand, how you can have EL:SE , maybe somehow corrupted copy of program
To reaction 3. To change the line to TL = str (1000*Tdec/16) is perfect from point of view of programer or maths.Super.
But from point of accuracy of DS18B20 one digit after decimal point could be just enough.
Your finding regarding resistor with lower value is interesting, and it is in relationship with http://www.picaxeforum.co.uk/showthread.php?t=14654. I studied DS18B20 datasheet, where in schemas is 4k7 and it worked for me too. Anyway - perfect !!!
To reaction 4. I estimate this is problem of PIC low frequency (and then bad timing, because of the longer code caused by translation from Basic to assembler)
Thanks to all of you. Lada K.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
2011-01-16 17:40:18 CET
For those, who would like to play with DS18B20 temperature sensor.
It is tested with current GCBASIC.exe 0.9 10/9/2010, graphical program 14/2/2010.
;Chip Settings
#chip 16F690,8
#config FCMEN=OFF, IESO=OFF, BOR=OFF, CP=OFF, MCLRE=OFF, PWRTE=ON, WDT=OFF, OSC=INTRC_OSC_NOCLKOUT
;Defines (Constants)
#define DQ PortA.2
#define SearchRom 0xF0
#define ReadRom 0x33
#define MatchRom 0x55
#define SkipRom 0xCC
#define AlarmSearch 0xEC
#define ConvertT 0x44
#define WriteScratch 0x4E
#define ReadScratch 0xBE
#define CopyScratch 0x48
#define RecallE2 0xB8
#define LCD_IO 4
#define LCD_RW PORTC.6
#define LCD_RS PORTC.4
#define LCD_Enable PORTC.5
#define LCD_DB4 PORTC.0
#define LCD_DB5 PORTC.1
#define LCD_DB6 PORTC.2
#define LCD_DB7 PORTC.3
#define LCD_NO_RW
;Variables
Dim TxDta As byte
Dim TEMPH As byte
Dim TEMPL As byte
Dim ACK As byte
Dim Clocks As byte
Dim TH As string
Dim TL As string
Dim Tdec As byte
Dim sign As string
''As inspiration used code of Kent Schafer Feb 12, 2007
''DS18B20 routines for the GCBASIC
''not tested in parasitic mode, tested with pull up resistor 4,7kohm
''tested on PIC16F690 with OSC=INTRC_OSC_NOCLKOUT
''On the same chip it didn't work with xtal 4MHz by the way
''maye be it needs shorter instructions to be able to do correct timing for reading/sending
''because the real code in assembler produced by GCBASIC is a little bit longer,than it appears in GCBASIC
''Distributed with absolutely no warranty, for test purposes
''TEMPH, TEMP are read bytes with temperature in DS18B20 forma
''TH holds integer part of temperature TL holds decimal part of temperature
''Used with 2x16 LCD
CLS
START:
Locate 0, 0
ReadTemperature
If ACK = 255 Then
''the length of both prints is 16 characters
Print "18B20 not found"
Else
''the length of both prints is 16 characters
Print "18B20 present "
End If
Locate 1, 0
''just to clear the line
Print " "
Locate 1, 0
Print "Celsius: "
ConvertTempr
''for testing purposes you can print read TEMPH and TEMPL via LCDHex
''LCDHex(TEMPH)
''LCDHex(TEMPL)
Print sign
Print TH
LCDWriteChar "."
Print TL
Wait 1 s
Goto START
Sub ReadTemperature
MasterRST
PresentPulse
wait 1 ms
WriteByte SkipRom
WriteByte ConvertT
''max time for 12bit resolution is 750ms
wait 1 s
MasterRST
PresentPulse
WriteByte SkipRom
WriteByte ReadScratch
ReadByte
TEMPL = TxDta
ReadByte
TEMPH = TxDta
wait 1 ms
End Sub
'''Master reset low for minimum 480 us
Sub MasterRST
Dir DQ In
Dir DQ Out
Set DQ Off
wait 50 10us
Dir DQ In
''released bus is pulled up by resistor
End Sub
Sub PresentPulse
ACK = 0xff
wait 70 us
If DQ 0 Then
''by ACK = 0 you can test presence of DS18B20
ACK = 0
End if
wait 43 10us
Dir DQ In
End Sub
Sub WriteByte (In Command)
For Clocks = 1 to 8
Dir DQ Out
Set DQ Off
Wait 5 us
''Need to release bus within 5 us
If Command.0 On Then
Dir DQ In
End if
wait 60 us
Dir DQ In
'Bus is still released
wait 3 us
ROTATE Command Right
'The DS18B20 wants data LSB first
Next
End Sub
Sub ReadByte
TxDta = 0
For Clocks = 1 to 8
Rotate TxDta Right
'The DS18B20 transmits data LSB first
Dir DQ Out
Set DQ Off
'Read time slot
Wait 6 us
Dir DQ In
'Release bus for one wire Reception,it means the bus is pulled up by resistor
Wait 9 us
If DQ 1 Then
Set TxDta.7 On
Else
Set TxDta.7 Off
end if
Wait 50 us
Next
End Sub
Sub ConvertTempr
''example of temperature +-48C
''+48C is 0x0300 eg. TEMPH=0x03 TEMPL = 0x00
''-48C is 0xFD00 eg. TEMPH=0xFD TEMPL = 0x00
''sign "+" as default
sign = "+"
''test TEMPH.7 On means, if higher byte of temerature is 0xFxxx, I have to convert negative number to positive
''It means to NEG both bytes TEMPH and TEMPL + add 1
If TEMPH.7 On Then
''sign "-", it is negative temperature
sign = "-"
TEMPH = (255 - TEMPH)
TEMPL = 255 - TEMPL
''Now I have to add +1
If TEMPL = 255 Then
TEMPL = 0
TEMPH = TEMPH + 1
Else
TEMPL = TEMPL + 1
End If
End If
Tdec = TEMPL and 0x0F
TH = str (((TEMPH And 0x0f) * 16) + (TEMPL And 0xf0) /16)
TL = str (100*Tdec/16)
End Sub
Tried this program with GCBasic. Got 3 syntax errors. On examination it contains EL:SE statements that GCBasic does not seem to support. Is this program for GCGB which does support ELSE? I'm confused.
Finally got this code working. I'm using a 16f648A with a 16mhz ceramic osc (HS) . Had to change the 4.7K ohm resistor on the 18b20 to a 1.2K ohm. It seems that the DS18b20 requires extra current during the measurement stage.
Also the line
TL = str (100*Tdec/16)
needs to be changed to
TL = str (1000*Tdec/16)
in order to get an accurate output
Same setup as above (1.2k ohm pullup) did not work with 4mhz int_osc. I plan to try a 16f628, 16f88 and others.
Hello, I am pleased you have tried the code.
To reaction 2. I do not understand, how you can have EL:SE , maybe somehow corrupted copy of program
To reaction 3. To change the line to TL = str (1000*Tdec/16) is perfect from point of view of programer or maths.Super.
But from point of accuracy of DS18B20 one digit after decimal point could be just enough.
Your finding regarding resistor with lower value is interesting, and it is in relationship with http://www.picaxeforum.co.uk/showthread.php?t=14654. I studied DS18B20 datasheet, where in schemas is 4k7 and it worked for me too. Anyway - perfect !!!
To reaction 4. I estimate this is problem of PIC low frequency (and then bad timing, because of the longer code caused by translation from Basic to assembler)
Thanks to all of you. Lada K.
Hi I just posted fully functional code at this link:
https://sourceforge.net/p/gcbasic/discussion/629990/thread/66f6fe4e/
it only works with one sensor on the bus as the serial number is a bit unwieldy to handle.
Maybe define a second pin for a second ds18b20 .
A series of select case statements can direct the subroutine to the relevant ds18b20 on either pin