Плеко / Робототехніка
Урок 09 · Крок 1 / 10

Автоматичний шлагбаум

Іграшкова машинка наближається — картонна стріла підіймається. Після звільнення зони вона опускається.

  • Arduino Uno, макетна плата, HC-SR04, позиційний SG90 або MG90S 180° з важелем і гвинтом.
  • Окреме стабілізоване джерело 5 В для серво, дроти, USB для Uno.
  • Невелика коробка, тонкий картон або легка соломинка довжиною 10–15 см, скотч.
  • Іграшкова машинка, лінійка, плаский картон для відлуння.

Сервопривід безперервного обертання 360° тут не підходить: потрібно задавати положення стріли.

Перед зміною схеми від’єднай живлення. У Wokwi зупини симуляцію. Справжню схему перевір разом з учителем перед підключенням USB.

Повний код і файли проєкту

HC-SR04 керує положенням SG90; закриття після 3 секунд вільної зони.

#include <Arduino.h> // Основні команди плати.
#include <Servo.h> // Керування позиційним сервоприводом.

const byte TRIG_PIN = 7; // Команда датчику почати вимірювання.
const byte ECHO_PIN = 6; // Вхід тривалості відлуння.
const byte SERVO_PIN = 9; // Сигнальний дріт серво.
const int CLOSED_ANGLE = 10; // Закрите положення без тиску на крайній упор.
const int OPEN_ANGLE = 90; // Відкрите положення; звірити напрямок на своєму серво.
const float OPEN_CM = 15; // Відкриваємо на відстані до 15 см включно.
const float CLEAR_CM = 25; // Вважаємо зону вільною лише далі за 25 см.
const unsigned long CLEAR_MS = 3000; // Потрібні 3 секунди вільної зони.
Servo barrier; // Об’єкт керування стрілою.
bool isOpen = false; // Початково стріла закрита.
bool clearing = false; // Чи відраховуємо час вільної зони.
unsigned long clearAt = 0; // Початок безперервного вільного інтервалу.

float readDistanceCm() { // Повертаємо сантиметри або -1 при помилці.
  digitalWrite(TRIG_PIN, LOW); // Початковий низький рівень.
  delayMicroseconds(2); // Даємо сигналу стабілізуватися.
  digitalWrite(TRIG_PIN, HIGH); // Починаємо запуск вимірювання.
  delayMicroseconds(10); // Тримаємо імпульс 10 мікросекунд.
  digitalWrite(TRIG_PIN, LOW); // Завершуємо імпульс.
  unsigned long duration = pulseIn(ECHO_PIN, HIGH, 25000UL); // Чекаємо не довше 25 мс.
  float cm = duration / 58.0; // Час шляху звуку туди й назад переводимо в см.

  if (duration == 0 || cm < 2 || cm > 400) { // Немає надійного вимірювання.
    return -1; // Окреме значення помилки, а не нуль сантиметрів.
  }

  return cm; // Віддаємо виміряну відстань.
}

void setup() { // Підготовка після ввімкнення.
  pinMode(TRIG_PIN, OUTPUT); // TRIG надсилає імпульс.
  pinMode(ECHO_PIN, INPUT); // ECHO приймає імпульс.
  digitalWrite(TRIG_PIN, LOW); // До першого вимірювання тримаємо LOW.
  Serial.begin(115200); // Монітор порту для перевірки.
  barrier.write(CLOSED_ANGLE); // Заздалегідь задаємо початковий кут.
  barrier.attach(SERVO_PIN); // Починаємо надсилати імпульси на D9.
}

void loop() { // Перевіряємо наближення та звільнення зони.
  float cm = readDistanceCm(); // Отримуємо відстань або -1.
  unsigned long now = millis(); // Час після вимірювання.
  Serial.println(cm); // Показ для налаштування датчика.

  if (cm < 0) { // Невдале вимірювання не доводить, що проїзд вільний.
    clearing = false; // Скидаємо відлік закривання; стріла залишається на місці.
  } else if (cm <= OPEN_CM) { // Предмет близько.
    barrier.write(OPEN_ANGLE); // Підіймаємо стрілу.
    isOpen = true; // Зберігаємо відкрите положення.
    clearing = false; // Предмет знову поруч — відлік скасовано.
  } else if (isOpen && cm > CLEAR_CM) { // Відкритий шлагбаум і вільна зона.

    if (!clearing) { // Перший вимір у новому вільному інтервалі.
      clearAt = now; // Запам’ятовуємо його початок.
      clearing = true; // Вмикаємо відлік.
    }

    if (now - clearAt >= CLEAR_MS) { // Зона була вільна щонайменше 3 секунди.
      barrier.write(CLOSED_ANGLE); // Опускаємо легку стрілу.
      isOpen = false; // Зберігаємо закритий стан.
      clearing = false; // Завершуємо відлік.
    }

  } else { // Предмет у проміжній зоні або шлагбаум уже закритий.
    clearing = false; // Не накопичуємо час для закривання.
  }

  delay(100); // Пауза перед новим вимірюванням.
}

Wokwi потребує інтернету. Завантажений HTML-урок працює офлайн.