farmerkeith / I2CScanner

Simple software to scan an I2C bus and report devices found
3 stars 2 forks source link

Scanner accesses 'reserved' I2C addresses #2

Open Tech-TX opened 5 years ago

Tech-TX commented 5 years ago

All the way back to rev 2.0 of the spec, up to current rev 6: https://www.nxp.com/docs/en/user-guide/UM10204.pdf page 17, 3.1.12 Reserved addresses, the bottom 8 and top 8 addresses are reserved for special purposes. Following that, line 31 is:

      for (address = 8; address < 120; address++ )

If you do that, you might be able to remove that unusual Wire.endTransmission(); at line 29. I couldn't see a reason for it, and commented it out in the file I downloaded. I'd presumed it was a hack for something weird you saw, and banging reserved addresses might cause weird operation with some slaves.

Additionally, for more reliable operation with slow slaves on the ESP8266 using the software wire library, I'd add Wire.setClockStretchLimit(500); or higher just after the Wire.begin(); as the default stretch limit is ridiculously short (230uS). I've seen people pushing that up to 1500us for some parts due to the non-static nature of the 8266 wire library. The ESP32 has a different library with a much longer timeout, so it doesn't need this. I've set my code to 1500us default clock stretch limit until I get hold of a fully-static 8266 library done more like the Arduino library.

Just after Wire.begin(); add

#ifdef ESP8266
Wire.setClockStretchLimit(500);  //may need to increase this to 1500us for slow parts
#endif

Other than that, I've been enjoying your scanner. Thanks! :-)

Tech-TX commented 5 years ago

Update: I found why you'd added that extra Wire.endTransmission(); at the top of the loop. The Wire.endTransmission(); at line 101 is being immediately followed by Wire.requestFrom(address, 1); at line 102, and it's occurring less than 1 clock afterwards and locking the bus low, depending on the Wire library used. Add delayMicroseconds(20); after the Wire.endTransmission(); at line 101 and you don't need that extra endTransmission at the top of the loop.