When interfacing distance sensors with microcontrollers, understanding the exact electrical behavior of the trigger and echo pin in ultrasonic sensor modules is the difference between reliable data and erratic timeouts. The HC-SR04, along with its waterproof sibling the JSN-SR04T, does not output an analog voltage or an I2C data stream. Instead, it relies on a strict digital timing protocol where the microcontroller initiates a measurement and the sensor responds with a proportional 5V TTL pulse width. Getting this timing right—especially when stepping down to 3.3V logic for an ESP32 or Raspberry Pi—requires precise resistor dividers and temperature-compensated math.

The Physics: How the Trigger and Echo Pin in Ultrasonic Sensor Timing Works

The HC-SR04 and its variants rely on piezoelectric transducers to emit a 40 kHz acoustic burst. The trigger pin acts as the input gate: when the microcontroller pulls this pin HIGH for at least 10 microseconds, the sensor's internal timing IC fires exactly eight 40 kHz cycles. This precise 10 µs threshold is hardcoded into the module's logic, meaning any trigger pulse shorter than this will be ignored, while pulses longer than 10 µs simply initiate the same standard burst.

Once the acoustic burst is emitted, the echo pin flips from LOW to HIGH and starts an internal hardware timer. It remains HIGH until the transducer detects the returning acoustic reflection, at which point it drops back to LOW. The width of this HIGH pulse is directly proportional to the round-trip time of flight (ToF) of the sound wave. If no echo is received within 38 milliseconds, the echo pin forces a timeout and drops LOW, signaling an out-of-range measurement to the host microcontroller.

Pinout, Electrical Specs, and 3.3V Wiring Matrix

Before writing any code, you must match the sensor's electrical expectations to your microcontroller's GPIO limits. The HC-SR04 is natively a 5V device. While the trigger pin is an input and will reliably register a 3.3V HIGH signal from an ESP32, the echo pin is a 5V output. Feeding a 5V echo signal directly into a 3.3V microcontroller GPIO will degrade the silicon over time or instantly brick the pin. You must use a voltage divider on the echo line.

Pin Name Function Voltage Level Timing / Specifications 3.3V MCU Adaptation (ESP32/Pi)
VCC Power Supply 4.5V to 5.5V DC Draws ~15mA active, 2mA standby Connect to 5V rail (USB or Buck)
TRIG Trigger Input 5V TTL (Accepts 3.3V) Requires ≥10 µs HIGH pulse Direct GPIO connection safe
ECHO Measurement Output 5V TTL Output Pulse width: 150 µs to 25,000 µs Voltage Divider Required
GND Ground Reference 0V Must share ground with MCU Connect to MCU GND
💡 Callout Tip: The 3.3V Echo Voltage Divider
To safely step the 5V Echo pin down to 3.3V, wire a 1kΩ resistor in series with the Echo pin, and a 2kΩ resistor from the microcontroller's GPIO pin to GND. This creates a 3.33V output when the Echo pin goes HIGH. For high-speed polling, keep the resistor values low (e.g., 1kΩ/2kΩ rather than 10kΩ/20kΩ) to minimize the RC time constant and preserve the sharp rising edge of the pulse.

Output Signal Math: Converting Raw Pulses to Physical Units

The output of the echo pin is strictly a digital pulse width measured in microseconds (µs). It is not an analog voltage that scales with distance, nor is it a serial data packet. To convert this raw time into centimeters, we use the physics of the speed of sound.

The standard formula is: Distance = (Time × Speed of Sound) / 2. We divide by 2 because the sound wave travels to the object and back (round-trip). At a standard room temperature of 20°C (68°F), the speed of sound in dry air is approximately 343 meters per second, or 0.0343 cm/µs.

Plugging this into the formula:
Distance (cm) = (Pulse_Width_µs × 0.0343) / 2
Distance (cm) = Pulse_Width_µs × 0.01715
Distance (cm) = Pulse_Width_µs / 58.309

Most basic tutorials hardcode the divisor as 58. While this works for rough hobby projects, it introduces a ~0.5% error. For precision applications, use 58.3 or implement dynamic temperature compensation.

Temperature-Compensated Scaling

The speed of sound changes by roughly 0.606 m/s for every 1°C change in air temperature. If your sensor is deployed in an unheated garage at 5°C, the speed of sound drops to ~334 m/s, and the standard / 58 math will report distances that are roughly 2.5% too long. The exact speed of sound formula is v = 331.4 + (0.606 × T) where T is temperature in Celsius. According to Penn State's Acoustics Laboratory, humidity and pressure have negligible effects compared to temperature.

Below is a complete, copy-pasteable ESP32/Arduino sketch that handles the trigger timing, reads the echo pulse safely using the Arduino pulseIn() function, and applies temperature compensation.

// HC-SR04 / JSN-SR04T Interfacing with Temperature Compensation
// Target: ESP32 DevKit V1 or Arduino Uno

const int TRIG_PIN = 5;    // Direct connection to 5V/3.3V GPIO
const int ECHO_PIN = 18;   // Connected via 1k/2k voltage divider for ESP32
const float TEMP_C = 22.5; // Update with real DS18B20/DHT22 reading

void setup() {
  Serial.begin(115200);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  digitalWrite(TRIG_PIN, LOW); // Ensure clean state
}

float getDistanceCM() {
  // 1. Clear trigger pin
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  
  // 2. Fire 10us trigger pulse
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  
  // 3. Read echo pulse width (timeout at 38000us = ~6.5 meters)
  unsigned long duration = pulseIn(ECHO_PIN, HIGH, 38000);
  
  if (duration == 0) {
    return -1.0; // Timeout / Out of range
  }
  
  // 4. Calculate temperature-adjusted speed of sound (cm/us)
  float speedOfSound = (331.4 + (0.606 * TEMP_C)) / 10000.0;
  
  // 5. Calculate one-way distance
  float distance = (duration * speedOfSound) / 2.0;
  return distance;
}

void loop() {
  float dist = getDistanceCM();
  if (dist >= 0) {
    Serial.printf("Distance: %.2f cm\n", dist);
  } else {
    Serial.println("Error: Out of range or no echo detected.");
  }
  delay(60); // 60ms delay prevents acoustic crosstalk / ringing
}

Real-World Interference and Edge Case Debugging

Ultrasonic sensors are notoriously susceptible to environmental physics. If your raw echo pulses are jittery or returning false zeros, you are likely hitting one of the following acoustic edge cases.

Interference Source Symptom in Data Physical Cause Engineering Fix
Transducer Ringing (Blind Spot) Readings jump to 0 or max when object is < 2 cm away. The sender transducer is still physically vibrating from the trigger burst when the echo returns, deafening the receiver. Enforce a software blind spot. Discard any duration reading under 115 µs (approx 2 cm).
Acoustic Crosstalk Random massive spikes in distance when using multiple sensors. Sensor A's receiver hears the 40 kHz bounce from Sensor B's transmitter. Stagger trigger pulses. Ensure a minimum 50 ms delay between firing adjacent sensors.
Specular Reflection Sensor reads "out of range" despite an object being directly in front. Smooth, hard surfaces (glass, polished metal) angled > 15° act like mirrors, bouncing the 40 kHz wave away from the receiver. Add acoustic dampening foam to the transducer rims to narrow the beam, or use multiple sensors at offset angles.
Thermal Gradients Distance readings drift slowly over time without object movement. Hot air rising from a heater or CPU creates a refractive index gradient, bending the sound wave path. Mount sensors away from HVAC vents, power supplies, and direct sunlight. Poll a local thermistor for math compensation.

Finally, if you are using the waterproof JSN-SR04T variant with the separate 2.5mm transducer probe, be aware that its internal ASIC requires a slightly longer trigger pulse. While the standard HC-SR04 fires reliably on a 10 µs trigger, the JSN-SR04T often requires 20 µs to reliably initiate the burst. Always consult the specific datasheet for your module's exact timing IC, as cheap clones frequently swap the underlying microcontroller without updating the silkscreen.