/* * I2C Communication Pattern Example * * Demonstrates I2C bus scanning and device detection with: * - 7-bit address scanning (0x08-0x77) * - Board-specific SDA/SCL pin configuration * - Error detection and reporting * - Common device identification * * Generated by: arduino-code-generator * Pattern: I2C Communication * License: MIT */ #include // === Board Configuration === #if defined(ARDUINO_AVR_UNO) #define BOARD_NAME "Arduino UNO" #define SDA_PIN A4 #define SCL_PIN A5 #define SERIAL_BAUD 9600 #elif defined(ESP32) #define BOARD_NAME "ESP32" #define SDA_PIN 21 #define SCL_PIN 22 #define SERIAL_BAUD 115200 #elif defined(ARDUINO_ARCH_RP2040) #define BOARD_NAME "RP2040" #define SDA_PIN 4 #define SCL_PIN 5 #define SERIAL_BAUD 115200 #else #define BOARD_NAME "Generic" #define SERIAL_BAUD 9600 #endif // === Common I2C Device Addresses === struct KnownDevice { uint8_t address; const char* name; }; const KnownDevice knownDevices[] = { {0x20, "MCP23017 GPIO Expander"}, {0x27, "PCF8574 LCD Backpack"}, {0x3C, "SSD1306 OLED Display"}, {0x3D, "SSD1306 OLED Display (Alt)"}, {0x48, "ADS1115 ADC"}, {0x50, "AT24C EEPROM"}, {0x57, "AT24C32 EEPROM"}, {0x68, "DS1307 RTC / MPU6050 IMU"}, {0x76, "BMP280 Sensor"}, {0x77, "BMP280 Sensor (Alt)"} }; const size_t knownDeviceCount = sizeof(knownDevices) / sizeof(knownDevices[0]); // === Helper Functions === const char* identifyDevice(uint8_t address) { for (size_t i = 0; i < knownDeviceCount; i++) { if (knownDevices[i].address == address) { return knownDevices[i].name; } } return "Unknown Device"; } void scanI2CBus() { Serial.println(F("\nScanning I2C bus...")); Serial.println(F("Addr Status Device Name")); Serial.println(F("---- -------- ---------------------")); uint8_t devicesFound = 0; for (uint8_t address = 0x08; address < 0x78; address++) { Wire.beginTransmission(address); uint8_t error = Wire.endTransmission(); if (error == 0) { // Device found Serial.print(F("0x")); if (address < 16) Serial.print(F("0")); Serial.print(address, HEX); Serial.print(F(" Found ")); Serial.println(identifyDevice(address)); devicesFound++; } else if (error == 4) { // Unknown error Serial.print(F("0x")); if (address < 16) Serial.print(F("0")); Serial.print(address, HEX); Serial.println(F(" Error Unknown I2C error")); } } Serial.println(F("---- -------- ---------------------")); Serial.print(F("Total devices found: ")); Serial.println(devicesFound); if (devicesFound == 0) { Serial.println(F("\nNo I2C devices detected!")); Serial.println(F("Check wiring:")); Serial.print(F(" SDA -> Pin ")); Serial.println(SDA_PIN); Serial.print(F(" SCL -> Pin ")); Serial.println(SCL_PIN); Serial.println(F(" VCC -> 3.3V or 5V")); Serial.println(F(" GND -> GND")); } } void setup() { Serial.begin(SERIAL_BAUD); while (!Serial && millis() < 3000); Serial.println(F("\n=== I2C Scanner Example ===")); Serial.print(F("Board: ")); Serial.println(F(BOARD_NAME)); #if defined(ARDUINO_AVR_UNO) Wire.begin(); #else Wire.begin(SDA_PIN, SCL_PIN); #endif Wire.setClock(100000); // 100kHz standard mode Serial.print(F("I2C Clock: 100 kHz\n")); Serial.print(F("SDA Pin: ")); Serial.println(SDA_PIN); Serial.print(F("SCL Pin: ")); Serial.println(SCL_PIN); scanI2CBus(); } void loop() { static unsigned long lastScan = 0; const unsigned long SCAN_INTERVAL_MS = 10000; // Scan every 10 seconds if (millis() - lastScan >= SCAN_INTERVAL_MS) { lastScan = millis(); scanI2CBus(); } }