SCRU-FE: The Simplest Arduino Robot with Ultrasonic Sensor

SCRU-FE is a minimalistic and beginner-friendly mobile robot built around the Arduino UNO platform. With only essential components and a 3D-printed body, it demonstrates the core principles of robotics such as movement, sensing, and obstacle avoidance - without the need for complex wiring or programming.

The idea was taken from https://www.thingiverse.com/thing:780050

SCRU-FE is ideal for:

  • Educational workshops
  • First-time Arduino learners
  • Demonstrations of basic robotics principles
  • STEM classroom use
  • DIY hobbyist exploration

Advantages and Limitations:

Advantages:

  • Extremely simple construction
  • All structural parts are 3‑D printed
  • Uses only widely available components
  • So simple that no wiring diagram is required

Limitations:

  • No wheel encoders, so precise turns or distance tracking are impossible
  • Obstacle avoidance relies only on ultrasound; obstacles at sharp angles may be missed
  • Powered by disposable AA alkaline batteries

List of Components:

  • Arduino UNO board
  • L293D motor shield
  • HC-SR04 ultrasonic sensor
  • Gear motors (2×)
  • Servo motor (1×)
  • AA battery holders (2×)
  • 6× AA batteries
  • 65mm wheels (2×)
  • Third caster wheel
  • 3D-printed chassis
  • 3D-printed ultrasonic sensor mount ("head")
  • Power button
  • Capacitors (ceramic and electrolytic)
  • Screws and nuts
  • Jumper wires

List of Tools:

  • Soldering iron
  • Screwdrivers
  • Wire cutters/strippers
  • Hot glue gun
  • Zip tie (for mounting head)

Assembly Instructions:

SCRU-FE is so simple to build that no circuit diagram or manual is required. All connections are straightforward, and the mechanical parts are designed to fit intuitively. A full build video is available:

Notes:

  • Ceramic capacitors (typically 100nF) are soldered across the motor terminals to reduce electrical noise from brushes and improve EMI resistance.
  • Electrolytic capacitor (commonly 470µF or similar) is used across the main power line to stabilize voltage and compensate for current spikes during motor startup.

STL Files: Download all STL files for the chassis and head: scru-fe-stl-files.zip

Example Code:

Below is a basic sketch that can be extended with features such as smoother turning, servo sweeping, or adaptive response:

#include <AFMotor.h>
#include <Servo.h>

// Motor setup
AF_DCMotor motorLeft(4);   // Left motor on M4
AF_DCMotor motorRight(3);  // Right motor on M3

// Servo setup
Servo myServo;
#define SERVO_PIN 10

// Ultrasonic Sensor setup
#define TRIG_PIN A1
#define ECHO_PIN A0

void setup() {
  Serial.begin(9600);

  // Attach servo
  myServo.attach(SERVO_PIN);
  myServo.write(90);  // Center position

  // Set motor speed
  motorLeft.setSpeed(120);
  motorRight.setSpeed(120);

  // Ultrasonic pins
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  delay (3000);
}

long getDistance() {
  long sum = 0;
  int numReadings = 5;

  for (int i = 0; i < numReadings; i++) {
    digitalWrite(TRIG_PIN, LOW);
    delayMicroseconds(2);
    digitalWrite(TRIG_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIG_PIN, LOW);

    long duration = pulseIn(ECHO_PIN, HIGH, 30000);
    long distance = duration * 0.034 / 2;

    sum += distance;
    delay(10);
  }

  return sum / numReadings;
}

void moveForward() {
  motorLeft.run(FORWARD);
  motorRight.run(FORWARD);
}

void moveBackward() {
  motorLeft.run(BACKWARD);
  motorRight.run(BACKWARD);
}

void stopMotors() {
  motorLeft.run(RELEASE);
  motorRight.run(RELEASE);
}

void turnLeft() {
  motorLeft.run(BACKWARD);
  motorRight.run(FORWARD);
  delay(300);  // Adjust turning duration
  stopMotors();
}

void turnRight() {
  motorLeft.run(FORWARD);
  motorRight.run(BACKWARD);
  delay(300); // Adjust turning duration
  stopMotors();
}

void smoothServoMove(int targetAngle) {
  int currentAngle = myServo.read();  // Read the current servo position

  if (currentAngle < targetAngle) {
    for (int pos = currentAngle; pos <= targetAngle; pos += 2) {  // Move in small steps
      myServo.write(pos);
      delay(10);  // Adjust delay for speed
    }
  } else {
    for (int pos = currentAngle; pos >= targetAngle; pos -= 2) {  
      myServo.write(pos);
      delay(10);
    }
  }
}

void loop() {
  long distance = getDistance();
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  if (distance < 25) { 
      stopMotors();
      delay(1000);
    smoothServoMove(150);
    long leftDistance = getDistance();
    delay(250);
    smoothServoMove(30);
    long rightDistance = getDistance();
    delay(250);
    smoothServoMove(90);

    if (leftDistance > rightDistance) turnLeft(); 
    else { turnRight();}

    if (leftDistance == rightDistance) {
      moveBackward();
      delay(100);
      }
  } else {
    moveForward();
  }
}
Date: 22.06.2025