ESP32: I2C and the first WHO_AM_I
Video coming soon
This is lesson 2.3 again, on the Arduino Nano ESP32: the Wire library sets up I2C on pins A4 and A5, no CubeMX needed. We write the register number, read one byte back, and check the answer.
In this lesson · 4 steps
1Wiring (Arduino Nano ESP32 → IMU breakout)
3V3→ VIN / VCC (not VBUS: that is 5 V)GND→ GNDA4→ SDAA5→ SCL- Most breakouts already have pull-up resistors on SDA and SCL. The address pin left open gives the default address.
2New sketch
- File → New Sketch, save it as
ch2_who_am_i - Tools → Board: Arduino Nano ESP32, Tools → Port: your board
3Read WHO_AM_I once
ch2_who_am_i.ino · replace everything
We tell the sensor which register we want, then read one byte back.
#include <Wire.h> /* IMU: change these three lines for your sensor * * sensor I2C address WHO_AM_I register expected answer * ISM330DHCX 0x6A (0x6B) 0x0F 0x6B * LSM6DSOX 0x6A (0x6B) 0x0F 0x6C * MPU-6050 0x68 (0x69) 0x75 0x68 * MPU-9250 0x68 (0x69) 0x75 0x71 * ICM-20948 0x69 (0x68) 0x00 0xEA * ICM-42688-P 0x68 (0x69) 0x75 0x47 * (in brackets: the address when the address pin is pulled the other way) */ #define IMU_ADDR 0x6A /* 7-bit I2C address */ #define IMU_WHO_AM_I 0x0F /* WHO_AM_I register */ #define IMU_WHO_AM_I_VAL 0x6B /* expected answer */ void setup() { Serial.begin(115200); delay(10000); /* 10 s: time to connect the serial plotter */ Wire.begin(); /* Nano ESP32: SDA = A4, SCL = A5 */ Wire.setClock(400000); /* 400 kHz, like on the STM32 */ /* 1. tell the sensor which register we want */ Wire.beginTransmission(IMU_ADDR); Wire.write(IMU_WHO_AM_I); uint8_t error = Wire.endTransmission(false); /* false: keep the bus, a read follows */ /* 2. read one byte back */ if (error != 0 || Wire.requestFrom(IMU_ADDR, 1) != 1) { Serial.println("No answer: check the wires and the address"); return; } uint8_t who_am_i = Wire.read(); if (who_am_i == IMU_WHO_AM_I_VAL) Serial.printf("WHO_AM_I = 0x%02X: sensor found!\n", who_am_i); else Serial.printf("WHO_AM_I = 0x%02X: unexpected value\n", who_am_i); } void loop() { }
Why?
The three values are the same as on the STM32; my sensor answers at 0x6B, so change IMU_ADDR if you get No answer. Wire uses the 7-bit address directly, no shift. endTransmission(false) keeps the bus for the read that follows. The 10 second delay gives us time to connect the plotter, because the message is printed only once.
4Upload and check
- Upload, then connect our web serial plotter (serial.steppeschool.com, chapter 1), 115200 baud
- Missed the line? It is printed once at start: press reset, then connect within 10 s (the USB port restarts too)
Check & troubleshoot
What you should see
WHO_AM_I = 0x6B: sensor found!in the serial plotter console
If it doesn't work
- Compile error: every Arduino sketch needs a
loop()function, even an empty one - No message: it is printed once at start. After the upload the USB port restarts, so connect the plotter within the 10-second delay
- No answer: check A4/A5 and the address (hex 6A or 6B, set by the SDO pin)
- Use the 3V3 pin, not 5 V