I2C Bus Search Program for Slaves

AllyCat

Senior Member
Hi,

At around 1300 bytes this is hardly a "snippet", but it has been cut and edited from a thread in the Active Forum, before it disappears under the weight of new posts. ;) The original program was intended to check for the existence of a few I2C chips under rather specific conditions, so I have adapted it to be a more "Universal" program. It should work with all M2 PICaxes (and perhaps a few others) and includes additional Bus tests to hopefully trap the most common Hardware construction Issues.

The 10,000 character forum limit won't allow me to add much explanation here, but most details should be documented within the comments. Basically, the top few text lines need to be edited to suit the Hardware configuration (PICaxe type, etc.) and in principle the single 6-pin header shown in the "ASCII Art" could check any breakout module having 4 sequential in-line pins, provided that SDA and SCL are adjacent. However, there might be issues if trying to use the SerOut pin (c.0) of an 08M2 to select the power supply to the breakout board. Any general questions might be best asked in the Active Forum thread linked above.
Code:
; **  Find Slaves on I2C Bus : IDENTIFY-003  Revised by AllyCat September 2020  **

; Prog --@-----\/\/\-----+ 100k    "Universal" I2C header
;        |  ,----_----,  |      SO      ,-,              
; Vdd ---|--| V+   0V |--@-- 0V  | +----|O| PWR/GND
;        +->| SI  C.0 |>---------@-|--@-|O| GND/pwr
;      +--<>| C.4 C.1 |<>-- SCL ---|--|-|O| SCL
;      |  ->| C.3 C.2 |<>-- SDA ---|--|-|O| SDA
;      |    '---------'            @--|-|O| PWR/GND
;      +---------------------------+  +-|O| GND/pwr
;                                       '-'
; Some Breakout boards include pull-up resistors for SDA and SCL
; This Program Enables the PICaxe's internal pull-ups if external pull-ups are missing

#define picaxe08    ; ** Choose 08,14,18 or 20 suffix and PWR/GND output pins if used **
#no_data            ; Speeds up the Programming
#terminal 4800      ; Activate the Terminal Emulator after programming
;#define simulating ; Can use with PE5, Automatic with PE6
Symbol SADDE = $DE  ; Address of any "expected" but not found Slave (Uncomment the Patch)

#ifdef picaxe08
#picaxe 08m2
#define ok
Symbol SCL = C.1 : Symbol pinSCL = pinC.1    ; Leg 6
Symbol SDA = C.2 : Symbol pinSDA = pinC.2    ; Leg 5
;Symbol PWR = C.4              ; Leg 3   (Uncomment to Enable output)
;Symbol GND = C.0              ; Leg 7 Defaults to GND (& used for SerOut)
Symbol MINVOLTS = 240        ; Minimum Suppy in Tens of mV (for 08M2)
#endif
#ifdef Picaxe14
#Picaxe 14M2
#define ok
Symbol SCL = B.3 : Symbol pinSCL = pinB.3    ; Leg 10
Symbol SDA = B.4 : Symbol pinSDA = pinB.4    ; Leg 9
;Symbol PWR = B.5              ; Leg 8   (Uncomment to Enable output)
;Symbol GND = B.2              ; Leg 11  (Uncomment to Enable output)
Symbol MINVOLTS = 190       ; Minimum Suppy in Tens of mV (for 14M2)
#endif
#ifdef Picaxe18
#Picaxe 18M2
#define ok
Symbol SCL = B.4 : Symbol pinSCL = pinB.4    ; Leg 10
Symbol SDA = B.1 : Symbol pinSDA = pinB.1    ; Leg 7
;Symbol PWR = B.0              ; Leg 6    (Uncomment to Enable output)
;Symbol GND = B.7              ; Leg 13   (Uncomment to Enable output)
Symbol MINVOLTS = 190        ; Minimum Suppy in Tens of mV (for 18M2)
#endif
#ifdef picaxe20
#picaxe 20m2
#define ok
Symbol SCL = B.7 : Symbol pinSCL = pinB.7    ; Leg 11 (eg. Linked to B.4 Leg 14)
Symbol SDA = B.5 : Symbol pinSDA = pinB.5    ; Leg 13
;Symbol PWR = B.6              ; Leg 12   (Uncomment to Enable output)
;Symbol GND = B.2              ; Leg 16   (Uncomment to Enable output)
Symbol MINVOLTS = 190          ; Minimum Suppy in Tens of mV (for 20M2)
#endif
#ifNdef ok
SerTxd("Sorry,Pinout not Programmed")
Symbol SCL = 0 : Symbol pinSCL = pin0        ; Dummy values to avoid syntax errors
Symbol SDA = 0 : Symbol pinSDA = pin0
Symbol MINVOLTS = 0
Stop
#endif

Symbol GND = 0    ; Uncomment if not defined (Editor reports error if already defined)
Symbol PWR = 0    ; Uncomment if not defined (Editor reports error if already defined)
Symbol MAXVOLTS = 550        ; Maximum Supply rail in Tens of mV
SerTxd(CR,LF,"SCL= ",#SCL,"  SDA= ",#SDA,"  V+= ",#PWR,"  GND=",#GND,CR,LF)
; **  Main Program  **
PowerOnReset:
Pause 1000
Do
  Gosub VoltCheck
  b0 = PWR                   ; Can't compare constants (eg PWR = GND)
  If b0 <> GND then          ; enable PWR/GND output pins
    High PWR
    Low GND
  Endif
  Gosub BusCheck             ; And enable pullups if required
  Pause 100
;  hi2csetup i2cmaster,SADDE,i2cslow,i2cbyte   ; Optional Patch, E.G. for MCP1740
;  hi2cin 0,(b0)                               ; Sometimes needed to "Wake Up" a chip
Main:
  SerTxd( CR, LF, "Looking for Devices ...", CR, LF )
  Gosub FindDevices
  Pullup OFF
  Pause 4000
Loop
; **  Check PSU Voltage and Bus hardware  **
VoltCheck:
  Do
#ifdef simulating
    w0 = 500                 ; Nominal 5v power supply
#else
    Calibadc10 w0
    w0 = w0 / 2 + 52378 / w0
    Calibadc10 w1            ; Sample again to average and give 10mV resolution
    w0 = 52378 / w1 + w0
#endif
    b11 = w0 // 10           ; Hundredths
    b12 = w0 / 10 // 10      ; Tenths
    b13 = w0 / 100           ; Units
    SerTxd( CR,LF,"Vpsu = ",#b13,".",#b12,#b11," Volts")
    Select Case w0
      Case < MINVOLTS : SerTxd( ": Supply too Low", CR, LF )
      Case > MAXVOLTS : SerTxd( ": Supply too High", CR, LF )
    End Select
  Pause 500
  Loop Until w0 >= MINVOLTS AND w0 =< MAXVOLTS     ; Only Return when supply rail is valid
  Return
BusCheck:
  Pullup OFF
  Low SDA               ; Make Low now to catch a SDA to SCL bridge
  Low SCL
  Input SCL              ; Float pin
  Call Wait10
  If pinSCL = 0 then
    Gosub pullups       ; PULLUP command cannot use a variable (PE6 can use #define)
    If pinSCL = 0 then
      SerTxd(CR,LF,"SCL held Low")
    Else
      SerTxd(CR,LF,"No SCL Pullup")
    Endif
    Pullup OFF
  Endif
  Input SDA
    Call Wait10
  If pinSDA = 0 then
    Gosub pullups
    If pinSDA = 0 then
      SerTxd(CR,LF,"SDA held Low")
    Else
      SerTxd(CR,LF,"No SDA Pullup")
    Endif
  Endif        ; Now fall into pullups in case SCL needs a pullup
Pullups:
#ifdef picaxe08
  Pullup %110
#endif
#ifdef picaxe14
  Pullup %11000
#endif
#ifdef picaxe18
  Pullup %10010
#endif
#ifdef picaxe20
  Pullup %10100000
#endif
  Call Wait10
Return
; **  Search For Devices  **
FindDevices:
  bptr = 20
  @bptr = 0
  SerTxd( CR, LF, " ")
  For b0 = $00 To $1F Step 2
    If b0 = $10 Then
      SerTxd( "    " )
    End If
    SerTxd( "  " ) : Gosub HexLsd
  Next
  b10 = $00                      ; Address to try
  b12 = $00                      ; Address found
  Do
    b0 = b10 AND $1F
    Select Case b0
      Case $00
        SerTxd( CR, LF )
        b0 = b10 / $10 : Gosub HexLsd
      Case $10
        SerTxd( "   " )
        b0 = b10 / $10 : Gosub HexLsd
    End Select
    If b10 < $10 OR b10 >= $F0 Then
      SerTxd( " XX" )
    Else
      Gosub CheckForDevice
    End If
    b10 = b10 + 2
  Loop Until b10 = 0
  SerTxd( CR, LF, CR, LF )
  bptr = 20
  b0 = @bptrinc AND 254
  If b0 = 0 then
       SerTxd( "No devices found" )
  Else
    Do
      SerTxd ( "Device found at " )
       Gosub Hex
      SerTxd(" = ")
      Select Case b0
        Case $40 to $4E : SerTxd ( "Expander PCF8574" )
        Case $78        : SerTxd ( "SSD1306 OLED" )
        Case $70 to $7E : SerTxd ( "Expander PCF8574A" )
        Case $A4        : SerTxd ( "Wii Controller" )
        Case $A6        : SerTxd ( "Wii Motion Plus" )
        Case $A0 to $AE : SerTxd ( "EEPROM 24LCxxx" )
;        Case $A0 to $AE : SerTxd ( "RAM PCF8570 256 bytes" )
        Case $C6        : SerTxd ( "AXE033 (Rev.Ed.)" )
        Case $D0        : SerTxd ( "RTC (Maxim)" )
        Case $DE        : SerTxd ( "RTC (MCP7940)" )
      Else
        SerTxd ( "  (Unknown)" )
      End Select
      SerTxd( CR, LF )
      b0 = @bptrinc AND 254
    Loop  until b0 = 0
  Endif
Return

CheckForDevice:
; Gosub ResetBus
  Gosub SendStart
  b0 = b10 OR 1                 ; Read bit
  Gosub SendByte
  Gosub ReadAck
; Gosub SendStop
  If b0 = 0 Then
; Ack
    @bptrinc = b10
    @bptr = 0
    SerTxd( " " ) : b0 = b10 : Gosub Hex
  Else
; Nak
    SerTxd( " --" )
  End If
  Gosub ReadByte
  Gosub SendNack
  Gosub SendStop  
  Return
; **  Low-Level I2C Routines  **
SendStart:
  Input SCL   ; SCL = 1
  Gosub Stretch
  Input SDA   ; SDA = 1
  Low   SDA   ; SDA = 0
  Low   SCL   ; SCL = 0
  Return
ResetBus:
  Input SDA   ; SDA = 1
  Low   SCL   ; SCL = 0
  For b1 = 0 To 8
    Input SCL ; SCL = 1
    Low   SCL ; SCL = 0
  Next
SendStop:
  Low   SDA   ; SDA = 0
  Low   SCL   ; SCL = 0
  Input SCL   ; SCL = 1
  Gosub Stretch
  Input SDA   ; SDA = 1
  Return
SendByte:
  For b1 = 0 To 7
    If bit7 = 0 Then
      Low  SDA  ; SDA = 0
    Else
      Input SDA ; SDA = 1
    End If
    Input   SCL ; SCL = 1
    Gosub   Stretch
    Low     SCL ; SCL = 0
    b0 = b0 + b0
  Next
  Return
ReadByte:
  Low   SCL     ; SCL = 0
  Input SDA     ; SDA = 1
  For b1 = 0 To 7
    Input SCL   ; SCL = 1
    Gosub Stretch
    b0 = b0 + b0 + pinSDA
    Low SCL     ; SCL = 0
  Next
  Return
ReadAck:
  Input SDA     ; SDA = 1
  Input SCL     ; SCL = 1
  Gosub Stretch
  b0  = pinSDA
  Low   SCL     ; SCL = 0
  Return
SendAck:
  Low   SDA     ; SDA = 0
  Input SCL     ; SCL = 1
  Gosub Stretch
  Low   SCL     ; SCL = 0
  Return
SendNack:
  Input SDA     ; SDA = 1
  Input SCL     ; SCL = 1
  Gosub Stretch
  Low   SCL     ; SCL = 0
  Return
Stretch:
  Do : Loop While pinSCL = 0
  Return
Wait10:       ; May be needed with Higher pullup resitances or bus capacitance
  Pause 7    ; 10 ms pause
Return
; **  Display Output Routines  **
Hex:
  b1 = b0 / $10 : Gosub Nibble
HexLsd:
  b1 = b0
Nibble:
  b1 = b1 AND $0F + "0"
  If b1 > "9" Then : b1 = b1 + 7 : End If
  SerTxd( b1 )
  Return
; **  End Of Program  **
Cheers, Alan.
 

AllyCat

Senior Member
Hi,

Here is a sample result from the Program above, which wouldn't fit within the forum's character limit. Note that the numbers shown in the first line are PICaxe PIN numbers (derived from the appropriate PICaxe's Port.Pin names), they are NOT "Leg" or Header pin numbers.
Code:
SCL= 3  SDA= 4  V+= 5  GND=2

Vpsu = 3.67 Volts
Looking for Devices ...

   0  2  4  6  8  A  C  E      0  2  4  6  8  A  C  E
0 XX XX XX XX XX XX XX XX   1 -- -- -- -- -- -- -- --
2 -- -- -- -- -- -- -- --   3 -- -- -- -- -- -- -- --
4 -- -- -- -- -- -- -- --   5 -- -- -- -- -- -- -- --
6 -- -- -- -- -- -- -- --   7 -- -- -- -- 78 -- -- --
8 -- -- -- -- -- -- -- --   9 -- -- -- -- -- -- -- --
A A0 -- -- -- -- -- -- AE   B -- -- -- -- -- -- -- --
C -- -- -- -- -- -- -- --   D D0 -- -- -- -- -- -- --
E -- -- -- -- -- -- -- --   F XX XX XX XX XX XX XX XX

Device found at 78 = SSD1306 OLED
Device found at A0 = EEPROM 24LCxxx
Device found at AE = EEPROM 24LCxxx
Device found at D0 = RTC (Maxim)
An explanation that I couldn't fit into the main description is that, for an unknown reason, the original program code often doesn't "find" a
MCP7940 (and there might be others) if it has been powered down for a "long" time. So an optional "Patch" for any "Expected" (but not found) Slave Address (SADDE) has been included, but is commented out until needed.

Cheers, Alan.
 

AllyCat

Senior Member
Hi,

Interesting, I didn't actually look at the I2C code as such, just revised the UI code to overcome the issues with its general-purpose usage. It was quite easy to replace the "CheckForDevice" routine with yours, which although much less verbose didn't reduce the number of program bytes by as much as I expected. However, the version using your code runs much faster, even with the "search table" display still included. I had been considering removing that as being an unnecessary overhead, but it does at least indicate the Slave Addresses that are considered to be "valid".

So here is my revised code; Of course it (now) needs a different configuration for the (20)X2, which I've implemented (but cannot test) for only the 20X2. It doesn't appear to need the previous "patch" for the MCP7940.
Code:
; **  Find Slaves on I2C Bus :  Revised by AllyCat October 2020  **
;  Using alternative  "CheckForDevice" I2C subroutine method from Phil Hornby

; Prog --@-----\/\/\-----+ 100k    "Universal" I2C header
;        |  ,----_----,  |      SO      ,-,              
; Vdd ---|--| V+   0V |--@-- 0V  | +----|o| PWR/GND
;        +->| SI  C.0 |>---------@-|--@-|o| GND/pwr
;      +--<>| C.4 C.1 |<>-- SCL ---|--|-|o| SCL
;      |  ->| C.3 C.2 |<>-- SDA ---|--|-|o| SDA
;      |    '---------'            @--|-|o| PWR/GND
;      +---------------------------+  +-|o| GND/pwr
;                                       '-'
; Some breakout boards include pull-up resistors for SDA and SCL
; This program enables chip pull-ups if external pull-ups are missing

#define picaxe14    ; ** Choose 08,14,18 or 20 suffix and PWR/GND output pins if used **
; #define X2       ; Alternative SFR address calculation (also must define #picaxe20)
#no_data            ; Speeds up the Programming
; #define simulating ; Can use with PE5, Automatic with PE6

#ifdef X2                        ; (Untested)
#terminal 9600      ; Activate the Terminal Emulator after programming
#define ok
symbol sspbuf = $C9       ; For all X2s
#picaxe 20x2
Symbol SCL = B.7 : Symbol pinSCL = pinB.7    ; Leg 11 (eg. Linked to B.4 Leg 14)
Symbol SDA = B.5 : Symbol pinSDA = pinB.5    ; Leg 13
; Symbol PWR = B.6                             ; Leg 12   (Uncomment to Enable output)
; Symbol GND = B.2                             ; Leg 16   (Uncomment to Enable output)
Symbol MINVOLTS = 190                        ; Minimum Suppy in Tens of mV (for 20M2)
#else
symbol sspbuf = $91        ; For all M2s
#terminal 4800      ; Activate the Terminal Emulator after programming
#ifdef picaxe08
#picaxe 08m2
#define ok
Symbol SCL = C.1 : Symbol pinSCL = pinC.1    ; Leg 6
Symbol SDA = C.2 : Symbol pinSDA = pinC.2    ; Leg 5
; Symbol PWR = C.4                            ; Leg 3   (Uncomment to Enable output)
; Symbol GND = C.0                            ; Leg 7 Defaults to GND (& used for SerOut)
Symbol MINVOLTS = 240                        ; Minimum Suppy in Tens of mV (for 08M2)
#endif

#ifdef Picaxe14
#Picaxe 14M2
#define ok
Symbol SCL = B.3 : Symbol pinSCL = pinB.3    ; Leg 10
Symbol SDA = B.4 : Symbol pinSDA = pinB.4    ; Leg 9
; Symbol PWR = B.5                             ; Leg 8   (Uncomment to Enable output)
; Symbol GND = B.2                             ; Leg 11  (Uncomment to Enable output)
Symbol MINVOLTS = 190                        ; Minimum Suppy in Tens of mV (for 14M2)
#endif

#ifdef Picaxe18
#Picaxe 18M2
#define ok
Symbol SCL = B.4 : Symbol pinSCL = pinB.4    ; Leg 10
Symbol SDA = B.1 : Symbol pinSDA = pinB.1    ; Leg 7
; Symbol PWR = B.0                             ; Leg 6    (Uncomment to Enable output)
; Symbol GND = B.7                             ; Leg 13   (Uncomment to Enable output)
Symbol MINVOLTS = 190                        ; Minimum Suppy in Tens of mV (for 18M2)
#endif

#ifdef picaxe20
; #picaxe 20m2
#define ok
Symbol SCL = B.7 : Symbol pinSCL = pinB.7    ; Leg 11 (eg. Linked to B.4 Leg 14)
Symbol SDA = B.5 : Symbol pinSDA = pinB.5    ; Leg 13
; Symbol PWR = B.6                          ; Leg 12   (Uncomment to Enable output)
; Symbol GND = B.2                          ; Leg 16   (Uncomment to Enable output)
Symbol MINVOLTS = 190                    ; Minimum Suppy in Tens of mV (for 20M2)
#endif
#endif

#ifNdef ok
SerTxd("Sorry,Pinout not Programmed")
Symbol SCL = 0 : Symbol pinSCL = pin0        ; Dummy values to avoid syntax errors
Symbol SDA = 0 : Symbol pinSDA = pin0
Symbol MINVOLTS = 0
Stop
#endif

Symbol GND = 0    ; Comment out if defined (Editor reports error if already defined)
Symbol PWR = 0    ; Comment out if defined (Editor reports error if already defined)
Symbol MAXVOLTS = 550        ; Maximum Supply rail in Tens of mV
SerTxd(cr,lf,"SCL= ",#SCL,"  SDA= ",#SDA,"  V+= ",#PWR,"  GND=",#GND,cr,lf)

; **  Main Program  **

PowerOnReset:
Pause 1000
Do
  Gosub VoltCheck
  b0 = PWR                   ; Can't compare constants (eg PWR = GND)
  If b0 <> GND then          ; enable PWR/GND output pins
    High PWR
    Low GND
  Endif
  Gosub BusCheck             ; And enable pullups if required
  Pause 100

Main:
  SerTxd( CR, LF, "Looking for Devices ...", CR, LF )
  Gosub FindDevices
  Pullup OFF
  Pause 4000
Loop

; **  Check PSU Voltage and Bus hardware  **
VoltCheck:
  Do
#ifdef simulating
    w0 = 500                 ; Nominal 5v power supply
#else
    Calibadc10 w0
    w0 = w0 / 2 + 52378 / w0
    Calibadc10 w1            ; Sample again to average and give 10mV resolution
    w0 = 52378 / w1 + w0
#endif
    b11 = w0 // 10           ; Hundredths
    b12 = w0 / 10 // 10      ; Tenths
    b13 = w0 / 100           ; Units
    SerTxd( cr,lf,"Vpsu = ",#b13,".",#b12,#b11," Volts")
    Select Case w0
      Case < MINVOLTS : SerTxd( ": Supply too Low", cr, lf )
      Case > MAXVOLTS : SerTxd( ": Supply too High", cr, lf )
    End Select
  Pause 500
  Loop Until w0 >= MINVOLTS AND w0 =< MAXVOLTS     ; Only Return when supply rail is valid
  Return

BusCheck:
  Pullup OFF
  Low SDA                       ; Make Low now to catch a SDA to SCL bridge
  Low SCL
  Input SCL                     ; Float pin
  Call Wait10
  If pinSCL = 0 then
    Gosub pullups               ; PULLUP command cannot use a variable (PE6 can use #define)
    If pinSCL = 0 then
      SerTxd(cr,lf,"SCL held Low")
    Else
      SerTxd(cr,lf,"No SCL Pullup")
    Endif
    Pullup OFF
  Endif
  Input SDA
    Call Wait10
  If pinSDA = 0 then
    Gosub pullups
    If pinSDA = 0 then
      SerTxd(cr,lf,"SDA held Low")
    Else
      SerTxd(cr,lf,"No SDA Pullup")
    Endif
  Endif                          ; Now fall into pullups in case SCL needs a pullup
Pullups:
#ifdef picaxe08
  Pullup %110
#endif
#ifdef picaxe14
  Pullup %11000
#endif
#ifdef picaxe18
  Pullup %10010
#endif
#ifdef picaxe20
  Pullup %10100000
#endif
  Call Wait10
Return

; **  Search For Devices  **
FindDevices:
  bptr = 20
  @bptr = 0
  SerTxd( CR, LF, " ")
  For b0 = $00 To $1F Step 2
    If b0 = $10 Then
      SerTxd( "    " )
    End If
    SerTxd( "  " ) : Gosub HexLsd
  Next
  b10 = $00                      ; Address to try
  b12 = $00                      ; Address found
  Do
    b0 = b10 AND $1F
    Select Case b0
      Case $00
        SerTxd( CR, LF )
        b0 = b10 / $10 : Gosub HexLsd
      Case $10
        SerTxd( "   " )
        b0 = b10 / $10 : Gosub HexLsd
    End Select
    If b10 < $10 OR b10 >= $F0 Then
      SerTxd( " XX" )
    Else
      Gosub CheckForDevice
    End If
    b10 = b10 + 2
  Loop Until b10 = 0
  SerTxd( CR, LF, CR, LF )
  bptr = 20
  b0 = @bptrinc AND 254
  If b0 = 0 then
       SerTxd( "No devices found" )
  Else
    Do
      SerTxd ( "Device found at " )
       Gosub Hex
      SerTxd(" = ")
      Select Case b0
        Case $40 to $4E : SerTxd ( "Expander PCF8574" )
        Case $78        : SerTxd ( "SSD1306 OLED" )
        Case $70 to $7E : SerTxd ( "Expander PCF8574A" )
        Case $A4        : SerTxd ( "Wii Controller" )
        Case $A6        : SerTxd ( "Wii Motion Plus" )
        Case $A0 to $AE : SerTxd ( "EEPROM 24LCxxx" )
;        Case $A0 to $AE : SerTxd ( "RAM PCF8570 256 bytes" )
        Case $C6        : SerTxd ( "AXE033 (Rev.Ed.)" )
        Case $D0        : SerTxd ( "RTC (Maxim)" )
        Case $DE        : SerTxd ( "RTC (MCP7940)" )
      Else
        SerTxd ( "  (Not Programmed)" )
      End Select
      SerTxd( CR, LF )
      b0 = @bptrinc AND 254
    Loop  until b0 = 0
  Endif
Return

CheckForDevice: 
       hi2csetup i2cmaster,b10,i2cslow,i2cbyte     ; Set up I2c. Enable SDA/SCL,          
       hi2cout (0)                                    ; Just send a 0 as data             ;
       peeksfr sspbuf,b0                             ; so, what was that last byte?
  If b0 = 0 Then
    @bptrinc = b10
    @bptr = 0
    SerTxd( " " ) : b0 = b10 : Gosub Hex
  Else
    SerTxd( " --" )
  End If
Return

Wait10:               ; May be needed with Higher pullup resistances or bus capacitance
  Pause 7             ; 10 ms pause
Return

; **  Display Output Routines  **
Hex:
  b1 = b0 / $10 : Gosub Nibble
HexLsd:
  b1 = b0
Nibble:
  b1 = b1 AND $0F + "0"
  If b1 > "9" Then : b1 = b1 + 7 : End If
  SerTxd( b1 )
  Return

; **  End Of Program  **
I also created a version without the tabular output, for all Slave Addresses, which appears to hang (only) at Addresses $00 and $FE.

Cheers, Alan.
 

PhilHornby

Senior Member
Looks good!

Tried it on a 14M2, where it successfully found a DS1307 + attendant EEPROM + PCF8574 on an LCD module

I also tried it on a 20X2, where it successfully detected a HTU12D @ 80h. (Download to 20X2 is speeded-up slightly, if #no_table is enabled).
 
Top