/* https://evision-webshop.de/blog/i2c-slave-adressierung-mit-7-bit-8-bit-und-10-bit I2C Adressen und Frequenz Scanner */ #include #include Stream &cout {Serial}; TwoWire &wire0 {Wire}; // die echten Frequenzen sind abhängig vom Pullup und Leitungskapazität const uint32_t i2cFreq [] = {100000, 200000, 400000}; // , 800000}; const uint8_t ANZAHLFREQ = sizeof(i2cFreq) / sizeof(i2cFreq[0]); void setup() { Serial.begin(9600); Wire.begin(); cout.println("\nReset ####"); delay(100); scanner(cout, wire0, 0); } void loop (void) { scanner(cout, wire0, 5000); } void scanner (Stream &out, TwoWire &line, const unsigned long interval) { static unsigned long lastMillis {0}; if (millis() - lastMillis >= interval) { lastMillis += interval; // Betreffzeile erzeugen out.print(F("\naddr ")); for (auto &i : i2cFreq) { out.print(i/1000); out.print(" "); } out.println(F("kHz Line")); scanI2C(out, line); } } void scanI2C (Stream &out, TwoWire &line) { bool deviceFound {false}; for (uint8_t addr = 0x08; addr < 0x78; addr++ ) { // gültiger 7Bit Adressbereich for (uint8_t i = 0; i < ANZAHLFREQ; i++) { line.setClock(i2cFreq[i]); const uint8_t error = checkI2CAddr(addr, line); if((0 == error) && (i2cFreq[i] == i2cFreq[0])) { deviceFound = true; out.print(F("0x")); if (addr < 0x10) { out.print(F("0")); } out.print(addr, HEX); out.print(F(" ")); } if (deviceFound && (0 == error)) { out.print(F("x ")); } if (deviceFound && (0 < error)) { out.print(F(" ")); } // alle Frequenzen gescannt, wenn ein Device gefunden wurde Zeile abschließen if (deviceFound && (i >= ANZAHLFREQ-1)) { out.print(F(" ")); if (&line == &wire0) { out.print(F("TWI.0")); } // else if (&line == &wire1) { out.print(F("TWI.1")); } if (0 < error) { out.print("\t"); i2cErrorEvaluation (out, error); } out.println(); deviceFound = false; } } } } byte checkI2CAddr (const uint8_t addr, TwoWire &line) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. line.beginTransmission(addr); const byte error = line.endTransmission(); if (0x04 <= error) { delay(5); // give the device x [ms] } return error; } void i2cErrorEvaluation (Stream &out, const uint8_t error) { switch (error) { case 0x00: out.print(F("ACK Response from device")); break; case 0x01: out.print(F("data too long to fit in transmit buffer")); break; case 0x02: out.print(F("received NACK on transmit")); break; case 0x03: out.print(F("received NACK on transmit of data")); break; case 0x04: out.print(F("Unknow error")); break; case 0x10: out.print(F("arbitration lost")); break; case 0x11: out.print(F("line held low or not pulled up")); break; case 0xFF: out.print(F("bus in unknown state")); break; default: out.print(F("unknow error code")); break; } }