I2C Scanner Code for the Arduino and ESP32
Table of Contents
I2C Scanner:
I2C Scanner Code for the Arduino and ESP32- today’s article is about scanning I2C sensors using Arduino and ESP32 WiFi + Bluetooth Module. The I2C Scanner code I will share works with both Arduino and ESP32 WiFi + Bluetooth Module.
For demonstration, I will connect the BMP585 pressure and temperature sensor to the Arduino and the AMG8833 IR temperature sensor to the ESP32 WiFi + Bluetooth Module. You can use any other sensors instead of these.
What is I²C?
I²C (Inter-Integrated Circuit) is a multi-master, multi-slave, packet-switched, single-ended, serial computer bus. Primarily used in short distance, intra-board communication it is often utilized to connect low-speed peripheral ICs and microcontrollers with a processor.
What are I²C Devices?
I²C devices include various types of Temperature sensors, Infrared sensors, pressure sensors, humidity sensors, memory devices like EEPROM, I2C LCDs, I2C Oled displays, Signal processor, and so many other types of sensors and IO devices. Each I²C device has a unique address, allowing multiple devices to share the same bus. So, this way, multiple I2C Sensors can be connected to the Arduino, ESP32, or any other controller board using only two IO pins.
Why Use an I²C Scanner?
An I2C scanner is a simple program with the help of which you can find the I2C address of all the I2C supported sensors. It scans all possible I²C addresses and checks if there is a device responding at each address. This can be extremely useful for:
Debugging: Ensuring that your I2C devices/Sensors are properly connected and accessible.
Address Discovery: Finding the address of new or unknown I2C devices.
Verification: Confirming the functionality of your I²C bus and Sensor.
Amazon Links:
ESP32 WiFi + Bluetooth Module (Recommended)
*Disclosure: These are affiliate links. As an Amazon Associate I earn from qualifying purchases.
I2C Sensor Interfacing:
On the Arduino
SDA = A4
SCL = A5
On ESP32
SDA = GPIO21
SCL = GPIO22
Connect the VCC and GND pins of the I2C sensor to the Arduino or ESP32 V and G pins.
Connect the I2C sensor SDA and SCL pins to the corresponding SDA and SCL pins.
Likewise, you can connect a sensor to the Arduino.
Upload the following Code to your Arduino or ESP32. Open the Serial port and select the desired baud rate.
I2C Scanner Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include <Wire.h> void setup() { Wire.begin(); Serial.begin(115200); // Start serial communication at 115200 baud // Wait for serial port to connect // (necessary for some boards) while (!Serial); Serial.println("\nI2C Scanner"); scanI2CDevices(); } void loop() { // Re-scan every 5 seconds delay(5000); scanI2CDevices(); } void scanI2CDevices() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for (address = 1; address < 127; address++) { // The I2C scanner uses the return value of // Wire.endTransmission to see if a device // did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Unknown error at address 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); } |
Using this scanner, you can easily identify and debug the I²C devices connected to your system.
How It Works
1 |
#include <Wire.h> |
This line includes the Wire library, which allows the Arduino and ESP32 to communicate with I²C devices.
1 |
void setup() { |
This begins the setup function, which runs once when the Arduino is powered ON or reset.
1 |
Wire.begin(); |
This initializes the I²C communication.
1 |
Serial.begin(115200); // Start serial communication at 115200 baud |
This starts serial communication at a baud rate of 115200, which is the speed at which data is transmitted.
1 2 3 4 5 |
// Wait for serial port to connect // (necessary for some boards) while (!Serial); |
This waits for the serial port to connect, which is necessary for some Arduino boards to ensure the serial communication is ready.
1 |
Serial.println("\nI2C Scanner"); |
This prints “I2C Scanner” to the serial monitor, indicating the start of the I²C scanning process.
1 |
scanI2CDevices(); |
This calls the scanI2CDevices function to scan for I²C devices.
1 |
} |
This ends the setup function.
1 |
void loop() { |
This begins the loop function, which runs repeatedly after the setup function.
1 2 3 |
// Re-scan every 5 seconds delay(5000); |
This pauses the program for 5 seconds.
1 |
scanI2CDevices(); |
This calls the scanI2CDevices function again to re-scan for I²C devices every 5 seconds.
1 |
} |
This ends the loop function.
scanI2CDevices Function
1 |
void scanI2CDevices() { |
This begins the scanI2CDevices function, which performs the actual I²C device scanning.
1 2 3 |
byte error, address; int nDevices; |
These lines declare variables: error and address are bytes (small integers), and nDevices is an integer to count the number of I²C devices found.
1 |
Serial.println("Scanning..."); |
This prints “Scanning…” to the serial monitor, indicating that the scanning process is starting.
1 |
nDevices = 0; |
This initializes the number of devices found to zero.
1 |
for (address = 1; address < 127; address++) { |
This starts a for-loop to iterate through all possible I²C addresses from 1 to 126.
1 2 3 4 5 6 7 |
// The I2C scanner uses the return value of // Wire.endTransmission to see if a device // did acknowledge to the address. Wire.beginTransmission(address); |
This begins communication with the device at the current address.
1 |
error = Wire.endTransmission(); |
This ends the communication and captures the result. If a device acknowledges the address, error will be 0.
1 |
if (error == 0) { |
This checks if a device responded at the current address.
1 |
Serial.print("I2C device found at address 0x"); |
This prints a message indicating that a device was found.
1 2 3 |
if (address < 16) Serial.print("0"); |
This adds a leading zero for addresses less than 16 to maintain proper formatting.
1 |
Serial.print(address, HEX); |
This prints the address of the device in hexadecimal format.
1 |
Serial.println(" !"); |
This finishes the line with an exclamation mark.
1 |
nDevices++; |
This increments the count of devices found.
1 |
} else if (error == 4) { |
This checks if there was an unknown error during communication.
1 |
Serial.print("Unknown error at address 0x"); |
This prints a message indicating an unknown error.
1 2 3 |
if (address < 16) Serial.print("0"); |
This adds a leading zero for addresses less than 16.
1 |
Serial.println(address, HEX); |
This prints the address with the unknown error.
1 2 3 |
} } |
This ends the for-loop.
1 2 3 |
if (nDevices == 0) Serial.println("No I2C devices found\n"); |
If no devices were found, this prints “No I2C devices found”.
1 2 3 |
else Serial.println("done\n"); |
If one or more devices were found, this prints “done”.
1 |
} |
This ends the scanI2CDevices function.
Arduino, BMP585 I2C address:
ESP32, AMG8833 I2C address:
Support me on Patreon for more articles and videos.