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