Модуль 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 размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Arduino SIM800 управління реле за вихідним дзвінком

Arduino SIM800 управління реле за вихідним дзвінком

Пропоную вашій увазі приклад простого застосування можливостей SIM800 під час вихідного дзвінка. В р..

Кабель живлення 220В 2х0,75мм2

Кабель живлення 220В 2х0,75мм2

Мережевий кабель живлення 220ВПлоща перерізу дроту 0,75 мм2Довжина дроту 1,8 м..

35.63грн.

SMD світлодіод 0603

SMD світлодіод 0603

SMD світлодіоди видимого діапазону для поверхневого монтажу на плату Типорозмір 0603 Червоний 619 ..

2.10грн.

Модуль павербанка 4,2В на 2 USB виходи

Модуль павербанка 4,2В на 2 USB виходи

До цього модуля потрібно тільки підключити літій-іонний акумулятор 3,7-4,2В, закрити в корпус і гото..

133.25грн.

Модуль годинника реального часу DS1302

Модуль годинника реального часу DS1302

Модуль годин реального часу на основі мікросхеми DS1302 призначений для роботи з контролерами Ardu..

50.25грн.