├── I2CDetective.ino ├── I2CDetectiveClue.ino └── README.md /I2CDetective.ino: -------------------------------------------------------------------------------- 1 | /* I2C Detective - see http://www.technoblogy.com/show?3FFW 2 | 3 | David Johnson-Davies - www.technoblogy.com - 19th January 2021 4 | 5 | CC BY 4.0 6 | Licensed under a Creative Commons Attribution 4.0 International license: 7 | http://creativecommons.org/licenses/by/4.0/ 8 | */ 9 | 10 | // Uncomment this for AVR platforms like the Arduino Uno 11 | //#define AVR_DATA 12 | 13 | #include 14 | 15 | typedef struct { 16 | const char *device; 17 | const char *category; 18 | uint8_t from; 19 | uint8_t to; 20 | uint8_t test; 21 | uint8_t value; 22 | } device_t; 23 | 24 | const char UnknownDevice[] PROGMEM = "Unknown Device"; 25 | 26 | // Categories 27 | const char Accelerometer[] PROGMEM = "Accelerometer"; 28 | const char AccelerometerGyroscope[] PROGMEM = "Accelerometer/Gyroscope"; 29 | const char AccelerometerGyroscopeMagnetometer[] PROGMEM = "Accelerometer/Gyroscope/Magnetometer"; 30 | const char AccelerometerMagnetometer[] PROGMEM = "Accelerometer/Magnetometer"; 31 | const char AirQualitySensor[] PROGMEM = "Air Quality Sensor"; 32 | const char Amplifier[] PROGMEM = "Amplifier"; 33 | const char AnaloguetoDigitalConverter[] PROGMEM = "Analogue to Digital Converter"; 34 | const char ADCDAC[] PROGMEM = "ADC/DAC"; 35 | const char CapacitiveTouchSensor[] PROGMEM = "Capacitive Touch Sensor"; 36 | const char ClockGenerator[] PROGMEM = "Clock Generator"; 37 | const char CO2Sensor[] PROGMEM = "CO2 Sensor"; 38 | const char ColourSensor[] PROGMEM = "Colour Sensor"; 39 | const char CryptographicDevice[] PROGMEM = "Cryptographic Device"; 40 | const char CurrentVoltageSensor[] PROGMEM = "Current/Voltage Sensor"; 41 | const char CurrentPowerSensor[] PROGMEM = "Current/Power Sensor"; 42 | const char DigitaltoAnalogueConverter[] PROGMEM = "Digital to Analogue Converter"; 43 | const char DigitalCapacitor[] PROGMEM = "Digital Capacitor"; 44 | const char DigitalPotentiometer[] PROGMEM = "Digital Potentiometer"; 45 | const char DSPRadio[] PROGMEM = "DSP Radio"; 46 | const char FanController[] PROGMEM = "Fan Controller"; 47 | const char FerroelectricRAM[] PROGMEM = "Ferroelectric RAM"; 48 | const char FMTransmitter[] PROGMEM = "FM Transmitter"; 49 | const char FuelGauge[] PROGMEM = "Fuel Gauge"; 50 | const char GasSensor[] PROGMEM = "Gas Sensor"; 51 | const char GPIOExpander[] PROGMEM = "GPIO Expander"; 52 | const char GPSGNSSReceiver[] PROGMEM = "GPS GNSS Receiver"; 53 | const char Gyroscope[] PROGMEM = "Gyroscope"; 54 | const char HumidityTemperatureSensor[] PROGMEM = "Humidity/Temperature Sensor"; 55 | const char IRTemperatureSensor[] PROGMEM = "IR Temperature Sensor"; 56 | const char IRThermalCamera[] PROGMEM = "IR Thermal Camera"; 57 | const char LEDCharlieplexDriver[] PROGMEM = "LED Charlieplex Driver"; 58 | const char LEDMatrixDriver[] PROGMEM = "LED Matrix Driver"; 59 | const char LightColourSensor[] PROGMEM = "Light/Colour Sensor"; 60 | const char LightSensor[] PROGMEM = "Light Sensor"; 61 | const char LoadCellScale[] PROGMEM = "Load Cell Scale"; 62 | const char Magnetometer[] PROGMEM = "Magnetometer"; 63 | const char MotorDriver[] PROGMEM = "Motor Driver"; 64 | const char MP3Player[] PROGMEM = "MP3 Player"; 65 | const char Multiplexer[] PROGMEM = "Multiplexer"; 66 | const char NFCRFIDReader[] PROGMEM = "NFC/RFID Reader"; 67 | const char NunchuckController[] PROGMEM = "Nunchuck Controller"; 68 | const char OLEDDisplay[] PROGMEM = "OLED Display"; 69 | const char PowerManagementIC[] PROGMEM = "Power Management IC"; 70 | const char PressureSensor[] PROGMEM = "Pressure Sensor"; 71 | const char ProximitySensor[] PROGMEM = "Proximity Sensor"; 72 | const char ProximityLightSensor[] PROGMEM = "Proximity/Light Sensor"; 73 | const char PulseOximetrySensor[] PROGMEM = "Pulse & Oximetry Sensor"; 74 | const char PWMDriver[] PROGMEM = "PWM Driver"; 75 | const char RadioReceiver[] PROGMEM = "Radio Receiver"; 76 | const char RealTimeClock[] PROGMEM = "Real-Time Clock"; 77 | const char ResistiveTouchController[] PROGMEM = "Resistive Touch Controller"; 78 | const char RFIDTag[] PROGMEM = "RFID Tag"; 79 | const char TemperatureSensor[] PROGMEM = "Temperature Sensor"; 80 | const char TemperatureHumiditySensor[] PROGMEM = "Temperature/Humidity Sensor"; 81 | const char TemperaturePressureSensor[] PROGMEM = "Temperature/Pressure Sensor"; 82 | const char TemperaturePressureHumiditySensor[] PROGMEM = "Temperature/Pressure/Humidity Sensor"; 83 | const char TemperaturePressureHumidityGasSensor[] PROGMEM = "Temperature/Pressure/Humidity/Gas Sensor"; 84 | const char ThermocoupleAmplifier[] PROGMEM = "Thermocouple Amplifier"; 85 | const char TimeofFlightSensor[] PROGMEM = "Time of Flight Sensor"; 86 | const char TriadSpectroscopySensor[] PROGMEM = "Triad Spectroscopy Sensor"; 87 | const char UVLightSensor[] PROGMEM = "UV Light Sensor"; 88 | const char VOCSensor[] PROGMEM = "VOC Sensor"; 89 | const char WaterSensor[] PROGMEM = "Water Sensor"; 90 | 91 | // Devices 92 | const device_t Device[] PROGMEM = { 93 | // Device Category From To Reg ID 94 | { "ADC122C04", ThermocoupleAmplifier, 0x40, 0x4F, 0x00, 0x00 }, 95 | { "ADS1015", AnaloguetoDigitalConverter, 0x48, 0x4B, 0x00, 0x00 }, 96 | { "ADS1113", AnaloguetoDigitalConverter, 0x48, 0x4B, 0x00, 0x00 }, 97 | { "ADS1114", AnaloguetoDigitalConverter, 0x48, 0x4B, 0x00, 0x00 }, 98 | { "ADS1115", AnaloguetoDigitalConverter, 0x48, 0x4B, 0x00, 0x00 }, 99 | { "ADT7410", TemperatureSensor, 0x48, 0x4B, 0x0B, 0xCB }, 100 | { "ADXL343", Accelerometer, 0x53, 0x1D, 0x00, 0xE5 }, 101 | { "ADXL345", Accelerometer, 0x53, 0x1D, 0x00, 0xE5 }, 102 | { "AHT20", TemperatureHumiditySensor, 0x38, 0x38, 0x00, 0x00 }, 103 | { "AM2315", HumidityTemperatureSensor, 0x5C, 0x5C, 0x00, 0x00 }, 104 | { "AM2320", HumidityTemperatureSensor, 0x5C, 0x5C, 0x00, 0x00 }, 105 | { "AMG8831", IRThermalCamera, 0x68, 0x69, 0x00, 0x00 }, 106 | { "AMG8833", IRThermalCamera, 0x68, 0x69, 0x00, 0x00 }, 107 | { "APDS-9660", ProximityLightSensor, 0x39, 0x39, 0x92, 0xAB }, 108 | { "AS7265x", TriadSpectroscopySensor, 0x49, 0x49, 0x00, 0x00 }, 109 | { "AS7341", LightColourSensor, 0x39, 0x39, 0x92, 0x24 }, 110 | { "ATECC608", CryptographicDevice, 0x60, 0x60, 0x00, 0x00 }, 111 | { "BH1750", LightSensor, 0x5C, 0x23, 0x00, 0x00 }, 112 | { "BMA180", Accelerometer, 0x77, 0x77, 0x00, 0x03 }, 113 | { "BME280", TemperaturePressureHumiditySensor, 0x76, 0x77, 0xD0, 0x60 }, 114 | { "BME680", TemperaturePressureHumidityGasSensor, 0x76, 0x77, 0xD0, 0x61 }, 115 | { "BMI270", AccelerometerGyroscope, 0x68, 0x69, 0x00, 0x24 }, 116 | { "BMP085", TemperaturePressureSensor, 0x77, 0x77, 0x00, 0x00 }, 117 | { "BMP180", TemperaturePressureSensor, 0x77, 0x77, 0xD0, 0x55 }, 118 | { "BMP280", TemperaturePressureSensor, 0x76, 0x77, 0xD0, 0x58 }, 119 | { "BMP388", PressureSensor, 0x76, 0x77, 0x00, 0x50 }, 120 | { "BMP390", PressureSensor, 0x76, 0x77, 0x00, 0x60 }, 121 | { "BNO055", AccelerometerGyroscopeMagnetometer, 0x28, 0x29, 0x00, 0xA0 }, 122 | { "CAP1188", CapacitiveTouchSensor, 0x28, 0x2D, 0xFD, 0x50 }, 123 | { "CCS811", VOCSensor, 0x5A, 0x5B, 0x20, 0x81 }, 124 | { "Chirp!", WaterSensor, 0x20, 0x20, 0x00, 0x00 }, 125 | { "DHT12", HumidityTemperatureSensor, 0x5C, 0x5C, 0x00, 0x00 }, 126 | { "DPS310", PressureSensor, 0x76, 0x77, 0x0D, 0x10 }, 127 | { "DRV2605", MotorDriver, 0x5A, 0x5A, 0x00, 0x60 }, 128 | { "DS1307", RealTimeClock, 0x68, 0x68, 0x00, 0x00 }, 129 | { "DS1841", DigitalPotentiometer, 0x28, 0x2B, 0x03, 0x03 }, 130 | { "DS3231", RealTimeClock, 0x68, 0x68, 0x00, 0x00 }, 131 | { "DS3502", DigitalPotentiometer, 0x28, 0x2B, 0x00, 0x40 }, 132 | { "EMC2101", FanController, 0x4C, 0x4C, 0x00, 0x00 }, 133 | { "FT6x06", CapacitiveTouchSensor, 0x38, 0x38, 0x00, 0x00 }, 134 | { "FXAS21001", Gyroscope, 0x20, 0x21, 0x00, 0x00 }, 135 | { "FXOS8700", AccelerometerMagnetometer, 0x1C, 0x1F, 0x0D, 0xC7 }, 136 | { "H3LIS331DL", Accelerometer, 0x18, 0x19, 0x0F, 0x32 }, 137 | { "HDC1008", TemperatureHumiditySensor, 0x40, 0x43, 0x02, 0x10 }, 138 | { "HDC1008", HumidityTemperatureSensor, 0x40, 0x43, 0x00, 0x00 }, 139 | { "HMC5883", Magnetometer, 0x1E, 0x1E, 0x0A, 0x48 }, 140 | { "HT16K33", LEDMatrixDriver, 0x70, 0x77, 0x00, 0x00 }, 141 | { "HTS221", TemperatureHumiditySensor, 0x5F, 0x5F, 0x0F, 0xBC }, 142 | { "HTU21D-F", HumidityTemperatureSensor, 0x40, 0x40, 0x00, 0x00 }, 143 | { "ICM-20649", AccelerometerGyroscope, 0x68, 0x69, 0x00, 0xE1 }, 144 | { "ICM-20948", AccelerometerGyroscopeMagnetometer, 0x68, 0x69, 0x00, 0xEA }, 145 | { "INA219", CurrentVoltageSensor, 0x40, 0x4F, 0x00, 0x39 }, 146 | { "INA260", CurrentPowerSensor, 0x40, 0x4F, 0x00, 0x61 }, 147 | { "IS31FL3731", LEDCharlieplexDriver, 0x74, 0x77, 0x00, 0x00 }, 148 | { "ISL29125", ColourSensor, 0x44, 0x44, 0x00, 0x7D }, 149 | { "ISM330DHCX", AccelerometerGyroscope, 0x6A, 0x6B, 0x0F, 0x6B }, 150 | { "ITG3200", Gyroscope, 0x68, 0x69, 0x00, 0x00 }, 151 | { "KT0915", DSPRadio, 0x35, 0x35, 0x00, 0x00 }, 152 | { "L3GD20H", Gyroscope, 0x6A, 0x6B, 0x0F, 0xD7 }, 153 | { "LIS2MDL", Magnetometer, 0x1E, 0x1E, 0x4F, 0x40 }, 154 | { "LIS331", Accelerometer, 0x18, 0x19, 0x0F, 0x32 }, 155 | { "LIS3DH", Accelerometer, 0x18, 0x19, 0x0F, 0x33 }, 156 | { "LIS3MDL", Magnetometer, 0x1E, 0x1C, 0x00, 0x00 }, 157 | { "LPS22HB", PressureSensor, 0x5C, 0x5D, 0x0F, 0xB1 }, 158 | { "LPS25HB", PressureSensor, 0x5C, 0x5D, 0x0F, 0xBD }, 159 | { "LPS33HW", PressureSensor, 0x5C, 0x5D, 0x0F, 0xB1 }, 160 | { "LPS35HW", PressureSensor, 0x5C, 0x5D, 0x0F, 0xB1 }, 161 | { "LSM303AGR", AccelerometerMagnetometer, 0x1E, 0x1E, 0x4F, 0x40 }, 162 | { "LSM303AGR", AccelerometerMagnetometer, 0x19, 0x19, 0x0F, 0x33 }, 163 | { "LSM303D", AccelerometerMagnetometer, 0x1D, 0x1E, 0x0F, 0x49 }, 164 | { "LSM303DLHC", AccelerometerMagnetometer, 0x1E, 0x1E, 0x0C, 0x33 }, 165 | { "LSM303DLHC", AccelerometerMagnetometer, 0x19, 0x19, 0x20, 0x07 }, 166 | { "LSM6DS33", AccelerometerGyroscope, 0x6A, 0x6B, 0x0F, 0x69 }, 167 | { "LSM6DSOX", AccelerometerGyroscope, 0x6A, 0x6B, 0x0F, 0x6C }, 168 | { "LSM9DS0", AccelerometerGyroscopeMagnetometer, 0x1E, 0x1D, 0x0F, 0x49 }, 169 | { "LSM9DS0", AccelerometerGyroscopeMagnetometer, 0x6B, 0x6A, 0x0F, 0xD4 }, 170 | { "LSM9DS1", AccelerometerGyroscopeMagnetometer, 0x1E, 0x1C, 0x0F, 0x3D }, 171 | { "LSM9DS1", AccelerometerGyroscopeMagnetometer, 0x6B, 0x6A, 0x0F, 0x68 }, 172 | { "LTR-390", UVLightSensor, 0x53, 0x53, 0x06, 0xB2 }, 173 | { "MAG3110", Magnetometer, 0x0E, 0x0E, 0x00, 0x00 }, 174 | { "MAX17055", FuelGauge, 0x36, 0x36, 0x00, 0x00 }, 175 | { "MAX30101", PulseOximetrySensor, 0x57, 0x57, 0xFF, 0x15 }, 176 | { "MAX77650", PowerManagementIC, 0x48, 0x40, 0x00, 0x00 }, 177 | { "MB85RC", FerroelectricRAM, 0x50, 0x57, 0x00, 0x00 }, 178 | { "MB85RC256V", FerroelectricRAM, 0x50, 0x57, 0x00, 0x00 }, 179 | { "MCP23008", GPIOExpander, 0x20, 0x27, 0x00, 0x00 }, 180 | { "MCP23017", GPIOExpander, 0x20, 0x27, 0x00, 0x00 }, 181 | { "MCP4725A1", DigitaltoAnalogueConverter, 0x62, 0x63, 0x00, 0x00 }, 182 | { "MCP4725A2", DigitaltoAnalogueConverter, 0x64, 0x65, 0x00, 0x00 }, 183 | { "MCP4725A3", DigitaltoAnalogueConverter, 0x66, 0x67, 0x00, 0x00 }, 184 | { "MCP4728", DigitaltoAnalogueConverter, 0x60, 0x67, 0x00, 0x00 }, 185 | { "MCP9600", ThermocoupleAmplifier, 0x60, 0x67, 0x20, 0x40 }, 186 | { "MCP9808", TemperatureSensor, 0x18, 0x1F, 0x07, 0x04 }, 187 | { "MLX9061x", IRTemperatureSensor, 0x5A, 0x5A, 0x00, 0x00 }, 188 | { "MLX90640", IRThermalCamera, 0x33, 0x33, 0x00, 0x00 }, 189 | { "MMA7455L", Accelerometer, 0x1C, 0x1D, 0x0F, 0x3D }, 190 | { "MMA8451Q", Accelerometer, 0x1C, 0x1D, 0x0D, 0x1A }, 191 | { "MMA8452Q", Accelerometer, 0x1C, 0x1D, 0x0D, 0x2A }, 192 | { "MMA8453Q", Accelerometer, 0x1C, 0x1D, 0x0D, 0x3A }, 193 | { "MMA8652FC", Accelerometer, 0x1D, 0x1D, 0x0D, 0x4A }, 194 | { "MMA8653FC", Accelerometer, 0x1D, 0x1D, 0x0D, 0x5A }, 195 | { "MPL115A2", PressureSensor, 0x60, 0x60, 0x00, 0x00 }, 196 | { "MPL3115A2", PressureSensor, 0x60, 0x60, 0x0C, 0xC4 }, 197 | { "MPR121", CapacitiveTouchSensor, 0x5A, 0x5D, 0x5C, 0x10 }, 198 | { "MPRLS", PressureSensor, 0x18, 0x18, 0x00, 0x00 }, 199 | { "MPU-6000", AccelerometerGyroscope, 0x68, 0x69, 0x00, 0x00 }, 200 | { "MPU-6050", AccelerometerGyroscope, 0x68, 0x69, 0x00, 0x00 }, 201 | { "MPU-9250", AccelerometerGyroscopeMagnetometer, 0x68, 0x69, 0x00, 0x48 }, 202 | { "MS5607", PressureSensor, 0x76, 0x77, 0x00, 0x00 }, 203 | { "MS5611", PressureSensor, 0x76, 0x77, 0x00, 0x00 }, 204 | { "MSA301", Accelerometer, 0x26, 0x26, 0x01, 0x13 }, 205 | { "NAU7802", LoadCellScale, 0x2A, 0x2A, 0x00, 0x00 }, 206 | { "NCD2400M", DigitalCapacitor, 0x60, 0x60, 0x00, 0x00 }, 207 | { "NCD2400M1", DigitalCapacitor, 0x61, 0x61, 0x00, 0x00 }, 208 | { "NEO-M9N", GPSGNSSReceiver, 0x42, 0x42, 0x00, 0x00 }, 209 | { "Nintendo", NunchuckController, 0x52, 0x52, 0x00, 0x00 }, 210 | { "PA1010D", GPSGNSSReceiver, 0x10, 0x10, 0x00, 0x00 }, 211 | { "PCA9685", PWMDriver, 0x7F, 0x40, 0x00, 0x00 }, 212 | { "PCF8523", RealTimeClock, 0x68, 0x68, 0x00, 0x00 }, 213 | { "PCF8591", ADCDAC, 0x48, 0x4F, 0x00, 0x00 }, 214 | { "PMSA003I", AirQualitySensor, 0x12, 0x12, 0x00, 0x00 }, 215 | { "PN532", NFCRFIDReader, 0x48, 0x48, 0x00, 0x00 }, 216 | { "SCD30", CO2Sensor, 0x61, 0x61, 0x00, 0x00 }, 217 | { "SGP30", GasSensor, 0x58, 0x58, 0x00, 0x00 }, 218 | { "SGP40", GasSensor, 0x59, 0x59, 0x00, 0x00 }, 219 | { "SH1106", OLEDDisplay, 0x3C, 0x3D, 0x00, 0x00 }, 220 | { "SHT30", HumidityTemperatureSensor, 0x44, 0x45, 0x00, 0x00 }, 221 | { "SHT31", HumidityTemperatureSensor, 0x44, 0x45, 0x00, 0x00 }, 222 | { "SHT35", HumidityTemperatureSensor, 0x44, 0x45, 0x00, 0x00 }, 223 | { "SHTC3", TemperatureHumiditySensor, 0x70, 0x70, 0x00, 0x00 }, 224 | { "SSD1305", OLEDDisplay, 0x3C, 0x3D, 0x00, 0x00 }, 225 | { "SSD1306", OLEDDisplay, 0x3C, 0x3D, 0x00, 0x00 }, 226 | { "SSD1327", OLEDDisplay, 0x7A, 0x78, 0x00, 0x00 }, 227 | { "ST25DV16K", RFIDTag, 0x57, 0x53, 0x00, 0x00 }, 228 | { "ST25DV16K", RFIDTag, 0x2D, 0x2D, 0x00, 0x00 }, 229 | { "STMPE610", ResistiveTouchController, 0x44, 0x41, 0x00, 0x08 }, 230 | { "STMPE811", ResistiveTouchController, 0x44, 0x41, 0x00, 0x08 }, 231 | { "Si1145", LightSensor, 0x60, 0x60, 0x00, 0x45 }, 232 | { "Si1146", LightSensor, 0x60, 0x60, 0x00, 0x46 }, 233 | { "Si1147", LightSensor, 0x60, 0x60, 0x00, 0x47 }, 234 | { "Si4712", FMTransmitter, 0x63, 0x11, 0x00, 0x00 }, 235 | { "Si4713", FMTransmitter, 0x63, 0x11, 0x00, 0x00 }, 236 | { "Si5351A", ClockGenerator, 0x60, 0x61, 0x00, 0x00 }, 237 | { "Si7021", HumidityTemperatureSensor, 0x40, 0x40, 0x00, 0x00 }, 238 | { "TC74A0", TemperatureSensor, 0x48, 0x48, 0x00, 0x00 }, 239 | { "TCA9548A", Multiplexer, 0x70, 0x77, 0x00, 0x00 }, 240 | { "TCS34721", ColourSensor, 0x39, 0x39, 0x92, 0x44 }, 241 | { "TCS34723", ColourSensor, 0x39, 0x39, 0x92, 0x4D }, 242 | { "TCS34725", ColourSensor, 0x29, 0x29, 0x92, 0x44 }, 243 | { "TCS34727", ColourSensor, 0x29, 0x29, 0x92, 0x4D }, 244 | { "TEA5767", RadioReceiver, 0x60, 0x60, 0x00, 0x00 }, 245 | { "TLV493D", Magnetometer, 0x5E, 0x5E, 0x00, 0x00 }, 246 | { "TMP006", IRTemperatureSensor, 0x40, 0x47, 0xFE, 0x54 }, 247 | { "TMP007", IRTemperatureSensor, 0x40, 0x47, 0xFE, 0x54 }, 248 | { "TMP102", TemperatureSensor, 0x48, 0x4B, 0x00, 0x00 }, 249 | { "TMP117", TemperatureSensor, 0x48, 0x49, 0x00, 0x00 }, 250 | { "TPA2016", Amplifier, 0x58, 0x58, 0x00, 0x00 }, 251 | { "TSL2561", LightSensor, 0x49, 0x49, 0x00, 0x00 }, 252 | { "TSL2561", LightSensor, 0x39, 0x29, 0x00, 0x00 }, 253 | { "TSL2591", LightSensor, 0x28, 0x29, 0x12, 0x50 }, 254 | { "VCNL4000", ProximitySensor, 0x13, 0x13, 0x81, 0x11 }, 255 | { "VCNL4010", ProximitySensor, 0x13, 0x13, 0x81, 0x21 }, 256 | { "VCNL4020", ProximitySensor, 0x13, 0x13, 0x81, 0x21 }, 257 | { "VCNL4040", ProximityLightSensor, 0x60, 0x60, 0x0C, 0x86 }, 258 | { "VEML6070", UVLightSensor, 0x38, 0x39, 0x00, 0x00 }, 259 | { "VEML6075", UVLightSensor, 0x10, 0x10, 0x0C, 0x26 }, 260 | { "VEML7700", LightSensor, 0x10, 0x10, 0x00, 0x00 }, 261 | { "VL53L0X", TimeofFlightSensor, 0x29, 0x29, 0xC0, 0xEE }, 262 | { "VL53L1X", TimeofFlightSensor, 0x29, 0x29, 0xC0, 0xEE }, 263 | { "VL53L3CX", TimeofFlightSensor, 0x29, 0x29, 0x00, 0x00 }, 264 | { "VL6180X", TimeofFlightSensor, 0x29, 0x29, 0x00, 0xB4 }, 265 | { "WT2003S", MP3Player, 0x37, 0x37, 0x00, 0x00 }, 266 | { "XA1110", GPSGNSSReceiver, 0x10, 0x10, 0x00, 0x00 }, 267 | { "ZMOD4450", GasSensor, 0x32, 0x32, 0x00, 0x00 }, 268 | { "ZOE-M8Q", GPSGNSSReceiver, 0x42, 0x42, 0x00, 0x00 }, 269 | }; 270 | 271 | const device_t Unknown PROGMEM = {"?", UnknownDevice, 0, 0, 0, 0}; 272 | const int Devices = sizeof Device / sizeof *Device; 273 | 274 | boolean match (uint8_t addr, uint8_t from, uint8_t to) { 275 | if (from > to) return (addr == from) || (addr == to); 276 | else return (addr >= from) && (addr <= to); 277 | } 278 | 279 | boolean whoami (uint8_t addr, uint8_t reg, uint8_t value) { 280 | if (reg == 0x00 && value == 0x00) return false; 281 | Wire.beginTransmission(addr); 282 | Wire.write(reg); 283 | if (Wire.endTransmission(false) != 0) return false; 284 | Wire.requestFrom(addr, 1); 285 | return value == Wire.read(); 286 | } 287 | 288 | uint8_t who (uint8_t addr, uint8_t reg) { 289 | Wire.beginTransmission(addr); 290 | Wire.write(reg); 291 | Wire.endTransmission(false); 292 | Wire.requestFrom(addr, 1); 293 | return Wire.read(); 294 | } 295 | 296 | const device_t *findtwin (int i) { 297 | const device_t *me = &Device[i]; 298 | const device_t *other; 299 | for (int j = i-1; j <= i+1; j=j+2) { 300 | if (j >= 0 && j < Devices) { 301 | other = &Device[j]; 302 | if (strcmp(me->device, other->device) == 0) return other; 303 | } 304 | } 305 | return NULL; 306 | } 307 | 308 | boolean twindevice (int i) { 309 | boolean ok; 310 | // Check whether previous or next one in list is a twin 311 | const device_t *other = findtwin(i); 312 | if (other) { 313 | // Check its whoami 314 | uint8_t from = other->from; 315 | uint8_t to = other->to; 316 | uint8_t test = other->test; 317 | uint8_t value = other->value; 318 | if (from > to) { 319 | ok = whoami(from, test, value) || whoami(to, test, value); 320 | } else { 321 | ok = false; 322 | for (uint8_t addr = from; addr <= to; addr++) { 323 | ok = whoami(addr, test, value); 324 | if (ok) break; 325 | } 326 | } 327 | if (ok) return true; 328 | } 329 | return false; 330 | } 331 | 332 | void list (uint8_t addr, const device_t *me) { 333 | Serial.print("0x"); Serial.print(addr/16, HEX); 334 | Serial.print(addr&0xF, HEX); Serial.print(' '); 335 | #if defined(AVR_DATA) 336 | Serial.print((__FlashStringHelper *)pgm_read_word(&me->category)); 337 | Serial.print(": "); Serial.print((char *)(pgm_read_word(&me->device))); 338 | #else 339 | Serial.print(me->category); 340 | Serial.print(": "); Serial.print(me->device); 341 | #endif 342 | Serial.println(); 343 | } 344 | 345 | void lookup (uint8_t addr) { 346 | // Check for devices with a device ID match 347 | boolean listed = false; 348 | for (int pass=1; pass<4; pass++) { 349 | for (int i=0; ifrom); 353 | uint8_t to = pgm_read_byte(&me->to); 354 | uint8_t test = pgm_read_byte(&me->test); 355 | uint8_t value = pgm_read_byte(&me->value); 356 | #else 357 | uint8_t from = me->from; 358 | uint8_t to = me->to; 359 | uint8_t test = me->test; 360 | uint8_t value = me->value; 361 | #endif 362 | if (match(addr, from, to)) { 363 | boolean ok; 364 | if (pass == 1) ok = twindevice(i) && whoami(addr, test, value); 365 | else if (pass == 2) ok = whoami(addr, test, value) && !findtwin(i); 366 | else if (pass == 3) ok = test == 0x00 && value == 0x00; 367 | if (ok) { 368 | list(addr, me); 369 | listed = true; 370 | } 371 | } 372 | } 373 | if (listed) return; 374 | } 375 | list(addr, &Unknown); 376 | } 377 | 378 | void scan () { 379 | for (uint8_t addr=8; addr<128; addr++) { 380 | int ok = true; 381 | Wire.beginTransmission(addr); 382 | if (Wire.endTransmission(true) == 0) lookup(addr); 383 | } 384 | } 385 | 386 | void setup () { 387 | Wire.begin(); 388 | Serial.begin(9600); 389 | delay(3000); 390 | } 391 | 392 | void loop () { 393 | Serial.println(); 394 | Serial.println("I2C Detective"); 395 | scan(); 396 | for(;;); 397 | } 398 | -------------------------------------------------------------------------------- /I2CDetectiveClue.ino: -------------------------------------------------------------------------------- 1 | /* I2C Detective - Clue version - see http://www.technoblogy.com/show?3FFW 2 | 3 | David Johnson-Davies - www.technoblogy.com - 19th January 2021 4 | 5 | CC BY 4.0 6 | Licensed under a Creative Commons Attribution 4.0 International license: 7 | http://creativecommons.org/licenses/by/4.0/ 8 | */ 9 | 10 | // Uncomment this for AVR platforms like the Arduino Uno 11 | //#define AVR_DATA 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | Adafruit_ST7789 tft = Adafruit_ST7789(&SPI1, 31, 32, 33); 19 | 20 | typedef struct { 21 | const char *device; 22 | const char *category; 23 | uint8_t from; 24 | uint8_t to; 25 | uint8_t test; 26 | uint8_t value; 27 | } device_t; 28 | 29 | const char UnknownDevice[] PROGMEM = "Unknown Device"; 30 | 31 | // Categories 32 | const char Accelerometer[] PROGMEM = "Accelerometer"; 33 | const char AccelerometerGyroscope[] PROGMEM = "Accelerometer/Gyroscope"; 34 | const char AccelerometerGyroscopeMagnetometer[] PROGMEM = "Accelerometer/Gyroscope/Magnetometer"; 35 | const char AccelerometerMagnetometer[] PROGMEM = "Accelerometer/Magnetometer"; 36 | const char AirQualitySensor[] PROGMEM = "Air Quality Sensor"; 37 | const char Amplifier[] PROGMEM = "Amplifier"; 38 | const char AnaloguetoDigitalConverter[] PROGMEM = "Analogue to Digital Converter"; 39 | const char ADCDAC[] PROGMEM = "ADC/DAC"; 40 | const char CapacitiveTouchSensor[] PROGMEM = "Capacitive Touch Sensor"; 41 | const char ClockGenerator[] PROGMEM = "Clock Generator"; 42 | const char CO2Sensor[] PROGMEM = "CO2 Sensor"; 43 | const char ColourSensor[] PROGMEM = "Colour Sensor"; 44 | const char CryptographicDevice[] PROGMEM = "Cryptographic Device"; 45 | const char CurrentVoltageSensor[] PROGMEM = "Current/Voltage Sensor"; 46 | const char CurrentPowerSensor[] PROGMEM = "Current/Power Sensor"; 47 | const char DigitaltoAnalogueConverter[] PROGMEM = "Digital to Analogue Converter"; 48 | const char DigitalCapacitor[] PROGMEM = "Digital Capacitor"; 49 | const char DigitalPotentiometer[] PROGMEM = "Digital Potentiometer"; 50 | const char DSPRadio[] PROGMEM = "DSP Radio"; 51 | const char FanController[] PROGMEM = "Fan Controller"; 52 | const char FerroelectricRAM[] PROGMEM = "Ferroelectric RAM"; 53 | const char FMTransmitter[] PROGMEM = "FM Transmitter"; 54 | const char FuelGauge[] PROGMEM = "Fuel Gauge"; 55 | const char GasSensor[] PROGMEM = "Gas Sensor"; 56 | const char GPIOExpander[] PROGMEM = "GPIO Expander"; 57 | const char GPSGNSSReceiver[] PROGMEM = "GPS GNSS Receiver"; 58 | const char Gyroscope[] PROGMEM = "Gyroscope"; 59 | const char HumidityTemperatureSensor[] PROGMEM = "Humidity/Temperature Sensor"; 60 | const char IRTemperatureSensor[] PROGMEM = "IR Temperature Sensor"; 61 | const char IRThermalCamera[] PROGMEM = "IR Thermal Camera"; 62 | const char LEDCharlieplexDriver[] PROGMEM = "LED Charlieplex Driver"; 63 | const char LEDMatrixDriver[] PROGMEM = "LED Matrix Driver"; 64 | const char LightColourSensor[] PROGMEM = "Light/Colour Sensor"; 65 | const char LightSensor[] PROGMEM = "Light Sensor"; 66 | const char LoadCellScale[] PROGMEM = "Load Cell Scale"; 67 | const char Magnetometer[] PROGMEM = "Magnetometer"; 68 | const char MotorDriver[] PROGMEM = "Motor Driver"; 69 | const char MP3Player[] PROGMEM = "MP3 Player"; 70 | const char Multiplexer[] PROGMEM = "Multiplexer"; 71 | const char NFCRFIDReader[] PROGMEM = "NFC/RFID Reader"; 72 | const char NunchuckController[] PROGMEM = "Nunchuck Controller"; 73 | const char OLEDDisplay[] PROGMEM = "OLED Display"; 74 | const char PowerManagementIC[] PROGMEM = "Power Management IC"; 75 | const char PressureSensor[] PROGMEM = "Pressure Sensor"; 76 | const char ProximitySensor[] PROGMEM = "Proximity Sensor"; 77 | const char ProximityLightSensor[] PROGMEM = "Proximity/Light Sensor"; 78 | const char PulseOximetrySensor[] PROGMEM = "Pulse & Oximetry Sensor"; 79 | const char PWMDriver[] PROGMEM = "PWM Driver"; 80 | const char RadioReceiver[] PROGMEM = "Radio Receiver"; 81 | const char RealTimeClock[] PROGMEM = "Real-Time Clock"; 82 | const char ResistiveTouchController[] PROGMEM = "Resistive Touch Controller"; 83 | const char RFIDTag[] PROGMEM = "RFID Tag"; 84 | const char TemperatureSensor[] PROGMEM = "Temperature Sensor"; 85 | const char TemperatureHumiditySensor[] PROGMEM = "Temperature/Humidity Sensor"; 86 | const char TemperaturePressureSensor[] PROGMEM = "Temperature/Pressure Sensor"; 87 | const char TemperaturePressureHumiditySensor[] PROGMEM = "Temperature/Pressure/Humidity Sensor"; 88 | const char TemperaturePressureHumidityGasSensor[] PROGMEM = "Temperature/Pressure/Humidity/Gas Sensor"; 89 | const char ThermocoupleAmplifier[] PROGMEM = "Thermocouple Amplifier"; 90 | const char TimeofFlightSensor[] PROGMEM = "Time of Flight Sensor"; 91 | const char TriadSpectroscopySensor[] PROGMEM = "Triad Spectroscopy Sensor"; 92 | const char UVLightSensor[] PROGMEM = "UV Light Sensor"; 93 | const char VOCSensor[] PROGMEM = "VOC Sensor"; 94 | const char WaterSensor[] PROGMEM = "Water Sensor"; 95 | 96 | // Devices 97 | const device_t Device[] PROGMEM = { 98 | // Device Category From To Reg ID 99 | { "ADC122C04", ThermocoupleAmplifier, 0x40, 0x4F, 0x00, 0x00 }, 100 | { "ADS1015", AnaloguetoDigitalConverter, 0x48, 0x4B, 0x00, 0x00 }, 101 | { "ADS1113", AnaloguetoDigitalConverter, 0x48, 0x4B, 0x00, 0x00 }, 102 | { "ADS1114", AnaloguetoDigitalConverter, 0x48, 0x4B, 0x00, 0x00 }, 103 | { "ADS1115", AnaloguetoDigitalConverter, 0x48, 0x4B, 0x00, 0x00 }, 104 | { "ADT7410", TemperatureSensor, 0x48, 0x4B, 0x0B, 0xCB }, 105 | { "ADXL343", Accelerometer, 0x53, 0x1D, 0x00, 0xE5 }, 106 | { "ADXL345", Accelerometer, 0x53, 0x1D, 0x00, 0xE5 }, 107 | { "AHT20", TemperatureHumiditySensor, 0x38, 0x38, 0x00, 0x00 }, 108 | { "AM2315", HumidityTemperatureSensor, 0x5C, 0x5C, 0x00, 0x00 }, 109 | { "AM2320", HumidityTemperatureSensor, 0x5C, 0x5C, 0x00, 0x00 }, 110 | { "AMG8831", IRThermalCamera, 0x68, 0x69, 0x00, 0x00 }, 111 | { "AMG8833", IRThermalCamera, 0x68, 0x69, 0x00, 0x00 }, 112 | { "APDS-9660", ProximityLightSensor, 0x39, 0x39, 0x92, 0xAB }, 113 | { "AS7265x", TriadSpectroscopySensor, 0x49, 0x49, 0x00, 0x00 }, 114 | { "AS7341", LightColourSensor, 0x39, 0x39, 0x92, 0x24 }, 115 | { "ATECC608", CryptographicDevice, 0x60, 0x60, 0x00, 0x00 }, 116 | { "BH1750", LightSensor, 0x5C, 0x23, 0x00, 0x00 }, 117 | { "BMA180", Accelerometer, 0x77, 0x77, 0x00, 0x03 }, 118 | { "BME280", TemperaturePressureHumiditySensor, 0x76, 0x77, 0xD0, 0x60 }, 119 | { "BME680", TemperaturePressureHumidityGasSensor, 0x76, 0x77, 0xD0, 0x61 }, 120 | { "BMI270", AccelerometerGyroscope, 0x68, 0x69, 0x00, 0x24 }, 121 | { "BMP085", TemperaturePressureSensor, 0x77, 0x77, 0x00, 0x00 }, 122 | { "BMP180", TemperaturePressureSensor, 0x77, 0x77, 0xD0, 0x55 }, 123 | { "BMP280", TemperaturePressureSensor, 0x76, 0x77, 0xD0, 0x58 }, 124 | { "BMP388", PressureSensor, 0x76, 0x77, 0x00, 0x50 }, 125 | { "BMP390", PressureSensor, 0x76, 0x77, 0x00, 0x60 }, 126 | { "BNO055", AccelerometerGyroscopeMagnetometer, 0x28, 0x29, 0x00, 0xA0 }, 127 | { "CAP1188", CapacitiveTouchSensor, 0x28, 0x2D, 0xFD, 0x50 }, 128 | { "CCS811", VOCSensor, 0x5A, 0x5B, 0x20, 0x81 }, 129 | { "Chirp!", WaterSensor, 0x20, 0x20, 0x00, 0x00 }, 130 | { "DHT12", HumidityTemperatureSensor, 0x5C, 0x5C, 0x00, 0x00 }, 131 | { "DPS310", PressureSensor, 0x76, 0x77, 0x0D, 0x10 }, 132 | { "DRV2605", MotorDriver, 0x5A, 0x5A, 0x00, 0x60 }, 133 | { "DS1307", RealTimeClock, 0x68, 0x68, 0x00, 0x00 }, 134 | { "DS1841", DigitalPotentiometer, 0x28, 0x2B, 0x03, 0x03 }, 135 | { "DS3231", RealTimeClock, 0x68, 0x68, 0x00, 0x00 }, 136 | { "DS3502", DigitalPotentiometer, 0x28, 0x2B, 0x00, 0x40 }, 137 | { "EMC2101", FanController, 0x4C, 0x4C, 0x00, 0x00 }, 138 | { "FT6x06", CapacitiveTouchSensor, 0x38, 0x38, 0x00, 0x00 }, 139 | { "FXAS21001", Gyroscope, 0x20, 0x21, 0x00, 0x00 }, 140 | { "FXOS8700", AccelerometerMagnetometer, 0x1C, 0x1F, 0x0D, 0xC7 }, 141 | { "H3LIS331DL", Accelerometer, 0x18, 0x19, 0x0F, 0x32 }, 142 | { "HDC1008", TemperatureHumiditySensor, 0x40, 0x43, 0x02, 0x10 }, 143 | { "HDC1008", HumidityTemperatureSensor, 0x40, 0x43, 0x00, 0x00 }, 144 | { "HMC5883", Magnetometer, 0x1E, 0x1E, 0x0A, 0x48 }, 145 | { "HT16K33", LEDMatrixDriver, 0x70, 0x77, 0x00, 0x00 }, 146 | { "HTS221", TemperatureHumiditySensor, 0x5F, 0x5F, 0x0F, 0xBC }, 147 | { "HTU21D-F", HumidityTemperatureSensor, 0x40, 0x40, 0x00, 0x00 }, 148 | { "ICM-20649", AccelerometerGyroscope, 0x68, 0x69, 0x00, 0xE1 }, 149 | { "ICM-20948", AccelerometerGyroscopeMagnetometer, 0x68, 0x69, 0x00, 0xEA }, 150 | { "INA219", CurrentVoltageSensor, 0x40, 0x4F, 0x00, 0x39 }, 151 | { "INA260", CurrentPowerSensor, 0x40, 0x4F, 0x00, 0x61 }, 152 | { "IS31FL3731", LEDCharlieplexDriver, 0x74, 0x77, 0x00, 0x00 }, 153 | { "ISL29125", ColourSensor, 0x44, 0x44, 0x00, 0x7D }, 154 | { "ISM330DHCX", AccelerometerGyroscope, 0x6A, 0x6B, 0x0F, 0x6B }, 155 | { "ITG3200", Gyroscope, 0x68, 0x69, 0x00, 0x00 }, 156 | { "KT0915", DSPRadio, 0x35, 0x35, 0x00, 0x00 }, 157 | { "L3GD20H", Gyroscope, 0x6A, 0x6B, 0x0F, 0xD7 }, 158 | { "LIS2MDL", Magnetometer, 0x1E, 0x1E, 0x4F, 0x40 }, 159 | { "LIS331", Accelerometer, 0x18, 0x19, 0x0F, 0x32 }, 160 | { "LIS3DH", Accelerometer, 0x18, 0x19, 0x0F, 0x33 }, 161 | { "LIS3MDL", Magnetometer, 0x1E, 0x1C, 0x00, 0x00 }, 162 | { "LPS22HB", PressureSensor, 0x5C, 0x5D, 0x0F, 0xB1 }, 163 | { "LPS25HB", PressureSensor, 0x5C, 0x5D, 0x0F, 0xBD }, 164 | { "LPS33HW", PressureSensor, 0x5C, 0x5D, 0x0F, 0xB1 }, 165 | { "LPS35HW", PressureSensor, 0x5C, 0x5D, 0x0F, 0xB1 }, 166 | { "LSM303AGR", AccelerometerMagnetometer, 0x1E, 0x1E, 0x4F, 0x40 }, 167 | { "LSM303AGR", AccelerometerMagnetometer, 0x19, 0x19, 0x0F, 0x33 }, 168 | { "LSM303D", AccelerometerMagnetometer, 0x1D, 0x1E, 0x0F, 0x49 }, 169 | { "LSM303DLHC", AccelerometerMagnetometer, 0x1E, 0x1E, 0x0C, 0x33 }, 170 | { "LSM303DLHC", AccelerometerMagnetometer, 0x19, 0x19, 0x20, 0x07 }, 171 | { "LSM6DS33", AccelerometerGyroscope, 0x6A, 0x6B, 0x0F, 0x69 }, 172 | { "LSM6DSOX", AccelerometerGyroscope, 0x6A, 0x6B, 0x0F, 0x6C }, 173 | { "LSM9DS0", AccelerometerGyroscopeMagnetometer, 0x1E, 0x1D, 0x0F, 0x49 }, 174 | { "LSM9DS0", AccelerometerGyroscopeMagnetometer, 0x6B, 0x6A, 0x0F, 0xD4 }, 175 | { "LSM9DS1", AccelerometerGyroscopeMagnetometer, 0x1E, 0x1C, 0x0F, 0x3D }, 176 | { "LSM9DS1", AccelerometerGyroscopeMagnetometer, 0x6B, 0x6A, 0x0F, 0x68 }, 177 | { "LTR-390", UVLightSensor, 0x53, 0x53, 0x06, 0xB2 }, 178 | { "MAG3110", Magnetometer, 0x0E, 0x0E, 0x00, 0x00 }, 179 | { "MAX17055", FuelGauge, 0x36, 0x36, 0x00, 0x00 }, 180 | { "MAX30101", PulseOximetrySensor, 0x57, 0x57, 0xFF, 0x15 }, 181 | { "MAX77650", PowerManagementIC, 0x48, 0x40, 0x00, 0x00 }, 182 | { "MB85RC", FerroelectricRAM, 0x50, 0x57, 0x00, 0x00 }, 183 | { "MB85RC256V", FerroelectricRAM, 0x50, 0x57, 0x00, 0x00 }, 184 | { "MCP23008", GPIOExpander, 0x20, 0x27, 0x00, 0x00 }, 185 | { "MCP23017", GPIOExpander, 0x20, 0x27, 0x00, 0x00 }, 186 | { "MCP4725A1", DigitaltoAnalogueConverter, 0x62, 0x63, 0x00, 0x00 }, 187 | { "MCP4725A2", DigitaltoAnalogueConverter, 0x64, 0x65, 0x00, 0x00 }, 188 | { "MCP4725A3", DigitaltoAnalogueConverter, 0x66, 0x67, 0x00, 0x00 }, 189 | { "MCP4728", DigitaltoAnalogueConverter, 0x60, 0x67, 0x00, 0x00 }, 190 | { "MCP9600", ThermocoupleAmplifier, 0x60, 0x67, 0x20, 0x40 }, 191 | { "MCP9808", TemperatureSensor, 0x18, 0x1F, 0x07, 0x04 }, 192 | { "MLX9061x", IRTemperatureSensor, 0x5A, 0x5A, 0x00, 0x00 }, 193 | { "MLX90640", IRThermalCamera, 0x33, 0x33, 0x00, 0x00 }, 194 | { "MMA7455L", Accelerometer, 0x1C, 0x1D, 0x0F, 0x3D }, 195 | { "MMA8451Q", Accelerometer, 0x1C, 0x1D, 0x0D, 0x1A }, 196 | { "MMA8452Q", Accelerometer, 0x1C, 0x1D, 0x0D, 0x2A }, 197 | { "MMA8453Q", Accelerometer, 0x1C, 0x1D, 0x0D, 0x3A }, 198 | { "MMA8652FC", Accelerometer, 0x1D, 0x1D, 0x0D, 0x4A }, 199 | { "MMA8653FC", Accelerometer, 0x1D, 0x1D, 0x0D, 0x5A }, 200 | { "MPL115A2", PressureSensor, 0x60, 0x60, 0x00, 0x00 }, 201 | { "MPL3115A2", PressureSensor, 0x60, 0x60, 0x0C, 0xC4 }, 202 | { "MPR121", CapacitiveTouchSensor, 0x5A, 0x5D, 0x5C, 0x10 }, 203 | { "MPRLS", PressureSensor, 0x18, 0x18, 0x00, 0x00 }, 204 | { "MPU-6000", AccelerometerGyroscope, 0x68, 0x69, 0x00, 0x00 }, 205 | { "MPU-6050", AccelerometerGyroscope, 0x68, 0x69, 0x00, 0x00 }, 206 | { "MPU-9250", AccelerometerGyroscopeMagnetometer, 0x68, 0x69, 0x00, 0x48 }, 207 | { "MS5607", PressureSensor, 0x76, 0x77, 0x00, 0x00 }, 208 | { "MS5611", PressureSensor, 0x76, 0x77, 0x00, 0x00 }, 209 | { "MSA301", Accelerometer, 0x26, 0x26, 0x01, 0x13 }, 210 | { "NAU7802", LoadCellScale, 0x2A, 0x2A, 0x00, 0x00 }, 211 | { "NCD2400M", DigitalCapacitor, 0x60, 0x60, 0x00, 0x00 }, 212 | { "NCD2400M1", DigitalCapacitor, 0x61, 0x61, 0x00, 0x00 }, 213 | { "NEO-M9N", GPSGNSSReceiver, 0x42, 0x42, 0x00, 0x00 }, 214 | { "Nintendo", NunchuckController, 0x52, 0x52, 0x00, 0x00 }, 215 | { "PA1010D", GPSGNSSReceiver, 0x10, 0x10, 0x00, 0x00 }, 216 | { "PCA9685", PWMDriver, 0x7F, 0x40, 0x00, 0x00 }, 217 | { "PCF8523", RealTimeClock, 0x68, 0x68, 0x00, 0x00 }, 218 | { "PCF8591", ADCDAC, 0x48, 0x4F, 0x00, 0x00 }, 219 | { "PMSA003I", AirQualitySensor, 0x12, 0x12, 0x00, 0x00 }, 220 | { "PN532", NFCRFIDReader, 0x48, 0x48, 0x00, 0x00 }, 221 | { "SCD30", CO2Sensor, 0x61, 0x61, 0x00, 0x00 }, 222 | { "SGP30", GasSensor, 0x58, 0x58, 0x00, 0x00 }, 223 | { "SGP40", GasSensor, 0x59, 0x59, 0x00, 0x00 }, 224 | { "SH1106", OLEDDisplay, 0x3C, 0x3D, 0x00, 0x00 }, 225 | { "SHT30", HumidityTemperatureSensor, 0x44, 0x45, 0x00, 0x00 }, 226 | { "SHT31", HumidityTemperatureSensor, 0x44, 0x45, 0x00, 0x00 }, 227 | { "SHT35", HumidityTemperatureSensor, 0x44, 0x45, 0x00, 0x00 }, 228 | { "SHTC3", TemperatureHumiditySensor, 0x70, 0x70, 0x00, 0x00 }, 229 | { "SSD1305", OLEDDisplay, 0x3C, 0x3D, 0x00, 0x00 }, 230 | { "SSD1306", OLEDDisplay, 0x3C, 0x3D, 0x00, 0x00 }, 231 | { "SSD1327", OLEDDisplay, 0x7A, 0x78, 0x00, 0x00 }, 232 | { "ST25DV16K", RFIDTag, 0x57, 0x53, 0x00, 0x00 }, 233 | { "ST25DV16K", RFIDTag, 0x2D, 0x2D, 0x00, 0x00 }, 234 | { "STMPE610", ResistiveTouchController, 0x44, 0x41, 0x00, 0x08 }, 235 | { "STMPE811", ResistiveTouchController, 0x44, 0x41, 0x00, 0x08 }, 236 | { "Si1145", LightSensor, 0x60, 0x60, 0x00, 0x45 }, 237 | { "Si1146", LightSensor, 0x60, 0x60, 0x00, 0x46 }, 238 | { "Si1147", LightSensor, 0x60, 0x60, 0x00, 0x47 }, 239 | { "Si4712", FMTransmitter, 0x63, 0x11, 0x00, 0x00 }, 240 | { "Si4713", FMTransmitter, 0x63, 0x11, 0x00, 0x00 }, 241 | { "Si5351A", ClockGenerator, 0x60, 0x61, 0x00, 0x00 }, 242 | { "Si7021", HumidityTemperatureSensor, 0x40, 0x40, 0x00, 0x00 }, 243 | { "TC74A0", TemperatureSensor, 0x48, 0x48, 0x00, 0x00 }, 244 | { "TCA9548A", Multiplexer, 0x70, 0x77, 0x00, 0x00 }, 245 | { "TCS34721", ColourSensor, 0x39, 0x39, 0x92, 0x44 }, 246 | { "TCS34723", ColourSensor, 0x39, 0x39, 0x92, 0x4D }, 247 | { "TCS34725", ColourSensor, 0x29, 0x29, 0x92, 0x44 }, 248 | { "TCS34727", ColourSensor, 0x29, 0x29, 0x92, 0x4D }, 249 | { "TEA5767", RadioReceiver, 0x60, 0x60, 0x00, 0x00 }, 250 | { "TLV493D", Magnetometer, 0x5E, 0x5E, 0x00, 0x00 }, 251 | { "TMP006", IRTemperatureSensor, 0x40, 0x47, 0xFE, 0x54 }, 252 | { "TMP007", IRTemperatureSensor, 0x40, 0x47, 0xFE, 0x54 }, 253 | { "TMP102", TemperatureSensor, 0x48, 0x4B, 0x00, 0x00 }, 254 | { "TMP117", TemperatureSensor, 0x48, 0x49, 0x00, 0x00 }, 255 | { "TPA2016", Amplifier, 0x58, 0x58, 0x00, 0x00 }, 256 | { "TSL2561", LightSensor, 0x49, 0x49, 0x00, 0x00 }, 257 | { "TSL2561", LightSensor, 0x39, 0x29, 0x00, 0x00 }, 258 | { "TSL2591", LightSensor, 0x28, 0x29, 0x12, 0x50 }, 259 | { "VCNL4000", ProximitySensor, 0x13, 0x13, 0x81, 0x11 }, 260 | { "VCNL4010", ProximitySensor, 0x13, 0x13, 0x81, 0x21 }, 261 | { "VCNL4020", ProximitySensor, 0x13, 0x13, 0x81, 0x21 }, 262 | { "VCNL4040", ProximityLightSensor, 0x60, 0x60, 0x0C, 0x86 }, 263 | { "VEML6070", UVLightSensor, 0x38, 0x39, 0x00, 0x00 }, 264 | { "VEML6075", UVLightSensor, 0x10, 0x10, 0x0C, 0x26 }, 265 | { "VEML7700", LightSensor, 0x10, 0x10, 0x00, 0x00 }, 266 | { "VL53L0X", TimeofFlightSensor, 0x29, 0x29, 0xC0, 0xEE }, 267 | { "VL53L1X", TimeofFlightSensor, 0x29, 0x29, 0xC0, 0xEE }, 268 | { "VL53L3CX", TimeofFlightSensor, 0x29, 0x29, 0x00, 0x00 }, 269 | { "VL6180X", TimeofFlightSensor, 0x29, 0x29, 0x00, 0xB4 }, 270 | { "WT2003S", MP3Player, 0x37, 0x37, 0x00, 0x00 }, 271 | { "XA1110", GPSGNSSReceiver, 0x10, 0x10, 0x00, 0x00 }, 272 | { "ZMOD4450", GasSensor, 0x32, 0x32, 0x00, 0x00 }, 273 | { "ZOE-M8Q", GPSGNSSReceiver, 0x42, 0x42, 0x00, 0x00 }, 274 | }; 275 | 276 | const device_t Unknown PROGMEM = {"?", UnknownDevice, 0, 0, 0, 0}; 277 | const int Devices = sizeof Device / sizeof *Device; 278 | 279 | boolean match (uint8_t addr, uint8_t from, uint8_t to) { 280 | if (from > to) return (addr == from) || (addr == to); 281 | else return (addr >= from) && (addr <= to); 282 | } 283 | 284 | boolean whoami (uint8_t addr, uint8_t reg, uint8_t value) { 285 | if (reg == 0x00 && value == 0x00) return false; 286 | Wire.beginTransmission(addr); 287 | Wire.write(reg); 288 | if (Wire.endTransmission(false) != 0) return false; 289 | Wire.requestFrom(addr, 1); 290 | return value == Wire.read(); 291 | } 292 | 293 | uint8_t who (uint8_t addr, uint8_t reg) { 294 | Wire.beginTransmission(addr); 295 | Wire.write(reg); 296 | Wire.endTransmission(false); 297 | Wire.requestFrom(addr, 1); 298 | return Wire.read(); 299 | } 300 | 301 | const device_t *findtwin (int i) { 302 | const device_t *me = &Device[i]; 303 | const device_t *other; 304 | for (int j = i-1; j <= i+1; j=j+2) { 305 | if (j >= 0 && j < Devices) { 306 | other = &Device[j]; 307 | if (strcmp(me->device, other->device) == 0) return other; 308 | } 309 | } 310 | return NULL; 311 | } 312 | 313 | boolean twindevice (int i) { 314 | boolean ok; 315 | // Check whether previous or next one in list is a twin 316 | const device_t *other = findtwin(i); 317 | if (other) { 318 | // Check its whoami 319 | uint8_t from = other->from; 320 | uint8_t to = other->to; 321 | uint8_t test = other->test; 322 | uint8_t value = other->value; 323 | if (from > to) { 324 | ok = whoami(from, test, value) || whoami(to, test, value); 325 | } else { 326 | ok = false; 327 | for (uint8_t addr = from; addr <= to; addr++) { 328 | ok = whoami(addr, test, value); 329 | if (ok) break; 330 | } 331 | } 332 | if (ok) return true; 333 | } 334 | return false; 335 | } 336 | 337 | void list (uint8_t addr, const device_t *me) { 338 | tft.print("0x"); tft.print(addr/16, HEX); 339 | tft.print(addr&0xF, HEX); tft.print(' '); 340 | tft.print(me->category); 341 | tft.print(": "); tft.print(me->device); 342 | tft.println(); tft.println(); 343 | } 344 | 345 | void lookup (uint8_t addr) { 346 | // Check for devices with a device ID match 347 | boolean listed = false; 348 | for (int pass=1; pass<4; pass++) { 349 | for (int i=0; ifrom; 352 | uint8_t to = me->to; 353 | uint8_t test = me->test; 354 | uint8_t value = me->value; 355 | if (match(addr, from, to)) { 356 | boolean ok; 357 | if (pass == 1) ok = twindevice(i) && whoami(addr, test, value); 358 | else if (pass == 2) ok = whoami(addr, test, value) && !findtwin(i); 359 | else if (pass == 3) ok = test == 0x00 && value == 0x00; 360 | if (ok) { 361 | list(addr, me); 362 | listed = true; 363 | } 364 | } 365 | } 366 | if (listed) return; 367 | } 368 | list(addr, &Unknown); 369 | } 370 | 371 | void scan () { 372 | for (uint8_t addr=8; addr<128; addr++) { 373 | int ok = true; 374 | Wire.beginTransmission(addr); 375 | if (Wire.endTransmission(true) == 0) lookup(addr); 376 | } 377 | } 378 | 379 | void setup () { 380 | Wire.begin(); 381 | tft.init(240, 240); 382 | tft.setRotation(1); 383 | tft.fillScreen(0); 384 | pinMode(34, OUTPUT); // Backlight 385 | digitalWrite(34, HIGH); 386 | } 387 | 388 | void loop () { 389 | tft.setTextSize(2); 390 | tft.println(" I2C Detective"); 391 | tft.setTextSize(1); 392 | tft.println(); 393 | scan(); 394 | for(;;); 395 | } 396 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # I2C Detective 2 | 3 | Identify I2C devices from a database of the most popular I2C sensors and other devices. 4 | 5 | For more information see http://www.technoblogy.com/show?3FFW. 6 | --------------------------------------------------------------------------------