PIC16F877A + 6x DS18S20 + mikroBasic
-
- Posts: 361
- Joined: 14 Dec 2005 20:56
- Location: Slovenia
PIC16F877A + 6x DS18S20 + mikroBasic
Hi everybody,
I have a problem in connection more then one DS18S20 to the PIC. I want to make control sistem for temperature. So if someone can help mi with explanation or with simple example in mikroBasic, I would be very grateful to him.
Have a nice day!
I have a problem in connection more then one DS18S20 to the PIC. I want to make control sistem for temperature. So if someone can help mi with explanation or with simple example in mikroBasic, I would be very grateful to him.
Have a nice day!
Hi, take a look here
http://www.mikroe.com/forum/viewtopic.p ... ple+ds1820
http://www.mikroe.com/forum/viewtopic.p ... ple+ds1820
-
- Posts: 361
- Joined: 14 Dec 2005 20:56
- Location: Slovenia
Here is some code that I wrote for a similar situation, I don't know if this is the latest or even if it works, but it would give you a hint
//Sonar
Code: Select all
program Temp_Read
symbol OWP = PORTE
symbol PIN = 2
'
dim T1 as byte[8]
dim T2 as byte[8]
'
dim b,iCnt,j1,j2,xCnt, minus as byte
dim M0, M1, M2, M3 as byte
dim ID as byte[8]
dim Temp as integer
'dim TempF as float
dim slask as string[20]
dim text as char[14]
dim st as char[3]
'
dim Raw_temp,TempC, decimal as word
'
'
sub Procedure SetID(dim xID as byte[8])
'
for xCnt = 0 to 7
b = xID[xCnt]
ID[xCnt] = b
next xCnt
'
end sub
sub procedure Ser_Out(dim byref xID as byte[8])
'
for iCnt = 0 to 7
b = xID[iCnt]
Ow_Write(OWP, PIN, b) ' ... should work?
delay_ms(10)
next iCnt
'
end sub
sub procedure Word2Str(dim count as word)
dim rest as byte
'
rest = count mod 10
M3 = rest + 48
count = count div 10
rest = count mod 10
M2 = rest + 48
count = count div 10
rest = count mod 10
M1 = rest + 48
count = count div 10
rest = count mod 10
M0 = rest + 48
count = count div 10
end sub
sub function GetTemp(dim byref xID as byte[8]) as integer
'
Ow_Reset(OWP, PIN)
' Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd
Ow_Write(OWP, PIN, $55) ' MATCH-ROM cmd
'Delay_us(120)
Ser_Out(xID) ' Send serialnumber
delay_us(120)
Ow_Write(OWP,PIN,$BE) ' READ SCRATCHPAD command [BEh]
j1 = OW_Read(OWP,PIN) ' Read LSB
j2 = OW_Read(OWP,PIN) ' Read MSB
result = (j2 << 8) + j1 ' result in 2's complement form
'
end sub
sub procedure StartConvert
'
Ow_Reset(OWP, PIN)
Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd , send cmd to all devices
Delay_us(120)
Ow_Write(OWP, PIN, $44) ' CONVERT-TEMP cmd
'Delay_ms(1000) ' conversion delay ...
'
end sub
sub procedure Init(dim byref xID as byte[8])
'
ow_reset(OWP,PIN) ' onewire reset signal
ow_write(OWP,PIN,$55) ' MATCH-ROM command
Ser_Out(xID) ' ROM-ID-CODE
delay_us(120)
ow_reset(OWP,PIN) ' onewire reset signal
'ow_write(OWP,PIN,$CC) '
ow_write(OWP,PIN,$4E) '
ow_write(OWP,PIN,$FF) '
ow_write(OWP,PIN,$FF) '
ow_write(OWP,PIN,$7F) ' Set for 12 bit output
'
end sub
sub procedure Out_LCD
'
minus = j2
minus = minus << 3
if minus = $1F then ' Checking temp.(+ or -)
'
j2 = not(j2)
j1 = not(j1)
j1 = j1+1
end if
Raw_temp = (j2 << 8) or j1 ' Getting RAW data
if minus = $1F then
Lcd_Chr(2,1,"-") ' Write temp. sign (+ or -) on LCD
else
Lcd_Chr(2,1,"+")
end if
'
TempC = (Raw_temp and $0FF0) >> 4 ' WHOLE NUMBER
decimal = (j1 and $0F) * 625 ' DECIMAL
word2str(TempC) ' Write temp. whole number on LCD
Lcd_Chr(2, 2, M2)
Lcd_Chr(2, 3, M3)
Lcd_Chr(2, 4, 46) ''.'
word2str(decimal) ' Write temp. decimal number on LCD
Lcd_Chr(2, 5, M0)
Lcd_Chr(2, 6, M1)
Lcd_Chr(2, 7, M2)
Lcd_Chr(2, 8, M3)
lcd_chr(2, 9, 223) ' 'degree' character
lcd_chr(2, 10,"C")
'
end sub
main:
'
adcon1 = 255 ' configure RE2 pin as digital I/O
PORTE = 0 '255 ' initialize PORTE
PORTB = 0 ' initialize PORTB
TRISE = %00000101 ' designate PORTE 0,2 as input
TRISB = 0 ' designate PORTB as output
Lcd_Init(PORTB)
lcd_cmd( LCD_CURSOR_OFF)
lcd_out( 1, 1, "2 x DS1820 temp")
delay_ms(1000)
lcd_cmd(lcd_clear)
'
T1[0] = 16
T1[1] = 87
T1[2] = 37
T1[3] = 189
T1[4] = 0
T1[5] = 8
T1[6] = 0
T1[7] = 0
'
T2[0] = 40 '$28
T2[1] = 190 '$BE
T2[2] = 148 '$94
T2[3] = 153 '$99
T2[4] = 0 '$00
T2[5] = 0 '$00
T2[6] = 0 '$00
T2[7] = 208 '$D0
'
'Init(T1)
Init(T2)
'
lcd_out( 1, 1, "Temp: ")
'
while true
StartConvert
Delay_ms(1000)
Temp = GetTemp(T2)
Out_LCD
wend ' endless loop
end.
//Sonar
-
- Posts: 361
- Joined: 14 Dec 2005 20:56
- Location: Slovenia
Hi!
No it won't work directly, you have to substitute the ROM code (T1, T2, and so on) of mine DS18B20 to yours, and if you got a DS1820 (9-bit resolution) then you just skip the "Init" routine.
My code sends the "Convert" command to ALL units and then does an addressing of an individual DS18x20 and ONLY reads the result from that particular unit, so the ROM code MUST match or else there would be no result.
If you don't know the ROM-ID of your devices you could use this program
on your EasyPIC3 board or others boards after necessery mods to read the ROM-ID and display it on the LCD
//Sonar
No it won't work directly, you have to substitute the ROM code (T1, T2, and so on) of mine DS18B20 to yours, and if you got a DS1820 (9-bit resolution) then you just skip the "Init" routine.
My code sends the "Convert" command to ALL units and then does an addressing of an individual DS18x20 and ONLY reads the result from that particular unit, so the ROM code MUST match or else there would be no result.
If you don't know the ROM-ID of your devices you could use this program
on your EasyPIC3 board or others boards after necessery mods to read the ROM-ID and display it on the LCD
Code: Select all
'
program Read_ID
'
symbol OWP = PORTE
'
dim text1 as char[17] ' message1 on LCD
dim text2 as char[17] ' message2 on LCD
dim Js as byte[8] ' accepts code from iButton
dim presence_check as byte
'
' -------------------------------------------------------------
' Procedure for converting byte variable to HEX and displaying
' it on LCD display.
'
' procedure int2hex(row, start_x : byte number : byte)
' row - LCD line,
' start_x - position of first hex digit (left to right)
' -------------------------------------------------------------
sub procedure int2hex(dim row as byte, dim start_x as byte, dim number as byte)
dim high as byte
dim low as byte
' high nibble
high = ((number and $F0) >> 4)+ 48 ' + "0"
if (high > 57) then high = high + 7 ' > "9"
end if
' low nibble
low = (number and $0F) + 48 ' + "0" low nibble
if (low > 57) then low = low + 7 ' > "9"
end if
Lcd_Chr(row, start_x, high)
Lcd_Chr(row, start_x + 1, low)
end sub
'Ow_Read_Serial reads 8 bytes via 1-wire protocol and
'places them into the array "out". The destination array
'needs to be at least 8 bytes in size
sub procedure Ow_Read_Serial(dim byref PORT as byte, dim pin as byte, dim byref out as byte[8])
dim i as byte
dim tmpRead as byte
i = 0
while i <= 7 ' we will move 8 bytes
tmpRead = ow_read(PORT,PIN) ' get one byte from Dallas iButton
out[i] = tmpRead
inc(i) ' next i
wend
end sub
main:
adcon1 = 255 ' pin Rd2 is digital I/O
TRISD = 255
PORTB = 0 ' initialize portb on 0
trisb = 0 ' portb is output
text1 = "mikro iButton:"
text2 = "not present "
Lcd_Init(PORTB)
Lcd_Cmd(LCD_CURSOR_OFF)
LCD_Out(1, 1, text1) ' print initial message
_loop:
' first, we read iButton if present on pin RD2
' if not present, print appropriate message on LCD
ow_reset(OWP,2) ' onewire reset signal
ow_write(OWP,2,$33) ' read iButton
delay_us(120) ' pause
Ow_Read_Serial(OWP, 2, Js) ' read 8 bytes of Dallas iButton
' if iButton is not present, j1 ~ j8 will be at 255, so we can easily
' test them:
presence_check = js[0] and js[1] and js[2] and js[3] and js[4] and js[5] and js[6] and js[7]
if presence_check = $FF then ' iButton is not present
LCD_Out(2, 1, text2) ' print message
else ' iButton is present, convert codes to hex and print them on LCD
int2hex(2, 1, js[7])
int2hex(2, 3, js[6])
int2hex(2, 5, js[5])
int2hex(2, 7, js[4])
int2hex(2, 9, js[3])
int2hex(2, 11, js[2])
int2hex(2, 13, js[1])
int2hex(2, 15, js[0])
end if
Delay_ms(500)
goto _loop
end.
//Sonar
-
- Posts: 361
- Joined: 14 Dec 2005 20:56
- Location: Slovenia
First of all, thanks for helping me!
I got ID from my Ds18S20's, and I replaced your numbers and it works, but?
1.In second row appeared +02,6250°C (should be ~22°C)
2.When I touch DS18S20 with hand, number increased on +04,0625°C (should be 30-32°C)
I made few experiments with code but nothing changed. here's the last version.
program Temp_Read
symbol OWP = PORTE
symbol PIN = 2
'
dim T1 as byte[8]
dim T2 as byte[8]
'
dim b,iCnt,j1,j2,xCnt, minus as byte
dim M0, M1, M2, M3 as byte
dim ID as byte[8]
dim Temp as integer
dim TempF as float
dim slask as string[20]
dim text as char[14]
dim st as char[3]
'
dim Raw_temp,TempC, decimal as word
'
'
sub Procedure SetID(dim xID as byte[8])
'
for xCnt = 0 to 7
b = xID[xCnt]
ID[xCnt] = b
next xCnt
'
end sub
sub procedure Ser_Out(dim byref xID as byte[8])
'
for iCnt = 0 to 7
b = xID[iCnt]
Ow_Write(OWP, PIN, b) ' ... should work?
delay_ms(10)
next iCnt
'
end sub
sub procedure Word2Str(dim count as word)
dim rest as byte
'
rest = count mod 10
M3 = rest + 48
count = count div 10
rest = count mod 10
M2 = rest + 48
count = count div 10
rest = count mod 10
M1 = rest + 48
count = count div 10
rest = count mod 10
M0 = rest + 48
count = count div 10
end sub
sub function GetTemp(dim byref xID as byte[8]) as integer
'
Ow_Reset(OWP, PIN)
' Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd
Ow_Write(OWP, PIN, $55) ' MATCH-ROM cmd
'Delay_us(120)
Ser_Out(xID) ' Send serialnumber
delay_us(120)
Ow_Write(OWP,PIN,$BE) ' READ SCRATCHPAD command [BEh]
j1 = OW_Read(OWP,PIN) ' Read LSB
j2 = OW_Read(OWP,PIN) ' Read MSB
result = (j2 << + j1 ' result in 2's complement form
'
end sub
sub procedure StartConvert
'
Ow_Reset(OWP, PIN)
Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd , send cmd to all devices
Delay_us(120)
Ow_Write(OWP, PIN, $44) ' CONVERT-TEMP cmd
'Delay_ms(1000) ' conversion delay ...
'
end sub
sub procedure Init(dim byref xID as byte[8])
'
ow_reset(OWP,PIN) ' onewire reset signal
ow_write(OWP,PIN,$55) ' MATCH-ROM command
Ser_Out(xID) ' ROM-ID-CODE
delay_us(120)
ow_reset(OWP,PIN) ' onewire reset signal
'ow_write(OWP,PIN,$CC) '
ow_write(OWP,PIN,$4E) '
ow_write(OWP,PIN,$FF) '
ow_write(OWP,PIN,$FF) '
ow_write(OWP,PIN,$7F) ' Set for 12 bit output
'
end sub
sub procedure Out_LCD
'
minus = j2
minus = minus << 3
if minus = $1F then ' Checking temp.(+ or -)
'
j2 = not(j2)
j1 = not(j1)
j1 = j1+1
end if
Raw_temp = (j2 << or j1 ' Getting RAW data
if minus = $1F then
Lcd_Chr(2,1,"-") ' Write temp. sign (+ or -) on LCD
else
Lcd_Chr(2,1,"+")
end if
'
TempC = (Raw_temp and $0FF0) >> 4 ' WHOLE NUMBER
decimal = (j1 and $0F) * 625 ' DECIMAL
word2str(TempC) ' Write temp. whole number on LCD
Lcd_Chr(2, 2, M2)
Lcd_Chr(2, 3, M3)
Lcd_Chr(2, 4, 46) ''.'
word2str(decimal) ' Write temp. decimal number on LCD
Lcd_Chr(2, 5, M0)
Lcd_Chr(2, 6, M1)
Lcd_Chr(2, 7, M2)
Lcd_Chr(2, 8, M3)
lcd_chr(2, 9, 223) ' 'degree' character
lcd_chr(2, 10,"C")
'
end sub
main:
'
adcon1 = 255 ' configure RE2 pin as digital I/O
PORTE = 0 '255 ' initialize PORTE
PORTB = 0 ' initialize PORTB
TRISE = %00000101 ' designate PORTE 0,2 as input
TRISB = 0 ' designate PORTB as output
Lcd_Init(PORTB)
lcd_cmd( LCD_CURSOR_OFF)
lcd_out( 1, 1, "2 x DS1820 temp")
delay_ms(1000)
lcd_cmd(lcd_clear)
'
T1[0] = 16 '$10
T1[1] = 221 '$DD
T1[2] = 65 '$41
T1[3] = 128 '$80
T1[4] = 0 '$00
T1[5] = 8 '$08
T1[6] = 0 '$00
T1[7] = 254 '$FE
'
T2[0] = 16 '$10
T2[1] = 213 '$D5
T2[2] = 133 '$85
T2[3] = 128 '$80
T2[4] = 0 '$00
T2[5] = 8 '$08
T2[6] = 0 '$00
T2[7] = 98 '$62
'
'Init(T1)
'Init(T2)
'
lcd_out( 1, 1, "Temp: ")
'
while true
StartConvert
Delay_ms(1000)
Temp = GetTemp(T2)
Out_LCD
wend ' endless loop
end.
I got ID from my Ds18S20's, and I replaced your numbers and it works, but?
1.In second row appeared +02,6250°C (should be ~22°C)
2.When I touch DS18S20 with hand, number increased on +04,0625°C (should be 30-32°C)
I made few experiments with code but nothing changed. here's the last version.
program Temp_Read
symbol OWP = PORTE
symbol PIN = 2
'
dim T1 as byte[8]
dim T2 as byte[8]
'
dim b,iCnt,j1,j2,xCnt, minus as byte
dim M0, M1, M2, M3 as byte
dim ID as byte[8]
dim Temp as integer
dim TempF as float
dim slask as string[20]
dim text as char[14]
dim st as char[3]
'
dim Raw_temp,TempC, decimal as word
'
'
sub Procedure SetID(dim xID as byte[8])
'
for xCnt = 0 to 7
b = xID[xCnt]
ID[xCnt] = b
next xCnt
'
end sub
sub procedure Ser_Out(dim byref xID as byte[8])
'
for iCnt = 0 to 7
b = xID[iCnt]
Ow_Write(OWP, PIN, b) ' ... should work?
delay_ms(10)
next iCnt
'
end sub
sub procedure Word2Str(dim count as word)
dim rest as byte
'
rest = count mod 10
M3 = rest + 48
count = count div 10
rest = count mod 10
M2 = rest + 48
count = count div 10
rest = count mod 10
M1 = rest + 48
count = count div 10
rest = count mod 10
M0 = rest + 48
count = count div 10
end sub
sub function GetTemp(dim byref xID as byte[8]) as integer
'
Ow_Reset(OWP, PIN)
' Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd
Ow_Write(OWP, PIN, $55) ' MATCH-ROM cmd
'Delay_us(120)
Ser_Out(xID) ' Send serialnumber
delay_us(120)
Ow_Write(OWP,PIN,$BE) ' READ SCRATCHPAD command [BEh]
j1 = OW_Read(OWP,PIN) ' Read LSB
j2 = OW_Read(OWP,PIN) ' Read MSB
result = (j2 << + j1 ' result in 2's complement form
'
end sub
sub procedure StartConvert
'
Ow_Reset(OWP, PIN)
Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd , send cmd to all devices
Delay_us(120)
Ow_Write(OWP, PIN, $44) ' CONVERT-TEMP cmd
'Delay_ms(1000) ' conversion delay ...
'
end sub
sub procedure Init(dim byref xID as byte[8])
'
ow_reset(OWP,PIN) ' onewire reset signal
ow_write(OWP,PIN,$55) ' MATCH-ROM command
Ser_Out(xID) ' ROM-ID-CODE
delay_us(120)
ow_reset(OWP,PIN) ' onewire reset signal
'ow_write(OWP,PIN,$CC) '
ow_write(OWP,PIN,$4E) '
ow_write(OWP,PIN,$FF) '
ow_write(OWP,PIN,$FF) '
ow_write(OWP,PIN,$7F) ' Set for 12 bit output
'
end sub
sub procedure Out_LCD
'
minus = j2
minus = minus << 3
if minus = $1F then ' Checking temp.(+ or -)
'
j2 = not(j2)
j1 = not(j1)
j1 = j1+1
end if
Raw_temp = (j2 << or j1 ' Getting RAW data
if minus = $1F then
Lcd_Chr(2,1,"-") ' Write temp. sign (+ or -) on LCD
else
Lcd_Chr(2,1,"+")
end if
'
TempC = (Raw_temp and $0FF0) >> 4 ' WHOLE NUMBER
decimal = (j1 and $0F) * 625 ' DECIMAL
word2str(TempC) ' Write temp. whole number on LCD
Lcd_Chr(2, 2, M2)
Lcd_Chr(2, 3, M3)
Lcd_Chr(2, 4, 46) ''.'
word2str(decimal) ' Write temp. decimal number on LCD
Lcd_Chr(2, 5, M0)
Lcd_Chr(2, 6, M1)
Lcd_Chr(2, 7, M2)
Lcd_Chr(2, 8, M3)
lcd_chr(2, 9, 223) ' 'degree' character
lcd_chr(2, 10,"C")
'
end sub
main:
'
adcon1 = 255 ' configure RE2 pin as digital I/O
PORTE = 0 '255 ' initialize PORTE
PORTB = 0 ' initialize PORTB
TRISE = %00000101 ' designate PORTE 0,2 as input
TRISB = 0 ' designate PORTB as output
Lcd_Init(PORTB)
lcd_cmd( LCD_CURSOR_OFF)
lcd_out( 1, 1, "2 x DS1820 temp")
delay_ms(1000)
lcd_cmd(lcd_clear)
'
T1[0] = 16 '$10
T1[1] = 221 '$DD
T1[2] = 65 '$41
T1[3] = 128 '$80
T1[4] = 0 '$00
T1[5] = 8 '$08
T1[6] = 0 '$00
T1[7] = 254 '$FE
'
T2[0] = 16 '$10
T2[1] = 213 '$D5
T2[2] = 133 '$85
T2[3] = 128 '$80
T2[4] = 0 '$00
T2[5] = 8 '$08
T2[6] = 0 '$00
T2[7] = 98 '$62
'
'Init(T1)
'Init(T2)
'
lcd_out( 1, 1, "Temp: ")
'
while true
StartConvert
Delay_ms(1000)
Temp = GetTemp(T2)
Out_LCD
wend ' endless loop
end.
Hi!
Yes that is right, because the "step" of the B-unit is 0.0625 deg. cels. if remember correcly, and the S-unit has a 0.5 step.
Use this routine to swap the "Out_LCD" routine, and it SHOULD work /
For the moment I can't test the routine because my DS18x20's are lost ...
//Sonar
Yes that is right, because the "step" of the B-unit is 0.0625 deg. cels. if remember correcly, and the S-unit has a 0.5 step.
Use this routine to swap the "Out_LCD" routine, and it SHOULD work /
Code: Select all
sub procedure Out_LCD
intToStr((Temp / 2),text)
lcd_out(2,1,text)
lcd_chr(2,7,",")
if t.0 = %1 then lcd_chr(2,8,"5") else lcd_chr(2,8,"0") end if
lcd_chr( 2, 9, 223)
lcd_chr( 2, 10,"C")
end sub
For the moment I can't test the routine because my DS18x20's are lost ...
//Sonar
Damnit....typo...
Corrected code:
I will find those DS18x20's of mine so I can test the code....I WILL
//Sonar
Corrected code:
Code: Select all
sub procedure Out_LCD
intToStr((Temp / 2),text)
lcd_out(2,1,text)
lcd_chr(2,7,",")
if Temp.0 = %1 then lcd_chr(2,8,"5") else lcd_chr(2,8,"0") end if
lcd_chr( 2, 9, 223)
lcd_chr( 2, 10,"C")
end sub
I will find those DS18x20's of mine so I can test the code....I WILL
//Sonar
-
- Posts: 361
- Joined: 14 Dec 2005 20:56
- Location: Slovenia
I found those darn DS18x20's
So now I have completed the code /
//Sonar
So now I have completed the code /
Code: Select all
program Temp_Read
symbol OWP = PORTE
symbol PIN = 2
'
dim T1 as byte[8]
dim T2 as byte[8]
dim T3 as byte[8]
'
dim b,iCnt,j1,j2,xCnt, minus as byte
dim M0, M1, M2, M3 as byte
dim Temp as integer
dim RStat as boolean
dim text as char[14]
'
dim Raw_temp,TempC, decimal as word
'
'
sub procedure Ser_Out(dim byref xID as byte[8])
'
for iCnt = 0 to 7
b = xID[iCnt]
Ow_Write(OWP, PIN, b) ' ... works !
delay_ms(10)
next iCnt
'
end sub
sub procedure Word2Str(dim count as word)
dim rest as byte
'
rest = count mod 10
M3 = rest + 48
count = count div 10
rest = count mod 10
M2 = rest + 48
count = count div 10
rest = count mod 10
M1 = rest + 48
count = count div 10
rest = count mod 10
M0 = rest + 48
count = count div 10
end sub
sub procedure GetTemp(dim byref xID as byte[8])
'
Ow_reset(OWP,PIN) ' onewire reset signal
' Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd
Ow_Write(OWP, PIN, $55) ' MATCH-ROM cmd
'Delay_us(120)
Ser_Out(xID) ' Send serialnumber
delay_us(120)
Ow_Write(OWP,PIN,$BE) ' READ SCRATCHPAD command [BEh]
j1 = OW_Read(OWP,PIN) ' Read LSB
j2 = OW_Read(OWP,PIN) ' Read MSB
end sub
sub procedure StartConvert
'
Ow_Reset(OWP, PIN)
Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd , send cmd to all devices
Delay_us(120)
Ow_Write(OWP, PIN, $44) ' CONVERT-TEMP cmd
'
end sub
sub procedure InitB(dim byref xID as byte[8])
'
ow_reset(OWP,PIN) ' onewire reset signal
ow_write(OWP,PIN,$55) ' MATCH-ROM command
Ser_Out(xID) ' ROM-ID-CODE
delay_us(120)
ow_reset(OWP,PIN) ' onewire reset signal
'ow_write(OWP,PIN,$CC) '
ow_write(OWP,PIN,$4E) '
ow_write(OWP,PIN,$FF) '
ow_write(OWP,PIN,$FF) '
ow_write(OWP,PIN,$7F) ' Set for 12 bit output
'
end sub
sub procedure OutS_LCD
Temp = (j2 << 8) + j1 ' Take first byte (hi) and shift it 8 steps left
' then add second byte (lo)
intToStr((Temp / 2),text)
text[1] = text[3]
text[2] = text[4]
text[3] = text[5]
text[4] = text[6]
text[5] = text[7]
text[6] = text[8]
lcd_out_cp(text)
lcd_chr_cp(",")
if Temp.0 = %1 then lcd_chr_cp("5") else lcd_chr_cp("0") end if
lcd_chr_cp(223)
lcd_chr_cp("C")
end sub
sub procedure OutB_LCD
'
minus = j2
minus = minus << 3 'Another way to do it :)
if minus = $1F then ' Checking temp.(+ or -)
'
j2 = not(j2)
j1 = not(j1)
j1 = j1+1
end if
Temp = (j2 << 8) or j1 ' Getting RAW data
'
if minus = $1F then
Lcd_Chr_cp("-") ' Write temp. sign (+ or -) on LCD
else
Lcd_Chr_cp("+")
end if
'
TempC = (Temp and $0FF0) >> 4 ' WHOLE NUMBER
decimal = (j1 and $0F) * 625 ' DECIMAL
word2str(TempC) ' Write temp. whole number on LCD
Lcd_Chr_cp(M2)
Lcd_Chr_cp(M3)
Lcd_Chr_cp(46) ''.'
word2str(decimal) ' Write temp. decimal number on LCD
Lcd_Chr_cp(M0)
Lcd_Chr_cp(M1)
Lcd_Chr_cp(M2)
Lcd_Chr_cp(M3)
lcd_chr_cp(223) ' 'degree' character
lcd_chr_cp("C")
'
end sub
main:
'
adcon1 = 255 ' configure RE2 pin as digital I/O
PORTE = 0 '255 ' initialize PORTE
PORTB = 0 ' initialize PORTB
'PORTC = 0
'PORTD = 0
TRISE = %00000101 ' designate PORTE 0,2 as input
TRISB = 0 ' designate PORTB as output
'TRISC = 0
'TRISD = 0
Lcd_Init(PORTB)
lcd_cmd(LCD_CURSOR_OFF)
lcd_out( 1, 1, "2 x DS1820 temp")
delay_ms(2000)
lcd_cmd(lcd_clear)
'
T1[0] = 16
T1[1] = 87
T1[2] = 37
T1[3] = 189
T1[4] = 0
T1[5] = 8
T1[6] = 0
T1[7] = 0
'
T2[0] = 40 '$28
T2[1] = 190 '$BE
T2[2] = 148 '$94
T2[3] = 153 '$99
T2[4] = 0 '$00
T2[5] = 0 '$00
T2[6] = 0 '$00
T2[7] = 208 '$D0
'
T3[0] = $10
T3[1] = $7d
T3[2] = $66
T3[3] = $b6
T3[4] = $0
T3[5] = $8
T3[6] = $0
T3[7] = $4a
'
'Init(T1)
'Init(T3)
'
lcd_out( 1, 1, "Temp:A Temp:B")
'
while true
StartConvert
Delay_ms(1000)
Lcd_Cmd(LCD_RETURN_HOME)
Lcd_Cmd(LCD_SECOND_ROW)
GetTemp(T1)
OutS_LCD ' In case of a "B" device use OutB_LCD
'lcd_chr_cp(" ")
GetTemp(T3)
OutS_LCD
wend ' endless loop
end.
//Sonar
-
- Posts: 361
- Joined: 14 Dec 2005 20:56
- Location: Slovenia
It works perfect. Now I have to understand this code, how it works. You know, I made few years ago control sistem for some kind of smart house with LabView on PC and it works very good. Now I want to produce smaller version of this project with PIC microcontroller (just for hobby).
Ok, thanks for helping me and have a lot of lucky and fun in new year. I wish the same all of the PIC-fans all over the world.
Ok, thanks for helping me and have a lot of lucky and fun in new year. I wish the same all of the PIC-fans all over the world.
v2.2 and boolean works fine. To avoid confusion about True/False values, True is not 1, True = $FF. False is always 0. Another tidbit, boolean True tests make for great compiled code optimization besides less typing in mB.alsopb wrote:Sonar,
What BASIC compiler are you using. Mine (MB V2.2) doesn't accept the datatype Boolean.
Brian
Code: Select all
dim mybool as boolean
If mybool then
nop
End If
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]
[url=http://circuit-ed.com]CircuitED -[/url]
Sonar wrote:I found those darn DS18x20's
So now I have completed the code /
..snipCode: Select all
..snip sub procedure GetTemp(dim byref xID as byte[8]) ' Ow_reset(OWP,PIN) ' onewire reset signal ' Ow_Write(OWP, PIN, $CC) ' SKIP-ROM cmd Ow_Write(OWP, PIN, $55) ' MATCH-ROM cmd 'Delay_us(120) Ser_Out(xID) ' Send serialnumber delay_us(120) Ow_Write(OWP,PIN,$BE) ' READ SCRATCHPAD command [BEh] j1 = OW_Read(OWP,PIN) ' Read LSB j2 = OW_Read(OWP,PIN) ' Read MSB end sub
I don't want to nitpick, but why you send a skip rom ($CC) and a match rom ($55) in sequence? Wouldn't a match rom be enough in this case?
I've been lurking this discussion these past days because I had to implement 2 DS18B20 on the same 1-wire bus, and I got it done yesterday. Reading the datasheet and some hints on this thread made it really easy.
Another question more or less off topic: my ds18B20 has a alarm feature. Why would someone use that feature instead of implementing that feature in the microcontroller?
Cheers
Padu
(BTW: if someone wants my source code in mP, I have both the temp reading program and the program to read the ROM ID string.)