i2cdetect

Posted on
  • Hi, I'm using an adapted version of i2cdetect for my own i2c experiments. Maybe it is useful for somebody else:

    function scanI2c( i2c, first, last ) {
       if (typeof first === "undefined") {
            first = 0x03;
        }
        if (typeof (last) === "undefined") {
            last = 0x77;
        }
        print( "     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f" );
        for (var upper = 0; upper < 8; ++upper) {
            var line = upper + "0: ";
    
            for (var lower = 0; lower < 16; ++lower) {
                var address = (upper << 4) + lower;
    
                // Skip unwanted addresses
                if ((address < first) || (address > last)) {
                    line += "   ";
                    continue;
                }
    
                try {
                    i2c.readFrom( address, 1 );
                    line += (address + 0x100).toString( 16 ).substr( -2 );
                    line += " ";
                } catch (err) {
                    line += "-- ";
                }
            }
            print( line );
        }
    }
    
    // Usage
    I2C1.setup( {scl: B8, sda: B9} );
    scanI2c( I2C1, 0x03, 0x2f );
    

    Output - first line is not aligned correctly.

         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          03 04 05 06 07 -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    

    What would be the right place for such a code snippet?

    1. Too special → don't share
    2. Own module: require("i2cdetect").scan()
    3. https://gist.github.com/
    4. ???

    It takes quite a long time to scan all addresses. Is it possible to decrease the timeout somehow?

  • That's great! I'm not sure - maybe a tutorial for the website, like 'Detecting I2C devices'?

    I'm afraid that right now the I2C timeout isn't configurable - although I can't really see a reason why it shouldn't be smaller. Even a 50ms timeout should really be more than enough.

  • Yeah, I agree about the timeout. Does anyone know of any I2C devices that don't respond practically instantly? I can't think of any examples - though it'd be nice to be able to set the timeout, I think in the short term, it would be an improvement to just make it shorter.

  • on ESP you can use this with the latest build

    I2C1.setup({sda: D4, scl: D5} );
    
    function isDeviceOnBus(i2c, addr) {
      try {  
        return i2c.readFrom(addr,1);
      } 
      catch(err) { 
        return -1;
      }
    }
    
    function i2cdetect( i2c, first, last ) {
      if (typeof first === "undefined") first = 0x03;
      if (typeof (last) === "undefined") last = 0x77;
    
      print( "     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f" );
      for (var upper = 0; upper < 8; ++upper) {
        var line = upper + "0: ";
        for (var lower = 0; lower < 16; ++lower) {
          var address = (upper << 4) + lower;
          // Skip unwanted addresses
          if ((address < first) || (address > last)) {
            line += "   ";
            continue;
          }
          if ( ! isDeviceOnBus(i2c,address) ){
            line += (address + 0x100).toString( 16 ).substr( -2 )+" ";
          } else 
            line += "-- ";
        }
        print( line );
      }
    }
    
    i2cdetect( I2C1, 0x03, 0x77);
    
    /* sample output for  a connected PCA9635 
    
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: 70 -- -- -- -- -- -- --
    
    */
    
    
    
  • now using a version that returns an array of ids

    var isDevice = function isDeviceOnBus(i2cBus,id) {
          try {
              return i2cBus.readFrom(id,1);
          }
          catch(err) {
              return -1;
          }
    };
    
    var detect = function(i2c,first, last) {
          first = first | 0;
          last = last | 0x77;
          var idsOnBus = Array();
          for (var id = first; id < last; id++) {
              if ( ! isDevice(i2c,id) ) {
                  idsOnBus.push(id);
              }
          }
          return idsOnBus;
    };
    
    
    I2C1.setup({sda: D4, scl: D5} );
    console.log(detect(I2C1));
    
    
  • On ESP you have to add pinMode for the I2C pins when using sdk 2.0

    I2C1.setup({sda: D4, scl: D5} );
    pinMode(D4,"opendrain");
    pinMode(D5,"opendrain");
    

    Not needed - don't know what went wrong....

  • changes:

    • include last id in scan
    • change if clause
    • add I2C1.setup() sample for Espruino boards

    function isDeviceOnBus(i2c,id) {
          try {
            return i2c.readFrom(id,1);
          }
          catch(err) {
            return -1;
          }
    }
    
    function detect(i2c,first, last) {
          first = first | 0;
          last = last | 0x77;
          var idsOnBus = Array();
          for (var id = first; id <= last; id++) {
            if ( isDeviceOnBus(i2c,id) != -1) {
              idsOnBus.push(id);
            }
          }
          return idsOnBus;
    }
    
    // Espruino boards
    // I2C1.setup( {scl: B8, sda: B9} );
    
    // ESP8266 
    I2C1.setup({sda: D2, scl: D4} );
    
    console.log('I2C detect as array:',detect(I2C1));
    
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

i2cdetect

Posted by Avatar for luwar @luwar

Actions