To code an ultrasonic sensor with an Arduino Uno R3, wire the HC-SR04 Trig pin to D9 and Echo pin to D10, power it with 5V, and use the NewPing library to handle timing interrupts and prevent the microcontroller from blocking. This guide provides the exact pinout, compilable code, and bench-tested debugging steps for when your serial monitor spits out 0 cm or erratic data.

Direct Answer: The most reliable way to code an HC-SR04 ultrasonic sensor on an Arduino is using the NewPing library rather than the native pulseIn() function, as it prevents the CPU from hanging during timeout events and natively handles out-of-range errors.

Project Overview & Difficulty Rating

HC-SR04 Ultrasonic Module Specifications
ParameterValueNotes
Operating Voltage5V DCDo not power directly from 3.3V pins
Operating Current15 mA (active)Quiescent current is < 2 mA
Measuring Range2 cm to 400 cmBlind zone is 0-2 cm
Trigger Pulse10 µs TTLMinimum HIGH time required
Echo Signal5V TTL PulseWidth proportional to distance

Parts List

  • Microcontroller: Arduino Uno R3 (ATmega328P) or Arduino Nano v3 (ATmega328P)
  • Sensor: HC-SR04 4-pin Ultrasonic Module (5V logic variant)
  • Wiring: 4x Male-to-Male or Male-to-Female jumper wires (22 AWG)
  • Breadboard: Standard 830-point solderless breadboard
  • Library: NewPing (Install via Arduino Library Manager)

HC-SR04 Pin Mapping & Wiring Steps

The HC-SR04 uses two digital pins for communication: one to send the ultrasonic burst (Trigger) and one to listen for the return echo (Echo). Because the Echo pin outputs a 5V HIGH signal, it is strictly compatible with 5V-tolerant microcontrollers like the Arduino Uno.

Arduino Uno R3 to HC-SR04 Pin Mapping
HC-SR04 PinArduino Uno R3 PinWire Color (Standard)
VCC5VRed
TrigDigital 9 (D9)Yellow
EchoDigital 10 (D10)Green
GNDGNDBlack

Wiring Procedure

  1. De-energize the board: Disconnect the Arduino from USB or external power before wiring.
  2. Connect Power: Route the red jumper from the Arduino 5V pin to the HC-SR04 VCC pin. Route the black jumper from GND to GND.
  3. Connect Trigger: Connect the yellow jumper from Arduino D9 to the sensor Trig pin.
  4. Connect Echo: Connect the green jumper from Arduino D10 to the sensor Echo pin.
  5. Verify: Double-check that VCC and GND are not swapped. Reversing polarity on the HC-SR04 will instantly destroy the onboard MAX232 equivalent driver chip.
3.3V Logic Warning: If you are adapting this build for an ESP32 or Raspberry Pi Pico, the 5V Echo pulse will damage the 3.3V GPIO pin. You must use a voltage divider (e.g., 1kΩ and 2kΩ resistors) on the Echo pin to step the 5V signal down to ~3.3V.

Complete Arduino Code for Ultrasonic Sensor

This code targets the Arduino Uno R3 and Nano v3 (AVR architecture). It uses the NewPing library, which is vastly superior to the native Arduino pulseIn() function because it uses timer interrupts and doesn't freeze your sketch if the echo never returns.

#include <NewPing.h>

// Pin Definitions - Change these if your wiring differs
#define TRIGGER_PIN  9
#define ECHO_PIN     10
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in cm)

// Initialize NewPing object
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
  // Start serial communication at 9600 baud
  Serial.begin(9600);
  Serial.println("HC-SR04 Ultrasonic Sensor Initialized.");
}

void loop() {
  // ping_cm() returns the distance in centimeters, or 0 if out of range
  unsigned int distance = sonar.ping_cm();
  
  // Error handling for out-of-range or timeout
  if (distance == 0) {
    Serial.println("Error: Out of range, object too close (<2cm), or no echo received.");
  } else {
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");
  }
  
  // Wait 50ms between pings (29ms is the minimum recommended delay)
  delay(50);
}

Advanced: Temperature Compensation

The speed of sound changes with air temperature. The NewPing library assumes 20°C (343 m/s). If your project operates in extreme environments, use sonar.ping_median(5) to get the raw microsecond time, then apply the formula: distance_cm = (ping_time / 2) * (331.3 + 0.606 * temp_C) / 10000.

Debugging: Fixing '0 cm' and Erratic Readings

When your serial monitor outputs Error: Out of range... or constantly prints 0 cm, do not immediately assume the sensor is dead. Follow these first three diagnostic steps to isolate the fault.

The First 3 Things to Check When It Fails

  1. Measure VCC at the Sensor Pins: Use a digital multimeter (DMM) to probe the VCC and GND pins directly on the HC-SR04 header. You must read between 4.8V and 5.2V. If you read 3.3V or 0V, your breadboard power rail is broken or you are plugged into the wrong Arduino pin.
  2. Verify the Trigger Pulse Width: The HC-SR04 requires a minimum 10 µs HIGH pulse on the Trigger pin. If your code uses a custom digitalWrite sequence without delayMicroseconds(10), the sensor will never fire. NewPing handles this automatically, but custom code often misses it.
  3. Check for Acoustic Blind Spots: The HC-SR04 has a physical blind zone of 2 cm. If an object is pressed directly against the metal mesh of the transducers, the echo returns before the receiver circuit finishes its initialization, resulting in a 0 cm reading.

Ranked Causes for Exact Error Strings

Serial Monitor OutputMost Likely CauseFix
0 cm continuouslyPower rail disconnected or Trig pin wired to wrong D-pin.Verify DMM reads 5V at sensor. Check #define TRIGGER_PIN matches physical wire.
200 cm (or MAX_DISTANCE) when object is closeEcho pin wire disconnected or broken internally.Swap the Echo jumper wire. Measure Echo pin with DMM; it should pulse 5V when triggered.
Erratic jumping (e.g., 14cm, 85cm, 15cm)Sound reflecting off soft/angled surfaces, or 5V ripple on power line.Aim at a flat, hard surface. Add a 100µF decoupling capacitor across VCC and GND on the breadboard.

Extending and Simplifying the Build

How to Simplify the Build (Zero Dependencies)

If you cannot use external libraries or are coding on a constrained platform without the Arduino Library Manager, you can simplify the build by using the native pulseIn() function. However, be aware that pulseIn() is a blocking function. If the sensor is pointed at an open window and no echo returns, the Arduino will freeze for up to 1 second (the default timeout) before moving to the next line of code. For simple LED-proximity alarms, this is acceptable; for motor control or multi-sensor arrays, it will cause system jitter.

How to Extend the Build

  • Multi-Sensor Arrays: The NewPing library supports up to 15 sensors. You can trigger them sequentially using the ping_timer() method, which uses hardware timers to ping sensors in the background without blocking the main loop().
  • Add an I2C OLED Display: Wire an SSD1306 128x64 OLED display to the A4 (SDA) and A5 (SCL) pins. Use the Adafruit_SSD1306 library to render the distance visually, turning the project into a standalone digital tape measure.
  • Implement a Moving Average Filter: Ultrasonic sensors suffer from acoustic jitter. Store the last 5 readings in an array, sort them, and return the median value to eliminate outlier spikes caused by stray acoustic reflections.

Frequently Asked Questions

Can I code an ultrasonic sensor with Arduino without the NewPing library?

Yes. You can write raw C++ using digitalWrite() to pulse the Trigger pin HIGH for 10 microseconds, then use pulseIn(ECHO_PIN, HIGH) to measure the return time. Divide the resulting microseconds by 58 to get centimeters. While this requires no external libraries, it blocks the CPU during the measurement and lacks built-in timeout handling, making it unsuitable for real-time robotics applications. For a detailed breakdown of the native timing, refer to the SparkFun HC-SR04 Hookup Guide.

Why does my HC-SR04 code ultrasonic sensor Arduino project read 0 cm constantly?

A constant 0 cm reading usually indicates a hardware fault, not a code error. The most common culprits are: (1) The 5V power rail on your breadboard is split and not jumpered, leaving the sensor unpowered. (2) The Trigger and Echo pins are swapped in your physical wiring but not in your code. (3) The object is inside the 2 cm acoustic blind zone. Always verify power with a multimeter before rewriting your code.

How do I wire an HC-SR04 to a 3.3V ESP32 instead of a 5V Arduino?

The HC-SR04 requires 5V to operate reliably, so you must power its VCC pin from the ESP32's VIN or 5V pin (if available via USB). However, the Echo pin outputs a 5V HIGH signal, which will fry the ESP32's 3.3V GPIO. You must build a voltage divider on the Echo line: connect a 1kΩ resistor between the Echo pin and the ESP32 GPIO, and a 2kΩ resistor between that same GPIO and GND. This drops the 5V pulse down to a safe ~3.3V.

What is the maximum reliable range when coding an ultrasonic sensor?

While the HC-SR04 datasheet claims a 400 cm (4 meter) maximum range, real-world bench testing shows reliable accuracy drops off significantly past 250 cm. At distances beyond 3 meters, the 40 kHz acoustic wave attenuates in the air, and the return echo is often too weak for the onboard comparator to trigger cleanly. For reliable industrial or robotic applications, cap your MAX_DISTANCE variable at 200 cm to prevent false timeouts.