Модуль 8 — Фінальний проєкт (курс для початківців)

Мета модуля: застосувати всі отримані знання та навички для створення завершеного пристрою на Arduino, який включає щонайменше один датчик, один виконавчий пристрій та систему виводу інформації.


Завдання

Необхідно зібрати пристрій, який використовує:

  • Щонайменше 1 датчик (температури, вологості, освітленості, руху тощо)
  • Щонайменше 1 виконавчий пристрій (світлодіод, мотор, реле)
  • Вивід інформації (світлодіоди або дисплей)

Можливі проєкти

1. Міні-метеостанція

Датчик: DHT11 або DHT22 (температура та вологість)
Вивід інформації: LCD 1602 або OLED дисплей
Виконавчий пристрій: світлодіод, що загоряється при перевищенні температури

#include <DHT.h>
#include <LiquidCrystal_I2C.h>

DHT dht(2, DHT11);
LiquidCrystal_I2C lcd(0x27, 16, 2);
int ledPin = 7;

void setup() {
  dht.begin();
  lcd.init();
  lcd.backlight();
  pinMode(ledPin, OUTPUT);
}

void loop() {
  float t = dht.readTemperature();
  float h = dht.readHumidity();

  lcd.setCursor(0,0);
  lcd.print("Temp: "); lcd.print(t); lcd.print("C");
  lcd.setCursor(0,1);
  lcd.print("Hum: "); lcd.print(h); lcd.print("%");

  if (t > 28) digitalWrite(ledPin, HIGH);
  else digitalWrite(ledPin, LOW);

  delay(2000);
}

2. Автоматична годівниця

Ідея: пристрій у заданий час відкриває кришку кормового відсіку за допомогою сервоприводу. DS3231 забезпечує точний час, LED або LCD показує статус та час наступної годівлі.

Комплектуючі

Компонент Примітка
Arduino Uno/Nano Контролер
RTC DS3231 (I2C) Точний модуль годинника; адреса I2C зазвичай 0x68
Сервопривід SG90/MG90S Відкривання кришки/заслінки
LED + резистор 220–330 Ω Індикація видачі корму
(Опційно) LCD 1602 I2C Вивід часу та статусу
Окремий БЖ 5 В ≥ 1 А Живлення сервоприводу (загальна «земля»)
Дроти, макетна плата, кріплення Монтаж

Підключення

  • DS3231: VCC → 5V, GND → GND, SDA → A4, SCL → A5 (для Uno/Nano).
  • Сервопривід: червоний → +5V БЖ, коричневий/чорний → GND (спільний з Arduino), помаранчевий/жовтий (сигнал) → D9.
  • LED: через резистор до D7, другий вивід на GND.
  • LCD 1602 I2C (опц.): VCC → 5V, GND → GND, SDA → A4, SCL → A5.

Важливо: сервопривід живити від окремого 5В джерела. GND БЖ та GND Arduino мають бути з’єднані.

Логіка роботи

  1. Після старту пристрій зчитує поточний час з DS3231.
  2. У масиві задано кілька щоденних годівель (наприклад, 08:00 та 19:30).
  3. Щохвилини пристрій порівнює час; при збігу:
    • вмикається LED-індикація,
    • сервопривід плавно відкриває заслінку, витримує паузу, закриває,
    • на LCD оновлюється «Наст. годівля».

Скетч Arduino

#include <Wire.h>#include <RTClib.h>#include <Servo.h>#include <LiquidCrystal_I2C.h>// ===== НАЛАШТУВАННЯ =====const int SERVO_PIN = 9;const int LED_PIN   = 7;const int OPEN_ANGLE  = 100;   // кут відкриття заслінкиconst int CLOSE_ANGLE = 0;     // кут закриттяconst int OPEN_MS     = 1500;  // скільки тримати відкритою, мс// Час годівель (24-годинний формат)const uint8_t FEEDS = 2;uint8_t feedHour[FEEDS]   = {8, 19};uint8_t feedMinute[FEEDS] = {0, 30};// ===== ОБ’ЄКТИ =====RTC_DS3231 rtc;Servo gate;LiquidCrystal_I2C lcd(0x27, 16, 2);bool fedThisMinute[FEEDS] = {false, false};void setup() {  pinMode(LED_PIN, OUTPUT);  digitalWrite(LED_PIN, LOW);  gate.attach(SERVO_PIN);  gate.write(CLOSE_ANGLE);  Wire.begin();  rtc.begin();  // *** Одноразово раскоментуйте для синхронізації з ПК:  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));  lcd.init(); lcd.backlight();  lcd.setCursor(0,0); lcd.print("Auto Feeder");  lcd.setCursor(0,1); lcd.print("Init...");  delay(800);  updateNextFeedOnLCD();}void loop() {  DateTime now = rtc.now();  static int lastMinute = -1;  if (now.minute() != lastMinute) {    lastMinute = now.minute();    for (uint8_t i = 0; i < FEEDS; i++) fedThisMinute[i] = false;    updateNextFeedOnLCD(now);  }  for (uint8_t i = 0; i < FEEDS; i++) {    if (!fedThisMinute[i] &&        now.hour() == feedHour[i] &&        now.minute() == feedMinute[i]) {      performFeeding(i);      fedThisMinute[i] = true;    }  }  delay(200);}void performFeeding(uint8_t idx) {  digitalWrite(LED_PIN, HIGH);  lcd.clear();  lcd.setCursor(0,0); lcd.print("Feeding #"); lcd.print(idx+1);  lcd.setCursor(0,1); lcd.print("Opening...");  for (int a = CLOSE_ANGLE; a <= OPEN_ANGLE; a += 3) {    gate.write(a);    delay(15);  }  delay(OPEN_MS);  for (int a = OPEN_ANGLE; a >= CLOSE_ANGLE; a -= 3) {    gate.write(a);    delay(15);  }  digitalWrite(LED_PIN, LOW);  updateNextFeedOnLCD();}void updateNextFeedOnLCD() {  updateNextFeedOnLCD(rtc.now());}void updateNextFeedOnLCD(const DateTime &now) {  int best = -1;  long bestDelta = 24L*60L + 1;  long curMin = now.hour()*60L + now.minute();  for (uint8_t i = 0; i < FEEDS; i++) {    long t = feedHour[i]*60L + feedMinute[i];    long delta = t - curMin;    if (delta < 0) delta += 24L*60L;    if (delta < bestDelta) { bestDelta = delta; best = i; }  }  char buf[6];  sprintf(buf, "%02d:%02d", feedHour[best], feedMinute[best]);  lcd.clear();  lcd.setCursor(0,0); lcd.print("Next feed:");  lcd.setCursor(0,1); lcd.print(buf);}

Як змінити розклад

У верхній частині скетчу змініть масиви feedHour[] та feedMinute[]. Кількість годівель задається константою FEEDS.

Механіка та калібрування

  • Використовуйте заслінку з мінімальним тертям. Для важчих заслінок — металевий сервопривід (MG90S) або редукторний.
  • Підберіть кути OPEN_ANGLE/CLOSE_ANGLE, щоб отвір відкривався повністю, але серво не впирався.
  • Налаштовуйте OPEN_MS для досягнення потрібної порції корму.

Безпека та надійність

  • Живіть серво від окремого 5В блока ≥ 1 А. Обов’язково з’єднайте GND з Arduino.
  • Додайте електроліт 470–1000 мкФ біля серво для стабільності.
  • Додайте кнопку «ручного режиму» для тестів.
  • Пружина на закриття допоможе уникнути перевантажень.

Поширені помилки

  • Arduino перезавантажується: слабкий блок живлення, спільна лінія живлення серво та контролера.
  • Час «пливе»: не ініціалізовано DS3231. Використайте rtc.adjust(...) один раз.
  • Серво не рухається: неправильне підключення або кути.

Розширення

  • Меню на LCD для зміни часу без перепрошивки.
  • Ваговий датчик HX711 для порційної видачі.
  • Надсилання повідомлень у Telegram/MQTT (ESP8266/ESP32).

3. Сигналізація на рух

Ідея: при виявленні руху PIR-датчиком (наприклад, HC-SR501) пристрій вмикає сирену (або лампу через реле), блимає світлодіодом та виводить попередження на дисплей.

Комплектуючі

КомпонентПризначення / примітка
Arduino Uno/NanoКонтролер системи
PIR HC-SR501Вихід OUT — цифровий сигнал HIGH при русі; на платі є регулятори чутливості та часу утримання
Модуль реле 5 ВКерування лампою/сиреною. Краще взяти реле-модуль з оптронами
Світлодіод + резистор 220–330 ΩІндикація тривоги
(Опц.) LCD 1602 I2CТекстові повідомлення: «Охорона», «Рух», «Тривога»
БЖ 5 В ≥ 1 АСтабільне живлення, спільна земля для всіх модулів
Дроти, макетна плата/корпусМонтаж та безпечне розміщення

Схема підключення

  • PIR: VCC → 5V, GND → GND, OUT → D2.
  • Реле: IN → D8, VCC → 5V, GND → GND. НО/НЗ контакти реле підключаються до вашого навантаження (сирена/лампа). З мережевою напругою працюйте лише при наявності навичок і дотриманні ПУЕ!
  • LED: через резистор до D13 (або іншого піна), другий вивід → GND.
  • LCD 1602 I2C (опц.): VCC → 5V, GND → GND, SDA → A4, SCL → A5.

Порада: на PIR-модулі встановіть режим H (повторний) для стабільної роботи тривоги та підберіть регуляторами чутливість і час утримання.

Логіка роботи

  1. Система має два стани: Охорона увімкнена (ARMED) та вимкнена (DISARMED). Для простоти стартуємо в ARMED.
  2. Фіксація руху (OUT=HIGH) → затримка фільтрації (дребезг/помилкові) → Тривога: увімкнути реле/сирену, мигати LED, показати попередження.
  3. Після тривоги — охолодження (cooldown), щоб уникнути безперервних спрацювань.
  4. (Опц.) Кнопкою можна перемикати ARMED/DISARMED; тут опущено для стислості.

Базовий скетч (з підтримкою LCD за прапорцем)

#include <Wire.h>
#include <LiquidCrystal_I2C.h> // якщо дисплея немає, встановіть USE_LCD false

// ====== НАЛАШТУВАННЯ ======
const bool USE_LCD = true;          // поставити false, якщо LCD немає
const uint8_t PIR_PIN   = 2;        // вхід PIR
const uint8_t RELAY_PIN = 8;        // вихід на реле
const uint8_t LED_PIN   = 13;       // індикація тривоги

// затримки, мс
const unsigned long TRIGGER_FILTER_MS = 80;    // антифальшивий фільтр
const unsigned long ALARM_DURATION_MS = 10000; // тривалість тривоги
const unsigned long COOLDOWN_MS       = 5000;  // пауза після тривоги

LiquidCrystal_I2C lcd(0x27, 16, 2);

enum State { ARMED, ALARM, COOLDOWN };
State state = ARMED;

unsigned long tState = 0;           // таймер поточного стану
unsigned long tMotionStart = 0;     // таймер підтвердження руху

void lcdInitIfUsed() {
  if (!USE_LCD) return;
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0,0); lcd.print("PIR Security");
  lcd.setCursor(0,1); lcd.print("ARMED");
}

void lcdShow(const char* l1, const char* l2) {
  if (!USE_LCD) return;
  lcd.clear();
  lcd.setCursor(0,0); lcd.print(l1);
  lcd.setCursor(0,1); lcd.print(l2);
}

void setup() {
  pinMode(PIR_PIN,   INPUT);       
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(LED_PIN,   OUTPUT);

  digitalWrite(RELAY_PIN, LOW);
  digitalWrite(LED_PIN,   LOW);

  lcdInitIfUsed();
}

void loop() {
  bool motion = digitalRead(PIR_PIN) == HIGH;
  unsigned long now = millis();

  switch (state) {
    case ARMED:
      if (motion) {
        if (tMotionStart == 0) tMotionStart = now;
        if (now - tMotionStart >= TRIGGER_FILTER_MS) {
          digitalWrite(RELAY_PIN, HIGH);  
          lcdShow("ALARM!", "Motion detect");
          tState = now;
          state = ALARM;
        }
      } else {
        tMotionStart = 0;
        digitalWrite(LED_PIN, (now/500)%2);
        if (USE_LCD && (now/2000)%2==0) lcdShow("ARMED", "Waiting motion");
      }
      break;

    case ALARM:
      digitalWrite(LED_PIN, (now/150)%2);
      if (now - tState >= ALARM_DURATION_MS) {
        digitalWrite(RELAY_PIN, LOW);
        digitalWrite(LED_PIN, LOW);
        lcdShow("COOLDOWN", "Please wait...");
        tState = now;
        state = COOLDOWN;
      }
      break;

    case COOLDOWN:
      if (now - tState >= COOLDOWN_MS) {
        state = ARMED;
        tMotionStart = 0;
        lcdShow("ARMED", "Ready");
      }
      break;
  }
}

Як додати дисплей пізніше

Якщо хочете спочатку протестувати без екрана, встановіть USE_LCD = false — повідомлення просто не виводитимуться, інша логіка збережеться.

Рекомендації по налаштуванню PIR

  • Перемичку встановіть у режим H (Repeatable) — вихід залишається HIGH при безперервному русі.
  • Регулятор TIME задає тривалість утримання OUT=HIGH після спрацювання. Для системи з програмним таймером ставте середнє значення.
  • Регулятор SENS — чутливість. Зменште при хибних спрацюваннях.

Безпека

  • При роботі з мережевою напругою підключайте лампу/сирену лише через реле-модуль, дотримуючись ізоляції та відстаней. Корпус — негорючий.
  • Забезпечте спільну землю для Arduino, PIR та реле. Живлення беріть із запасом по струму.
  • Якщо замість реле використовується транзисторна схема для 12 В сирени — ставте зворотний діод паралельно котушці/навантаженню.

Розширення

  • Кнопка «Охорона»: перемикання ARMED/DISARMED (наприклад, пін D4 з INPUT_PULLUP).
  • Запис подій: мітка часу з DS3231, вивід на LCD або в Serial.
  • Тиха тривога: замість сирени — лише підсвічування/повідомлення.
  • Сповіщення: відправка в Telegram/MQTT (ESP8266/ESP32).

Типові помилки

  • Сирена «дребезжить»: зменшіть чутливість PIR, збільште TRIGGER_FILTER_MS і/або ALARM_DURATION_MS.
  • LCD порожній: невірна адреса I2C. Проскануйте шину (часто 0x27 або 0x3F).
  • Реле клацає при старті: ініціалізуйте пін як OUTPUT і одразу ставте LOW.

План роботи

  1. Виберіть ідею проєкту.
  2. Складіть список необхідних компонентів.
  3. Зберіть схему на макетній платі.
  4. Напишіть і завантажте програму в Arduino.
  5. Протестуйте та усуньте помилки.
  6. За бажання — зберіть проєкт у корпусі.

Поради

  • Використовуйте вже вивчені модулі та команди.
  • Для фінального проєкту можна комбінувати кілька датчиків.
  • Обов’язково враховуйте живлення та безпеку пристрою.

Контрольні запитання

  1. Які три обов’язкові частини має містити фінальний проєкт?
  2. Як можна вдосконалити проєкт у майбутньому?
  3. Чим корисна відладка під час збірки?

Авторський курс з Arduino для початківців. Використання матеріалів на комерційних сайтах дозволяється з посиланням на джерело.

<< Проекти << Усі товари >> Статті, уроки >>

Написати відгук

Примітка: HTML размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Модуль 1 — Знайомство з Arduino: перше прошивання Blink і проєкт миготіння світлодіода

Модуль 1 — Знайомство з Arduino: перше прошивання Blink і проєкт миготіння світлодіода

Модуль 1 — Знайомство з Arduino (курс для початківців) Мета модуля: зрозуміти, що таке Arduino, в..

ESP32: Високоточні вимірювання сигналів за допомогою таймерів

ESP32: Високоточні вимірювання сигналів за допомогою таймерів

ESP32: Високоточні вимірювання сигналів за допомогою таймерів ESP32 оснащений потужними апаратним..

Світлодіод ультраяскравий 3мм

Світлодіод ультраяскравий 3мм

Над-яскравий світлодіод діаметром 3 ммКорпус прозорий в світлодіодів різного кольору світіння. Тобто..

0.99грн.

Цифровий датчик температури та вологості DHT11

Цифровий датчик температури та вологості DHT11

Вимірювання відносної вологості в межах 20 ... 90 %Точність вимірювання вологості ± 5,0 %RHВимірюван..

59.29грн.

Резистор змінний 1; 10; 200 кОм

Резистор змінний 1; 10; 200 кОм

Змінний резистор або потенціометр для встановлення на друковану плату. Опір налаштовується за допомо..

15.48грн.