View previous topic :: View next topic |
Author |
Message |
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Mon Dec 07, 2015 10:06 am Post subject: 1-Wire search & save + DS1820 |
|
|
Here is some working code for finding 1-wire devices and storing the IDs in EEPROM
Also code for reading DS1820 temperature sensors'
Regards Paul
Code: |
'--------------------------------------------------------------------------------
'name : 1wireSearch.bas
'micro : Mega168p
'suited for demo : No Only due to code size which could be
'reduced by removing print commands!!!!!!!!
'commercial addon needed : no
'--------------------------------------------------------------------------------
$regfile = "m168pdef.dat"
$crystal = 8000000
$baud = 9600
$hwstack = 100 ' default use 32 for the hardware stack
$swstack = 100 'default use 10 for the SW stack
$framesize = 100 'default use 40 for the frame space
'Config 1wire = Portc.4 'use this pin
Io_1wire_port Alias Pinc
Declare Sub Read_ds1820(byval Piin As Byte )
Declare Sub Send1wire_cmd(byval Cmd As Byte , Byval Piin As Byte )
Declare Sub Look_for_devices
Declare Sub Save_eeprom
Declare Sub Check_stord
Declare Function Compare(val1 As Byte , Val2 As Byte , Byval Btcomp As Word) As Word
'we need some space from at least 8 bytes to store the ID
Dim Sc(9) As Byte ' result when reading DS chip
Dim Scd As Double At Sc(1) Overlay '1st 8 bytes ofSc(9)
Dim Dev_sc As Double
Dim Dev_scb(8) As Byte At Dev_sc Overlay '8 bytes of Dev_sc
Dim Work As Double
Dim Workw(2) As Dword At Work Overlay
Dim Devs(20 ) As Eram Double '8 bytes per device
Const Devices = 20 'max number of devices
Dim Cntr As Byte
Dim J As Byte
Dim K As Byte
Dim L As Byte
Dim I As Byte , W As Word
Dim Z As Single
Dim Zs As String * 5 'for print to LCD
Poort Alias Pinc 'pin for 1-wire
' 1WIRE COMMANDS
Const C1w_read_rom = &H33
Const C1w_match_rom = &H55
'===============================
'tell all devices to do a temperature read
'+++++++++++++++++++++++++++++
'send this command to address all devices on the bus
Const C1w_skip_rom = &HCC
'then send this command the instruction to tell all do temperature conversion
Const C1w_convert_t = &H44
'==============================
Const C1w_search_rom = &HF0
Const C1w_alarm_search = &HEC
Const C1w_wr_scratchpad = &H4E
Const C1w_rd_scratchpad = &HBE
Const C1w_cpy_scratchpad = &H48
Const C1w_recall_memory = &HB8
Const C1w_convert_v = &HB4
Config Pinb.2 = Output 'LCD back light on my board
' Config 1wire = Portc.4 'use this pin
Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.4 , Db6 = Portd.3 , Db7 = Portd.2 , E = Portb.0 , Rs = Portb.1
I = 1
Set Portb.2 'turn back light on
1wwrite C1w_skip_rom , 1 , Poort , 4 'address all devices
1wwrite C1w_convert_t , 1 , Poort , 4 'tell all to convert
'Now search for devices on the bus
Call Look_for_devices
Cls
Locate 1 , 1
Lcd "family code";
Locate 2 , 1
Lcd Hex(sc(1));
Wait 5
Cls
Call Read_ds1820(4)
Cls
Locate 1 , 1
Lcd "Deg C " ;
Zs = Fusing(z , "##.##")
Lcd Zs
End
'-------------------------------------------------------------------------------
' Name: Read_DS1820()
' Function: read the temperature from sensor (separated temp sensor)
' Input : 1Wire Hardware
'-------------------------------------------------------------------------------
Sub Read_ds1820(byval Piin As Byte )
Local T As Integer
Local Tt As Single
Local Tl As Single
'clear variables
Z = 0
T = 0
Call Send1wire_cmd(c1w_rd_scratchpad , 4 ) ' read scratchpad
Sc(1) = 1wread(9 , Poort , Piin ) ' read bytes in array
If Sc(9) = Crc8(sc(1) , 8) Then ' check CRC
'find the resolution of temp bits
Select Case Sc(5)
Case 127 ' 127 = 12 bits
Tl = 0.0625
Case 95 ' 95 = 11 bit
Tl = 0.125
Case 63 ' 63 = 10 bits
Tl = 0.25
Case 31 ' 31 = 9 bits
Tl = 0.5
End Select
T = Makeint(sc(1) , Sc(2))
Tt = T
Tt = Tt * Tl
Z = Tt
End If
Call Send1wire_cmd(c1w_convert_t , 4) ' start conversion for next read
End Sub Read_ds1820()
'-------------------------------------------------------------------------------
' Name: Send1wire_cmd(cmd)
' Function: Send a command to a predefined 1W device dsid()
' Input : 1WIRE Command (see command list)
' Output: 1Wire Hardware
'-------------------------------------------------------------------------------
Sub Send1wire_cmd(byval Cmd As Byte , Byval Piin As Byte )
1wverify Sc(1) , Poort , Piin ' Send chip unique ID
If Err = 0 Then
1wwrite Cmd , 1 , Poort , Piin ' send command
End If
End Sub
'------------------------------------------------------------
'==Search for devices on the buss
'==Put the IDs new into EEPROM
'------------------------------------------------------------
Sub Look_for_devices
Local Xv As Byte
Xv = 0
'Now search for the first device on the bus
Sc(1) = 1wsearchfirst(poort , 4)
Cls
Locate 1 , 1
Cntr = 1
If Err = 0 Then 'found device
Print "found one"
Incr Xv 'add one for every device found
Call Check_stord
End If
Lcd Hex(sc(i)); 'print the number to LCD
Print Hex(sc(i)); 'print the number
'Wait 2
Print
Print
Wait 1
Do
' Now Search For Other Devices
Sc(1) = 1wsearchnext(poort , 4)
If Err = 0 Then 'found device
Print "found another"
Incr Xv
Call Check_stord
End If
'Print
Loop Until Err = 1
Locate 2 , 1
Cntr = 1
Print Xv ; " devices found"
End Sub
'==save device IDs to eeprom
Sub Save_eeprom
Local Xl As Byte
Local Wd As Double
Print "save eeprom"
'blank eeprom is all FFFF
Workw(1) = &HFFFFFFFF
Workw(2) = &HFFFFFFFF
For Xl = 1 To Devices
Wd = Devs(xl)
If Wd = Work Then 'blank eeprom bytes are FF
Print "WD is it"
Devs(xl) = Scd 'save to eeprom
Exit For
Elseif Wd = 0 Then
Print "WD is it"
Devs(xl) = Scd 'save to eeprom
Exit For
End If
Next
If Xl = Devices Then
Print "Not saved out of space"
End If
End Sub
Sub Check_stord
Local Devpoint As Byte
Local Res As Byte
Print "Checking!"
For Devpoint = 1 To Devices
Dev_sc = Devs(devpoint)
Print "If Scd = Dev_sc Then "
Print "Sc() " ;
For I = 1 To 8
Print Hex(sc(i));
Next
Print
Print "Dev_scb " ;
For I = 1 To 8
Print Hex(dev_scb(i));
Next
Print
'Now we use the MWS Compare!
Res = Compare(dev_scb , Scd , 8)
If Res = 0 Then 'stored
Exit For 'its stored so lets not waste time
End If
Next
If Res > 0 Then
Print "not stored"
Call Save_eeprom
Else
Print "device stored"
End If
End Sub
'===============
' The MWS Compare
' "==============="
Function Compare(val1 As Byte , Val2 As Byte , Byval Btcomp As Word) As Word
!LD XL, Y+0 ' get pointer to BtComp
!LD XH, Y+1
!LD R24, X+ ' R24/25 as counter
!LD R25, X
!MOVW R16, R24 ' save BtComp for later calculation of mismatch position
!LD XL, Y+4 ' get pointer to Val1 into X
!LD XH, Y+5
!LD ZL, Y+2 ' get pointer to Val2 into Z
!LD ZH, Y+3
!cmp_start:
!LD R20, X+ ' X points to Val1
!LD R21, Z+ ' Z points to Val2
!CP R20, R21 ' compare!
!BRNE cmp_nomatch ' if equal: ok, next one
!SBIW R24, 1 ' decrease loop counter
!BRNE cmp_start ' if not zero do another turn
!RJMP cmp_end
!cmp_nomatch:
!SBIW R24, 1 ' else: calculate the position of compare mismatch
!SUB R16, R24
!SBC R17, R25
!MOVW R24, R16
!cmp_end:
!LD XL, Y+6
!LD XH, Y+7
!ST X+, R24 ' store success or position of mismatch
!ST X, R25
End Function
|
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Tue Dec 08, 2015 10:13 pm Post subject: |
|
|
Thanks for sharing Paul !
The compare function from MWS is added to 2080 so take care that in an update it will give a conflict. _________________ Mark |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Wed Dec 09, 2015 12:17 am Post subject: |
|
|
Hello Mark
Yes I will have to update the post with another version when it comes out.
I am also not using some of the variables exactly as intended but there is no 8 byte variable in bascom
It would be nice to have a 8 and 16 byte pure binary variables to work with hardware connected to the AVR
Maybe a quad word Qword and octo word Oword
Regards Paul |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Sun Dec 20, 2015 11:31 am Post subject: |
|
|
Now so the free version of Bascom can be used I have set up conditional compilation
By setting one of the constants Test or Uselcd to 0 less than 4k of code is produced
Regards Paul
Code: |
'--------------------------------------------------------------------------------
'name : 1wireSearch.bas
'micro : Mega168p
'suited for demo : yes by setting constants Test or Uselcd to 0
'commercial addon needed : no
'--------------------------------------------------------------------------------
$regfile = "m168pdef.dat"
$crystal = 8000000
$baud = 9600
$hwstack = 100 ' default use 32 for the hardware stack
$swstack = 100 'default use 10 for the SW stack
$framesize = 100 'default use 40 for the frame space
'Config 1wire = Portc.4 'use this pin
Io_1wire_port Alias Pinc
Declare Sub Read_ds1820(byval Piin As Byte )
Declare Sub Send1wire_cmd(byval Cmd As Byte , Byval Piin As Byte )
Declare Sub Look_for_devices
Declare Sub Save_eeprom
Declare Sub Check_stord
Declare Function Compare(val1 As Byte , Val2 As Byte , Byval Btcomp As Word) As Word
'we need some space from at least 8 bytes to store the ID
Dim Sc(9) As Byte ' result when reading DS chip
Dim Scd As Double At Sc(1) Overlay '1st 8 bytes ofSc(9)
Dim Dev_sc As Double
Dim Dev_scb(8) As Byte At Dev_sc Overlay '8 bytes of Dev_sc
Dim Work As Double
Dim Workw(2) As Dword At Work Overlay
Dim Devs(20 ) As Eram Double '8 bytes per device
Const Devices = 20 'max number of devices
Dim Cntr As Byte
Dim J As Byte
Dim K As Byte
Dim L As Byte
Dim I As Byte , W As Word
Dim Z As Single
Dim Zs As String * 5 'for print to LCD
Poort Alias Pinc 'pin for 1-wire
' 1WIRE COMMANDS
Const C1w_read_rom = &H33
Const C1w_match_rom = &H55
'===============================
'tell all devices to do a temperature read
'+++++++++++++++++++++++++++++
'send this command to address all devices on the bus
Const C1w_skip_rom = &HCC
'then send this command the instruction to tell all do temperature conversion
Const C1w_convert_t = &H44
'==============================
Const C1w_search_rom = &HF0
Const C1w_alarm_search = &HEC
Const C1w_wr_scratchpad = &H4E
Const C1w_rd_scratchpad = &HBE
Const C1w_cpy_scratchpad = &H48
Const C1w_recall_memory = &HB8
Const C1w_convert_v = &HB4
'======================================
' by setting one or both of these to 0 the free version can be used
Const Test = 1 '1 will enable print commands
Const Uselcd = 0 '1 will enable LCD
'=====================================
Config Pinb.2 = Output 'LCD back light on my board
' Config 1wire = Portc.4 'use this pin
Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.4 , Db6 = Portd.3 , Db7 = Portd.2 , E = Portb.0 , Rs = Portb.1
'set to 1 for print to rs232 debuging
I = 1
Set Portb.2 'turn back light on
#if Test = 1
Print "starting"
#endif
1wwrite C1w_skip_rom , 1 , Poort , 4 'address all devices
1wwrite C1w_convert_t , 1 , Poort , 4 'tell all to convert
'Now search for devices on the bus
Call Look_for_devices
#if Uselcd = 1
Cls
Locate 1 , 1
Lcd "family code";
Locate 2 , 1
Lcd Hex(sc(1));
Wait 5
Cls
#endif
Call Read_ds1820(4)
#if Uselcd = 1
Cls
Locate 1 , 1
Lcd "Deg C " ;
Zs = Fusing(z , "##.##")
Lcd Zs
#endif
End
'-------------------------------------------------------------------------------
' Name: Read_DS1820()
' Function: read the temperature from sensor (separated temp sensor)
' Input : 1Wire Hardware
'-------------------------------------------------------------------------------
Sub Read_ds1820(byval Piin As Byte )
Local T As Integer
Local Tt As Single
Local Tl As Single
'clear variables
Z = 0
T = 0
Call Send1wire_cmd(c1w_rd_scratchpad , 4 ) ' read scratchpad
Sc(1) = 1wread(9 , Poort , Piin ) ' read bytes in array
If Sc(9) = Crc8(sc(1) , 8) Then ' check CRC
'find the resolution of temp bits
Select Case Sc(5)
Case 127 ' 127 = 12 bits
Tl = 0.0625
Case 95 ' 95 = 11 bit
Tl = 0.125
Case 63 ' 63 = 10 bits
Tl = 0.25
Case 31 ' 31 = 9 bits
Tl = 0.5
End Select
T = Makeint(sc(1) , Sc(2))
Tt = T
Tt = Tt * Tl
Z = Tt
End If
Call Send1wire_cmd(c1w_convert_t , 4) ' start conversion for next read
End Sub Read_ds1820()
'-------------------------------------------------------------------------------
' Name: Send1wire_cmd(cmd)
' Function: Send a command to a predefined 1W device dsid()
' Input : 1WIRE Command (see command list)
' Output: 1Wire Hardware
'-------------------------------------------------------------------------------
Sub Send1wire_cmd(byval Cmd As Byte , Byval Piin As Byte )
1wverify Sc(1) , Poort , Piin ' Send chip unique ID
If Err = 0 Then
1wwrite Cmd , 1 , Poort , Piin ' send command
End If
End Sub
'------------------------------------------------------------
'==Search for devices on the buss
'==Put the IDs new into EEPROM
'------------------------------------------------------------
Sub Look_for_devices
Local Xv As Byte
Xv = 0
'Now search for the first device on the bus
Sc(1) = 1wsearchfirst(poort , 4)
Cls
Locate 1 , 1
Cntr = 1
If Err = 0 Then 'found device
#if Test = 1
Print "found one"
#endif
Incr Xv 'add one for every device found
Call Check_stord
End If
Lcd Hex(sc(i)); 'print the number to LCD
Print Hex(sc(i)); 'print the number
'Wait 2
#if Test = 1
Print
Print
#endif
Wait 1
Do
' Now Search For Other Devices
Sc(1) = 1wsearchnext(poort , 4)
If Err = 0 Then 'found device
#if Test = 1
Print "found another"
#endif
Incr Xv
Call Check_stord
End If
'Print
Loop Until Err = 1
Locate 2 , 1
Cntr = 1
#if Test = 1
Print Xv ; " devices found"
#endif
End Sub
'==save device IDs to eeprom
Sub Save_eeprom
Local Xl As Byte
Local Wd As Double
#if Test = 1
Print "save eeprom"
#endif
'blank eeprom is all FFFF
Workw(1) = &HFFFFFFFF
Workw(2) = &HFFFFFFFF
For Xl = 1 To Devices
Wd = Devs(xl)
If Wd = Work Then 'blank eeprom bytes are FF
#if Test = 1
Print "WD is it"
#endif
Devs(xl) = Scd 'save to eeprom
Exit For
Elseif Wd = 0 Then
#if Test = 1
Print "WD is it"
#endif
Devs(xl) = Scd 'save to eeprom
Exit For
End If
Next
If Xl = Devices Then
#if Test = 1
Print "Not saved out of space"
#endif
End If
End Sub
Sub Check_stord
Local Devpoint As Byte
Local Res As Byte
#if Test = 1
Print "Checking!"
#endif
For Devpoint = 1 To Devices
Dev_sc = Devs(devpoint)
#if Test = 1
Print "If Scd = Dev_sc Then "
Print "Sc() " ;
For I = 1 To 8
Print Hex(sc(i));
Next
Print
Print "Dev_scb " ;
For I = 1 To 8
Print Hex(dev_scb(i));
Next
Print
#endif
'Now we use the MWS Compare!
Res = Compare(dev_scb , Scd , 8)
If Res = 0 Then 'stored
Exit For 'its stored so lets not waste time
End If
Next
If Res > 0 Then
#if Test = 1
Print "not stored"
#endif
Call Save_eeprom
Else
#if Test = 1
Print "device stored"
#endif
End If
End Sub
'===============
' The MWS Compare
' "==============="
Function Compare(val1 As Byte , Val2 As Byte , Byval Btcomp As Word) As Word
!LD XL, Y+0 ' get pointer to BtComp
!LD XH, Y+1
!LD R24, X+ ' R24/25 as counter
!LD R25, X
!MOVW R16, R24 ' save BtComp for later calculation of mismatch position
!LD XL, Y+4 ' get pointer to Val1 into X
!LD XH, Y+5
!LD ZL, Y+2 ' get pointer to Val2 into Z
!LD ZH, Y+3
!cmp_start:
!LD R20, X+ ' X points to Val1
!LD R21, Z+ ' Z points to Val2
!CP R20, R21 ' compare!
!BRNE cmp_nomatch ' if equal: ok, next one
!SBIW R24, 1 ' decrease loop counter
!BRNE cmp_start ' if not zero do another turn
!RJMP cmp_end
!cmp_nomatch:
!SBIW R24, 1 ' else: calculate the position of compare mismatch
!SUB R16, R24
!SBC R17, R25
!MOVW R24, R16
!cmp_end:
!LD XL, Y+6
!LD XH, Y+7
!ST X+, R24 ' store success or position of mismatch
!ST X, R25
End Function
|
|
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Mon Jun 20, 2016 1:06 pm Post subject: |
|
|
Sadly this one can not be used with the free version as it just exceeds the 4K limit by 200 bytes.
But the .HEX & .BIN files will let you load the UNO
Note the I2C address has been set to H46 by shorting A2 on the board
This uses the Arduino UNO with an Pcf8574 I2C lcd driver to display the
Family code on the LCD and the temprature
Regards Paul |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|