> ## Documentation Index
> Fetch the complete documentation index at: https://docs.e-spin.fr/llms.txt
> Use this file to discover all available pages before exploring further.

# I2C Scanner

> Learn how to interface with different sensors using the I2C protocol and your E-Spin.

<Note>
  This tutorial assumes you have already installed the QMI8658 library and know how to flash the board. See the [library installation guide](#) and [getting started guide](#) if needed.
</Note>

## What is I2C?

I2C (Inter-Integrated Circuit, pronounced "I-squared-C") is a two-wire serial communication protocol. Every device on the bus shares two lines:

* **SDA** — Serial Data
* **SCL** — Serial Clock

Each device has a fixed 7-bit address (e.g. `0x68`). The controller (your ESP32) initiates every transaction and addresses a specific peripheral. Multiple devices can coexist on the same two wires as long as their addresses are unique.

**Why does this matter for E-Spin?** Your board already has one I2C device built in — the IMU. The exposed GPIO headers let you chain additional sensors (temperature, pressure, distance, OLED displays...) onto the same bus without using extra pins.

## What this project does

The scanner iterates through all 128 possible I2C addresses and attempts to contact each one. When a device acknowledges the ping, its address is printed to the serial monitor.

Expected output on a bare E-Spin:

```text theme={null}
Scanning I2C bus...
Found device at address 0x6A  <- IMU
Scan complete. 1 device found.
```

## Wiring

No additional wiring needed. The IMU is already connected to the ESP32's I2C bus on the PCB.

If you want to scan external devices, connect them to the GPIO header:

| E-Spin Pin | Function  |
| ---------- | --------- |
| `GPIO5`    | I2C Data  |
| `GPIO4`    | I2C Clock |
| `3.3V`     | Power     |
| `GND`      | Ground    |

<Note>
  Most 3.3V I2C breakout boards work directly. For 5V modules, use a logic-level shifter — the ESP32-C3 is **not** 5V tolerant.
</Note>

## Code

```cpp theme={null}
#include <Wire.h>

// Default I2C pins on E-Spin
#define SDA_PIN 5
#define SCL_PIN 4

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);
  Wire.begin(SDA_PIN, SCL_PIN);
}

void loop() {
  Serial.println("\n--- Scanning I2C bus ---");
  uint8_t devicesFound = 0;

  for (uint8_t address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    uint8_t error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("Found device at address 0x");
      if (address < 16) Serial.print("0");
      Serial.println(address, HEX);
      devicesFound++;
    }
  }

  Serial.print("Scan complete. ");
  Serial.print(devicesFound);
  Serial.println(" devices found.");

  delay(3000); // scan every 3s
}
```

## What's next?

Now that you've confirmed the IMU is alive on the bus, the next tutorial reads actual sensor data from it.

<Card title="Read IMU Raw Data" icon="compass" href="/projects/imu-raw">
  Read accelerometer and gyroscope values directly over I2C.
</Card>
