Let’s build.
This is a design guide, not a complete wiring schematic. Pin mappings and firmware depend on your selected hardware.
Keep the robot chassis raised on bench stand during initial motor direction calibration. Have an accessible emergency battery switch.
Hardware Bill of Materials (BOM)
Circuit Wiring & Pin-to-Pin Connection Matrix
ESP32 GPIO 5 (D5)HC-SR04 Ultrasonic TRIGYellowSends 10µs ultrasonic start pulseESP32 GPIO 18 (D18)HC-SR04 Ultrasonic ECHOGreenReads high pulse duration for distance calculationESP32 GPIO 19 / 21L298N IN1 / IN2 (Left Motor)BlueControls Left Motor direction & PWM speedESP32 GPIO 22 / 23L298N IN3 / IN4 (Right Motor)PurpleControls Right Motor direction & PWM speedCommon Ground (GND)L298N GND & ESP32 GNDBlack (Heavy)Essential common ground loop across motor & logic railsStep-by-Step Assembly & Verification Guide
- 01
Define the behaviour: travel slowly and stop when an obstacle is close. Specify what happens when the sensor fails.
- 02
Choose a compatible controller, distance sensor, motor driver, two geared motors, chassis and protected low-voltage power supply.
- 03
Read each component’s voltage and current requirements. Draw a wiring plan using the manufacturer’s documentation.
- 04
Test the sensor alone. Record measurements at several known distances and note unreliable conditions.
- 05
Test the motor driver with the wheels raised. Add the stop behaviour, then test on a clear floor with an accessible power switch.
- 06
Publish your wiring diagram, parts list, code and test results in a community discussion.
Reference Firmware Sketch (CPP)
// iSpark Robotics: Autonomous Obstacle-Aware Rover Controller
// Microcontroller: ESP32 NodeMCU | Driver: L298N | Sensor: HC-SR04
#define TRIG_PIN 5
#define ECHO_PIN 18
#define MOTOR_LEFT_FWD 19
#define MOTOR_LEFT_REV 21
#define MOTOR_RIGHT_FWD 22
#define MOTOR_RIGHT_REV 23
#define OBSTACLE_DISTANCE_CM 25 // Safe standoff distance
long measureDistanceCM() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout
if (duration == 0) return 999; // Sensor fault guard
return duration * 0.034 / 2;
}
void stopMotors() {
digitalWrite(MOTOR_LEFT_FWD, LOW);
digitalWrite(MOTOR_LEFT_REV, LOW);
digitalWrite(MOTOR_RIGHT_FWD, LOW);
digitalWrite(MOTOR_RIGHT_REV, LOW);
}
void driveForward() {
digitalWrite(MOTOR_LEFT_FWD, HIGH);
digitalWrite(MOTOR_LEFT_REV, LOW);
digitalWrite(MOTOR_RIGHT_FWD, HIGH);
digitalWrite(MOTOR_RIGHT_REV, LOW);
}
void turnRight() {
digitalWrite(MOTOR_LEFT_FWD, HIGH);
digitalWrite(MOTOR_LEFT_REV, LOW);
digitalWrite(MOTOR_RIGHT_FWD, LOW);
digitalWrite(MOTOR_RIGHT_REV, HIGH);
}
void setup() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(MOTOR_LEFT_FWD, OUTPUT);
pinMode(MOTOR_LEFT_REV, OUTPUT);
pinMode(MOTOR_RIGHT_FWD, OUTPUT);
pinMode(MOTOR_RIGHT_REV, OUTPUT);
stopMotors();
Serial.begin(115200);
Serial.println("[iSpark Rover] Autonomous obstacle navigation initialized.");
}
void loop() {
long distance = measureDistanceCM();
Serial.printf("Clearance ahead: %ld cm\n", distance);
if (distance < OBSTACLE_DISTANCE_CM) {
Serial.println("Obstacle detected! Stopping and executing pivot turn...");
stopMotors();
delay(200);
turnRight();
delay(450);
stopMotors();
delay(100);
} else {
driveForward();
}
delay(50);
}An introductory learning resource, not an accredited qualification. Check the documentation for your exact hardware and work with appropriate supervision.

