
Overview
The HC-SR04 (2021 version) is an enhanced ultrasonic distance sensor based on the classic HC-SR04 design. It integrates a dedicated RCWL-9200 ultrasonic signal processor that adds multiple digital communication modes to the original hardware platform.
Unlike the traditional two-pin TRIG/ECHO interface, this version supports four selectable communication modes:
- GPIO (TRIG/ECHO pins, classic HC-SR04 default mode)
- I²C (IIC)
- 1-Wire
- UART
This allows flexible integration into a wide variety of embedded systems.
In this tutorial, we will investigate the I2C mode.
Compatibility
Given the voltage input range for the HC-SR04 (2021 version) is between 2.8V and 5.5V, this module will work with a range of microcontroller development boards. Most notably the common 3.3V and 5V development boards such as:
Technical Features
Range Explanation
The range specifications of the HC-SR04 ultrasonic sensor are:
- Minimum distance: about 2 cm. This is the acoustic dead zone (the sensor cannot detect anything closer because the echo overlaps with the transmitted pulse).
- Typical usable distance: about 5 cm to 300–400 cm. Within this range, readings are stable and accurate on flat, perpendicular targets.
- Maximum distance: up to about 450–500 cm under ideal conditions:
- Large, hard, flat target surface
- Perpendicular to the sensor
- Good power supply and stable I²C timing
- Quiet environment (low acoustic noise)
Assumptions behind these figures:
- Target surface is flat and hard (like a wall or book)
- Target is directly facing the sensor (normal incidence)
- Ambient temperature is near 20 °C, which gives a sound speed of about 343 m/s
- Supply voltage is stable
- Proper delay (~120–200 ms) is given between measurements
If any of these conditions are not met (soft or angled target, small object, background noise, short delay), the effective range becomes shorter and readings may fluctuate.
Mode Selection
The module uses two solder jumpers, M1 and M2, to select the communication mode.
For I²C mode:
- M1: bridged (soldered closed)
- M2: open
Ensure this configuration before uploading the sketch below. See the image below to verify the proper mode selection.

Communication Protocol
The RCWL-9200 controller uses a simple I²C sequence:
-
Send command: Write a single byte
0x01
to the device at address0x57
to start a measurement - Wait: Delay approximately 100 – 150 ms for the measurement to complete
-
Read result: Read 3 bytes from register
0xAF
- Convert: Combine the three bytes into a 24-bit integer (micrometers), then divide by 10 000 to get distance in centimeters
Example Sketch
For this Mode 2: I2C Method simply connect Ground GND and VCC to the power pins of the Dev Board (Uno R3, Nano Flip, ESP32 microWatt, Nano Flip 3V3, etc). If using an ATmega328P based microcontroller, for example, connect the SCL pin to A5, and SDA pin to A4.
// Example: Mode 2) I2C (M1=1, M2=0)
// Last Update: Sept 16, 2025
//
// CONNECTIONS
// In this example we are using the 5V ATmega328P based Uno R3+ microcontroller development board.
// But all other common dev boards should work
// HC-SR04 -> Uno R3+
// VCC -> 5V
// GND -> GND
// SDA -> A4
// SCL -> A5
// OPERATIONAL NOTES
/*
This ultrasonic module is designed for general distance measurement and typically provide a measurable range of about:
Minimum range: ≈ 2 cm (limited by transmit/receive dead zone)
Maximum range: ≈ 450 to 500 cm (4.5 to 5 meters) under ideal conditions
Key points
- Accuracy is best from 5 cm to 300 cm
- Beyond ~3 m, readings become more sensitive to target size, angle, and ambient noise
- Objects must be flat, hard, and perpendicular to the sensor to reflect the ultrasonic pulse effectively
*/
/*
The ultrasonic module integrates a dedicated controller (RCWL-9191/9300C/9200 series) that implements a proprietary I²C communication protocol, distinct from the commonly referenced SRF02 protocol.
In this protocol, the device operates at the fixed I²C address 0x57.
To initiate a ranging operation, the host transmits a single command byte 0x01 to this address.
After a measurement delay of approximately 100–150 ms, the host reads three consecutive bytes from register 0xAF.
These bytes represent the measured distance in micrometers.
The combined 24-bit value must be divided by 1000 to obtain the result in millimeters, and can be further divided by 10 to express the result in centimeters.
*/
#include
const uint8_t I2C_ADDR = 0x57; // Device address
const uint8_t CMD_START = 0x01; // start ranging
const uint8_t REG_READ = 0xAF; // returns H M L
const uint16_t MEASURE_DELAY_MS = 120;
const uint16_t PERIOD_MS = 300;
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
Wire.beginTransmission(I2C_ADDR);
Wire.write(CMD_START);
uint8_t err = Wire.endTransmission();
if (err) {
Serial.print("I2C err "); Serial.println(err);
delay(PERIOD_MS);
return;
}
delay(MEASURE_DELAY_MS);
Wire.beginTransmission(I2C_ADDR);
Wire.write(REG_READ);
Wire.endTransmission(false);
Wire.requestFrom((int)I2C_ADDR, 3);
if (Wire.available() == 3) {
uint32_t H = Wire.read();
uint32_t M = Wire.read();
uint32_t L = Wire.read();
uint32_t micrometers = (H << 16) | (M << 8) | L;
float cm = micrometers / 10000.0f; // convert µm → cm
Serial.print(cm, 2);
Serial.println(" cm");
} else {
Serial.println("no data");
}
delay(PERIOD_MS);
}
How It Works
This sketch works because it follows the RCWL-9200’s I²C protocol. Sending 0x01
tells the controller to initiate a ranging cycle. After the measurement completes, the controller places a 24-bit distance value in micrometers into register 0xAF
. The sketch reads this 3-byte value, converts it to centimeters, and prints it.