SCRU-FE: Найпростіший робот на Arduino

SCRU-FE - це мінімалістичний та дружній до новачків мобільний робот на базі Arduino UNO. Він складається лише з найнеобхідніших компонентів та показує основи робототехніки: рух та оминання перешкод. Дуже простий але деякі деталі треба надрукувати на 3D принтері.

Ідею було взято з https://www.thingiverse.com/thing:780050

Для чого це:

  • Проведення освітніх занять
  • Старт у світ роботів та Arduino
  • Створення STEM-проектів

Переваги та недоліки:

Переваги:

  • Дуже проста конструкція
  • Деталі шасі надруковані на 3D принтері
  • Використовуються поширені комплектуючі
  • Настільки простий, що не потребує схем підключення

Недоліки:

  • Немає енкодерів коліс, тому неможливо точно повертати та вимірювати пройдену відстань
  • Оминання перешкод лише ультразвуком, тому під кутом сенсор може не «бачити» об’єкт
  • Використовує лужні батарейки AA для живлення

Список деталей:

  • Плата Arduino UNO
  • Мотор шилд L293D
  • Ультразвуковий датчик HC-SR04
  • Мотор-редуктори (2×)
  • Серводвигун (1×)
  • Тримачі для батарейок типу АА (2×)
  • 6× батарейок типу АА
  • Колеса 65 мм (2×)
  • Третє колесо
  • Шасі, надруковане на 3D-принтері
  • Кріплення ультразвукового датчика ("голова"), надруковане на 3D-принтері
  • Кнопка живлення
  • Конденсатори (керамічні та електролітичні)
  • Гвинти та гайки
  • Дроти-перемички

Список інструментів:

  • Паяльник
  • Викрутки
  • Кусачки/інструменти для зняття ізоляції дроту
  • Клейовий пістолет
  • Стяжка (для монтажної головки)

Інструкція:

Цей робот такий простий, що інструкція не потрібна. Всі кроки збірки показані у відео:

Примітки:

  • Керамічні конденсатори (зазвичай 100нФ) припаюються до моторів для зменшення електричних перешкод і захисту від шумів.
  • Електролітичний конденсатор (наприклад, 470мкФ) встановлюється на лінії живлення для згладжування напруги та компенсації струмових стрибків при запуску моторів.

STL-файли:

Завантажити всі STL-файли для шасі, колеса та голови: scru-fe-stl-files.zip

Приклад коду:

Нижче наведено базовий код, який можна розширити такими функціями, як плавніше обертання, серво-зміщення або адаптивна реакція:

#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();
  }
}
Дата: 22.06.2025