Kshitij

BLG-002

Building an Obstacle-Avoidance Robot from First Principles

How a simple Arduino Uno, an ultrasonic sensor, and interrupt-driven control taught me to think in real-time systems.

Starting from scratch

The obstacle-avoidance robot began as a way to understand sensor integration. No libraries, no abstractions — just reading pins, timing pulses, and deciding when to turn.

The ultrasonic sensor works by sending a sound pulse and measuring the return time. At 343 m/s (speed of sound), every microsecond of delay means about 0.17 mm of distance. Precision matters.

The interrupt problem

My first implementation polled the sensor continuously. It worked, but the main loop became a waiting game. When you’re trying to scan multiple sensors or respond to multiple events, blocking code becomes a bottleneck.

Interrupts fixed this. I wired the sensor to an interrupt pin and let the microcontroller handle timing in the background. The main loop could focus on control logic — steering, acceleration, decision-making.

volatile unsigned long pulseStart;
volatile unsigned long pulseDuration;

ISR(INT0_vect) {
  if (digitalRead(triggerPin) == HIGH) {
    pulseStart = micros();
  } else {
    pulseDuration = micros() - pulseStart;
  }
}

This pattern became the foundation for semi-autonomous systems later.

What it taught me

Real-time thinking isn’t just about fast code — it’s about understanding latency, predictability, and failure modes. A robot that sometimes responds in 10ms and sometimes in 500ms is unreliable. Consistency matters more than raw speed.