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

Спочатку команда, потім механізм

Як це працює

Дві окремі перевірки

Спершу перевіряємо, чи програма видає правильні команди. Потім — чи механізм може виконати їх без упору. Важіль у повітрі показує логіку, але ще не доводить, що серво підніме кришку.

Петля несе кришку

Кришка спирається на власну петлю, а серво рухає її через тягу. Довжина тяги й точки кріплення впливають на потрібне зусилля та кути. Команди 60 і 120 поки лише дві цілі для вільного серво; готовій механіці можуть знадобитися інші перевірені значення.

Зроби

  1. Підготуй Uno, серво, кнопку, HC-SR04, макетну плату та джерело 5 V.
  2. Почни без кришки і тяги.
  3. Повтори центральне положення серво.

Очікуваний результат

Електроніку можна дослідити до виготовлення кріплення.

Що можна змінити

Для фізичної кришки потрібні перевірена петля, легка кришка і кріплення. До їх готовності демонструй положення важелем.

Як запустити у Wokwi або на платі

У Wokwi: відкрий новий Arduino Uno, перенеси diagram.json, sketch/sketch.ino та libraries.txt з ZIP потрібного кроку у відповідні вкладки, натисни ▶. На справжній платі спочатку перевір підключення з учителем. Кожен код замінює весь попередній скетч.

Схема підключення — відкрити

Підключення справжнього комплекту

Підключення: звір кожен дрітДжерело серво +5VВерхня шина +Джерело GNDВерхня шина −Uno GNDВерхня шина −Серво V+Верхня +, отвір 10Серво GNDВерхня −, отвір 11Серво сигналUno D9Два плюси розділені, GND спільний

На макетній платі верхня + — тільки джерело серво, нижня + — тільки Uno. Об’єднуємо мінусові шини. Перевір розриви шин; за потреби з’єднай половини тієї самої шини. У Wokwi верхня + живиться від Uno лише як спрощення. На справжній платі цей дріт заміни на +5 V окремого джерела; його мінус додай на верхню −.

Код цього кроку — відкрити й скопіювати

Повний код кроку 1

#include <Arduino.h>
#include <Servo.h>
const byte SERVO_PIN = 9;
const int ANGLE = 90; // Початковий кут без стріли
Servo arm;

void setup() {
  arm.write(ANGLE); // Задаємо початкове положення
  arm.attach(SERVO_PIN); // Сигнал керування через D9
}

void loop() {
}
Код, схема й бібліотека кроку 1 · ZIP
Повний код і файли проєкту

Від кнопки до датчика: відкривання та відлік перед закриванням.

#include <Arduino.h>
const byte TRIG_PIN = 7;
const byte ECHO_PIN = 6;
#include <Servo.h>
const byte SERVO_PIN = 9;
const int CLOSED_ANGLE = 60; // Звірити без тяги
const int OPEN_ANGLE = 120; // Звірити напрямок без тяги на своєму серво
const float OPEN_CM = 15; // Відкрити при 2–15 см
Servo arm;
const float CLEAR_CM = 25; // Далі цієї межі зона вільна
const unsigned long CLEAR_MS = 3000; // Безперервний вільний інтервал
bool isOpen = false;
bool clearing = false;
unsigned long clearAt = 0;

float readDistanceCm() {
  digitalWrite(TRIG_PIN, LOW); // Готуємо короткий імпульс
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH); // Запускаємо вимірювання
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  unsigned long echoUs = pulseIn(ECHO_PIN, HIGH, 25000UL);
  float cm = echoUs / 58.0; // Шлях туди й назад уже врахований

  if (echoUs == 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);
  Serial.begin(115200); // Така сама швидкість у моніторі
  arm.write(CLOSED_ANGLE);
  arm.attach(SERVO_PIN);
}

void loop() {
  float cm = readDistanceCm();

  if (cm < 0) {
    Serial.println("No echo");
  } else {
    Serial.print("Distance: ");
    Serial.print(cm, 1);
    Serial.println(" cm");
  }

  unsigned long now = millis(); // Час після вимірювання

  if (cm < 0) {
    clearing = false; // Помилка не означає вільну зону
  } else if (cm <= OPEN_CM) {
    arm.write(OPEN_ANGLE);
    isOpen = true;
    clearing = false;
  } else if (isOpen && cm > CLEAR_CM) {

    if (!clearing) {
      clearAt = now; // Початок нового вільного інтервалу
      clearing = true;
    }

    if (now - clearAt >= CLEAR_MS) {
      arm.write(CLOSED_ANGLE);
      isOpen = false;
      clearing = false;
    }

  } else {
    clearing = false; // Проміжна зона скасовує відлік
  }

  delay(100); // Нове вимірювання приблизно 10 разів/с
}

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