Menu

Rom-ID Finder for 1-wire devices on a multidrop line

Theo
2016-03-08
2016-03-10
  • Theo

    Theo - 2016-03-08
    '''Rom ID Finder for Multidrop and hardware serial output with Atmega8
    '''------------------------------------------------------------------------
    '''
    '''This program is based on the Search Algorythm described in MAXIM AN817.
    '''The variable names are (as far as possible) identical to the application note.
    '''The CRC8 algorythm is based on public sources found on the internet.
    '''
    '''The program searches and finds the Rom ID's of multiple 1-wire devices
    '''connected to a so called Multidrop. A Multidrop is a line with 2 or more
    '''1-wire devices connected in normal or parasite Power mode.
    '''Parasite Power mode is not supported for now.
    '''
    '''
    '''This program can be adapted to any of the supported microprocessor
    '''by simply changing the #chip as follows: #chip 16f877a, 4
    '''and by choosing the right connections for the Hardware UART and OW input pin.
    '''
    '''@Theo Loermans
    '''@licence GPL
    '''@version 1.0
    '''@date    08.03.2016
    '''********************************************************************************
    
      #chip mega8, 16
    
      ; ----- Define Hardware settings
      ; Required to LCD to Serial redirection
      #define LCD_IO 0
      #define USART_BAUD_RATE 9600
      Dir PORTD.1 Out
      Dir PORTD.0 In
      #define USART_BLOCKING
    
      ; #define debug                   ' if activate, the script produces additional output
      #define DQ PortB.0            ; input pin for 1-wire device(s), normal power mode with pullup 4K7
      Dim ROM_NO(9) as byte   ; 9 ROM_NO bytes to store ID Bytes + CRC; don't use ROM_NO(0)
      Dim ByteNum as byte
    
      'DS18X20 Settings
      #define SearchRom 240                         '0xF0 (240) 'Command for identifying Slave Rom codes,
      #define ReadPowerSup 180                  '0XB4 (180) 'Read Power Supply mode
        #define SkipRom 204                             '0xCC (204) 'Command for addressing all devices simultaneously
    
    'Start main program
        HSerPrint "Multidrop ID-Search.":CRLF
      HSerPrint "No. Family + Rom Number = ID-Number        CRC    Status":CRLF
    
        MasterRST                                           ' reset and check presence of sensor(s)
    
      if command = 2 then
        HSerPrint "Check line, shorted?":CRLF
            End                                                 ' exit script, resolve problem
      end if
    
      if command = 1 then
            HSerPrint "No device(s) detected!":CRLF
        End                                                 ' exit script for now, future expand
        end if
    
    ' sequence for checking Power Supply Mode
        OWout SkipRom
        OWout ReadPowerSup                      ' read power Supply Mode
      OWinBit Command
        If not Command Then
            HSerPrint "Parasite power mode detected!":CRLF
        HSerPrint "Not supported now, program end.":CRLF
        End                                                 ' Parasite mode not supported now, stop program
        end If
    
    ''Init Variable
        TotDevF = 0
        LastDiscrepancy = 0
      LastFamilyDiscrepancy = 0
      LastDeviceFlag = 0
      Returnvalue = 0
      For Bytenum = 1 to 9
        ROM_NO(Bytenum)=0
      Next
    
    ' Start ID Search
        Search ' This is the first Search
    
    Do
      If Returnvalue = 1 then
            #ifdef debug
          HSerPrint "Returnvalue = 1":CRLF
          HSerPrint "LastDeviceFlag = ":HSerPrint LastDeviceFlag:CRLF
        #Endif
        if TotDevF < 10 then HSerPrint " "
        HSerPrint TotDevF:HSerPrint "  "
        HSerprint "0x":HSerPrint HEX(ROM_NO(1)):HSerPrint "   "
        For Bytenum = 2 to 7
            HSerprint "0x":HSerPrint HEX(ROM_NO(Bytenum)):HSerPrint " "
        next
        HSerprint "  0x":HSerPrint HEX(ROM_NO(8)):HSerPrint "   "
        #ifdef debug
          HSerPrint "0x":HSerPrint HEX(CRC):HSerPrint "   "
        #Endif
        If CRC = ROM_NO(8) Then ' Calculated CRC identical to found CRC?'
            HSerPrint "OK :-)"
        Else
            HSerPrint "Error :-("
        end if
        CRLF
      Else
        HSerPrint "ID-Search finished." : CRLF:CRLF
        End             ' stop program
      end if
      Search ' second and further Search until Returnvalue = false
    Loop
    
    '-------------------------SUB------------------------------------
    
    Sub Search          ' Start ID Search
      MasterRST
      If LastDeviceFlag = 1 Then
        Returnvalue = 0
        Goto Ready  'Search Finished
      end if
    
      id_bit_number = 0
      last_zero = 0
      Bytenum = 1
      BPiB = 0 ' Bit position in Byte (ROM_NO)
    
      OWout SearchRom
    
      Do While id_bit_number < 64 ; (0-63)
        OWInBit id_bit          'read 1 bit from device
        OWInBit cmp_id_bit  'read 1 bit (complement) from device
    
        if id_bit = 1 AND cmp_id_bit = 1 Then 'invalid value's
          HSerPrint "No answer from device(s)!": CRLF
          Returnvalue = 0
          Goto Ready
        end if
    
        If id_bit = 0 AND cmp_id_bit = 0 Then ' 2 or more devices have the same bit value in common
                #ifdef debug
              HSerPrint "0-0 Discrepancy ":CRLF
            #Endif
    
          If id_bit_number = LastDiscrepancy Then
            Search_Direction = 1
          else
            If id_bit_number > LastDiscrepancy Then
              Search_Direction = 0
            Else
                CalcBPiB
                Select Case BPiB
                  Case 0
                    Set Search_Direction = ROM_NO(Bytenum).0
                  Case 1
                    Set Search_Direction = ROM_NO(Bytenum).1
                  Case 2
                    Set Search_Direction = ROM_NO(Bytenum).2
                  Case 3
                    Set Search_Direction = ROM_NO(Bytenum).3
                  Case 4
                    Set Search_Direction = ROM_NO(Bytenum).4
                  Case 5
                    Set Search_Direction = ROM_NO(Bytenum).5
                  Case 6
                    Set Search_Direction = ROM_NO(Bytenum).6
                  Case 7
                    Set Search_Direction = ROM_NO(Bytenum).7
                End Select
                  #ifdef debug
                  HSerPrint "Bytenum= ":HSerPrint Bytenum:HSerPrint " BPiB= ":HSerPrint BPiB
                  HSerPrint " Search dir= ":HSerPrint Search_direction:CRLF
                      #Endif
            end if
          end if
    
          If Search_Direction = 0 Then
            last_zero = id_bit_number
            If last_zero < 8 Then
              LastFamilyDiscrepancy = last_zero
            end if
          end if
        Else
          Search_Direction = id_bit
        End if
            CalcBPiB
    
        Select Case BPiB
            Case 0
               if Search_Direction = 1 then
                 Set ROM_NO(Bytenum).0 On
               else
                 Set ROM_NO(Bytenum).0 Off
               end if
            Case 1
               if Search_Direction = 1 then
                 Set ROM_NO(Bytenum).1 On
               else
                 Set ROM_NO(Bytenum).1 Off
               end if
            Case 2
               if Search_Direction = 1 then
                 Set ROM_NO(Bytenum).2 On
               else
                 Set ROM_NO(Bytenum).2 Off
               end if
            Case 3
               if Search_Direction = 1 then
                 Set ROM_NO(Bytenum).3 On
               else
                 Set ROM_NO(Bytenum).3 Off
               end if
            Case 4
               if Search_Direction = 1 then
                 Set ROM_NO(Bytenum).4 On
               else
                 Set ROM_NO(Bytenum).4 Off
               end if
            Case 5
               if Search_Direction = 1 then
                 Set ROM_NO(Bytenum).5 On
               else
                 Set ROM_NO(Bytenum).5 Off
               end if
            Case 6
               if Search_Direction = 1 then
                 Set ROM_NO(Bytenum).6 On
               else
                 Set ROM_NO(Bytenum).6 Off
               end if
            Case 7
               if Search_Direction = 1 then
                 Set ROM_NO(Bytenum).7 On
               else
                 Set ROM_NO(Bytenum).7 Off
               end if
        End Select
    
          #ifdef debug
                if id_bit_number < 10 then HSerPrint " "
                HSerPrint id_bit_number: HSerPrint ")"
                HSerPrint " id_bit=":HSerPrint id_bit
                HSerPrint "  cmp_id_bit=":HSerPrint cmp_id_bit
                HSerPrint "  Bytenum=":HSerPrint Bytenum
            HSerPrint "  BPiB=":HSerPrint BPiB
                HSerPrint "  ROM_NO(":HSerPrint Bytenum:HSerPrint ")=0x"
                HSerPrint Hex(ROM_NO(Bytenum))
                HSerPrint "  Search dir=":HSerPrint Search_Direction 'CRLF
                HSerPrint "  last_zero=":HSerPrint last_zero
              HSerPrint "  LastDiscrepancy=":HSerPrint LastDiscrepancy
                HSerPrint "  LastFamilyDiscrepancy=":HSerPrint LastFamilyDiscrepancy:CRLF
            #Endif
    
        OWoutBit Search_Direction ' send search_direction bit to device
    
        Bytenum = (id_bit_number/8) + 1     ' calculate Byte number (1-8) for ROM_NO bytes
        id_bit_number = id_bit_number + 1 ' increment ID bit number (0-63)
      Loop
      LastDiscrepancy = last_zero
      If LastDiscrepancy = 0 Then
        LastDeviceFlag = 1
      end if
    
        CRC = 0                               ' Calculate CRC8: DALLAS/MAXIM, reversed Polynomial
      For index = 1 to 7
        _DB=ROM_NO(index)
        Repeat 8
          FB = (_DB XOR crc) AND 1
          CRC = CRC/2
          _DB = _DB/2
          if FB = 1 then
            CRC = CRC XOR 140 ' 0x8C
          end if
        end Repeat
      next
        Returnvalue = 1
    
      Ready:
      if Returnvalue = 0 then
        LastDiscrepancy = 0
        LastFamilyDiscrepancy = 0
        LastDeviceFlag = 0
      end if
        TotDevF = TotDevF + 1 ' Increment Total Devices Found
    end Sub
    
    Sub CRLF                ' Carriage return, Line feed
      HSerSend 13
      HSerSend 10
    End sub
    
    Sub CalcBPiB            ' by using bytes for the variables there are no fractions if you divide
      Bytenum = (id_bit_number/8)+1                              ' calculate Byte number (1-8)
      BPiB = id_bit_number - ((id_bit_number/8)*8) ' calculate Bit position in Byte (0-7)
    end Sub
    
    Sub OWin (Command)
     IntOff                                                   ' Interrupt Disabled
     Repeat 8
      Rotate Command Right                      ' LSB first
      Dir DQ Out
      Set DQ Off                                        ' Start time slot
      wait 6 us
      Dir DQ In                                         ' Release bus for one wire Reception
      wait 9 us
      If DQ On  Then Set Command.7 1
      If DQ Off Then Set Command.7 0
      wait 55 us
     End Repeat
     IntOn                                                      ' Interrupt Enabled
    end sub
    
    Sub OWinBit (Command)
     IntOff
     Dir DQ Out
     Set DQ Off  ' Start time slot
     wait 6 us
     Dir DQ In   ' Release bus for one wire Reception
     wait 9 us
     If DQ On  Then Set Command = 1
     if DQ Off then Set Command = 0
      wait 55 us
     IntOn
    end sub
    
    Sub OWout (In Command)
     IntOff
     Repeat 8
      wait 1 us     ' Recovery time between write cycles
      Dir DQ Out
      Set DQ Off  ' Start time slot
      wait 6 us
      If Command.0 On then
       Dir DQ In
      End if
      wait 60 us
      Dir DQ In
      ROTATE Command Right  ' LSB first
     End Repeat
     IntOn
    end sub
    
    Sub OWoutBit (In Command)
     IntOff
     wait 1 us      ' Recovery time between write cycles
     Dir DQ Out
     Set DQ Off
     wait 6 us
     If Command.0 On then
      Dir DQ In
     End if
     wait 60 us
     Dir DQ In
     IntOn
    end sub
    
    Sub MasterRST (optional command=0)
     IntOff
     Dir DQ Out
     Set DQ Off
     wait 480 us
     Dir DQ In
     wait 86 us ' 70 us default: tested low 30, High 143; at home: (143-30)/2=56+30=86
     If DQ On then ' No sensor(s) found
        command = 1
     end if
     wait 394 us '410 us default: tested 394
     if DQ Off then ' line still low after end time slot: shorted?
      Command = 2
     end if
     IntOn
    end sub
    
     

    Last edit: Theo 2016-03-09
    • Theo

      Theo - 2016-03-09

      Variable DB changed into _DB, thanks to Anobium.

       
  • jackjames

    jackjames - 2016-03-08

    Beautiful !
    Tomorrow I try it!

     
  • jackjames

    jackjames - 2016-03-08

    I bought it for pic16f877a and i got these errors:

     
    • Theo

      Theo - 2016-03-09

      @jackjames

      There seems to be an issue with the compiler, I get the same kind of errors during compiling with a PIC. (i don't have PIC's , so I didn't try it before). So far no problems with AVR.(knock on wood!)

      Perhaps Anobium can take a look at the problem.

      Theo.

       
  • Anobium

    Anobium - 2016-03-09

    DB is for reserved ASM.

    Please change DB = DB/2 to _DB = = _DB/2

    Something like:

        _DB=ROM_NO(index)
        Repeat 8
          FB = (_DB XOR crc) AND 1
          CRC = CRC/2
          _DB = _DB/2
            .....
    
     
    • Theo

      Theo - 2016-03-09

      Thank you Anobium, I discovered the same, but the reason was unknow to me.
      Perhaps extend the compiler with an error message which tells you the name of the variable that is causing the problem?

      Theo.

       
  • jackjames

    jackjames - 2016-03-10

    Changing the variable name the compilation problem has been solved

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.