Данный проект направлен на создание простого, но функционального автоматизированного устройства, которое самостоятельно регулирует микроклимат внутри миниатюрной теплицы. Используя недорогие электронные компоненты и микроконтроллер Arduino, мы моделируем систему, которая:

  • открывает или закрывает окно (или заслонку) в зависимости от температуры;
  • включает дополнительное освещение при недостатке солнечного света.

Этот проект сочетает датчики окружающей среды, исполнительные механизмы (сервомотор, светодиод) и логическое управление на микроконтроллере, что даёт реальное представление о том, как работает умная автоматика в сельском хозяйстве.

Кроме того, проект способствует развитию навыков в следующих областях:

  • проектирование систем на базе Arduino;
  • работа с аналоговыми и цифровыми сигналами;
  • программирование логики управления;
  • интерпретация физических показателей (температура, свет) и преобразование их в управляющие действия.

Таким образом, проект не только полезен в учебной среде, но и имеет потенциал практического применения в реальной жизни.

Компоненты, используемые в проекте

  1. Температурный датчик (например, TMP36, LM35 или DHT11)
    — измеряет температуру воздуха и передаёт данные на Arduino.
  2. Фоторезистор (LDR)
    — измеряет уровень освещённости.
  3. Сервомотор (например, SG90)
    — открывает или закрывает вентиляцию/окно, в зависимости от температуры.
  4. Светодиод (LED)
    — включает дополнительное освещение при низком уровне света.
  5. Arduino Uno
    — основной контроллер, обрабатывающий данные от датчиков и управляющий выходами.
  6. Резисторы, провода, макетная плата (breadboard), источник питания
    — стандартные элементы для сборки схемы.
#include <Servo.h>

// Определение пинов
const int tempPin = A0;
const int ldrPin = A1;
const int ledPin = 7;
const int servoPin = 9;
const int photoresistorPIN = A1;
int lightLevel, high = 0, low = 1023;

// Константы
const int LIGHT_THRESHOLD = 500;
const float TEMP_LOW = 5.0;
const float TEMP_HIGH = 10.0;

// Глобальные переменные
Servo greenhouseServo;
int currentServoAngle = 0;
float temperature = 0;
unsigned long previousServoMillis = 0;
const int servoInterval = 20;

void setup() {
  pinMode(ledPin, OUTPUT);
  greenhouseServo.attach(servoPin);
  greenhouseServo.write(currentServoAngle);
  Serial.begin(9600);
 
  // Тест LED
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin, LOW);
}

void loop()
{
  readTemperature();
  controlServo();
  int photoresistorVALUE = analogRead(photoresistorPIN);
  lightLevel = photoresistorVALUE;  
  autoTune();  // Настроим яркость по данным с фоторезистора
 
  // Управление LED на основе освещенности
  analogWrite(ledPin, 255 - lightLevel); // Инвертируем, так как чем больше света, тем меньше нужно светить
 

  Serial.print(photoresistorVALUE);
  Serial.println(lightLevel);
}

void autoTune() {
  // Настроим диапазон значений для фоторезистора
  if (lightLevel < low) low = lightLevel;
  if (lightLevel > high) high = lightLevel;

  lightLevel = map(lightLevel, low + 10, high - 30, 0, 255);
  lightLevel = constrain(lightLevel, 0, 255);
}

void readTemperature() {
  int reading = analogRead(tempPin);
  float voltage = reading * (5.0 / 1024.0);
  temperature = (voltage - 0.5) * 100;
 
  Serial.print(temperature);
}

void controlServo() {
  int targetAngle = currentServoAngle;
 
  if (temperature <= TEMP_LOW) {
    targetAngle = 0;
  }
  else if (temperature >= TEMP_HIGH) {
    targetAngle = 180;
  }

  if (millis() - previousServoMillis >= servoInterval) {
    previousServoMillis = millis();
   
    if (currentServoAngle < targetAngle) {
      currentServoAngle = min(currentServoAngle + 5, targetAngle);
    }
    else if (currentServoAngle > targetAngle) {
      currentServoAngle = max(currentServoAngle - 5, targetAngle);
    }
   
    greenhouseServo.write(currentServoAngle);
   
    Serial.println(currentServoAngle);
  }
}

Разбор кода

1. Подключение библиотеки

#include <Servo.h>

Подключает библиотеку для работы с сервомотором.

2. Объявление пинов и глобальных переменных

const int tempPin = A0;
const int ldrPin = A1;
const int ledPin = 7;
const int servoPin = 9;

  • tempPin — входной пин для температурного датчика.
  • ldrPin — пин для фоторезистора.
  • ledPin — выходной пин для управления LED.
  • servoPin — выходной пин для управления сервомотором.

3. Константы

const int LIGHT_THRESHOLD = 500;
const float TEMP_LOW = 5.0;
const float TEMP_HIGH = 10.0;

Эти значения определяют пороги, при которых система начинает действовать:

  • При температуре ≤ 5 °C — окно закроется.
  • При температуре ≥ 10 °C — окно откроется.

4. Инициализация компонентов

void setup() {
  pinMode(ledPin, OUTPUT);
  greenhouseServo.attach(servoPin);
  greenhouseServo.write(currentServoAngle);
  Serial.begin(9600);
 
  // Тест LED
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin, LOW);
}

  • Устанавливается режим работы пинов.
  • Сервомотор инициализируется и устанавливается в начальное положение (0°).
  • Запускается последовательный порт (Serial) для отладки.
  • Выполняется короткий тест светодиода.

5. Главный цикл программы

void loop() {
  readTemperature();       // Считывание температуры
  controlServo();          // Управление положением сервомотора
  int photoresistorVALUE = analogRead(photoresistorPIN); // Чтение с фоторезистора
  lightLevel = photoresistorVALUE;
  autoTune();              // Автоматическая калибровка диапазона освещённости
  analogWrite(ledPin, 255 - lightLevel);  // Управление яркостью LED

  Serial.print(photoresistorVALUE);
  Serial.println(lightLevel);
}

  • Чтение температуры и вызов функции управления серво.
  • Считывание текущего уровня освещённости.
  • Функция autoTune калибрует входящие данные от LDR (подробности ниже).
  • В зависимости от света LED становится ярче или тусклее.
  • Вывод данных на монитор порта (для отладки).

Подфункции

6. Чтение температуры

void readTemperature() {
  int reading = analogRead(tempPin);
  float voltage = reading * (5.0 / 1024.0);
  temperature = (voltage - 0.5) * 100;
 
  Serial.print(temperature);
}

  • Аналоговый сигнал преобразуется в напряжение.
  • Затем — в температуру (формула для TMP36).
  • Вывод температуры в Serial Monitor.

7. Плавное управление сервомотором

void controlServo() {
  int targetAngle = currentServoAngle;

  if (temperature <= TEMP_LOW) {
    targetAngle = 0;
  }
  else if (temperature >= TEMP_HIGH) {
    targetAngle = 180;
  }

  if (millis() - previousServoMillis >= servoInterval) {
    previousServoMillis = millis();

    if (currentServoAngle < targetAngle) {
      currentServoAngle = min(currentServoAngle + 5, targetAngle);
    }
    else if (currentServoAngle > targetAngle) {
      currentServoAngle = max(currentServoAngle - 5, targetAngle);
    }

    greenhouseServo.write(currentServoAngle);
    Serial.println(currentServoAngle);
  }
}

  • Определяет целевой угол в зависимости от температуры.
  • Плавно (шагами по 5°) изменяет угол, чтобы движение сервомотора было плавным, а не резким.
  • Ограничивает частоту обновления через проверку времени (millis()).

8. Автокалибровка освещённости

void autoTune() {
  if (lightLevel < low) low = lightLevel;
  if (lightLevel > high) high = lightLevel;

  lightLevel = map(lightLevel, low + 10, high - 30, 0, 255);
  lightLevel = constrain(lightLevel, 0, 255);
}

  • Автоматически настраивает минимальные и максимальные значения освещённости.
  • Использует map() и constrain() для нормализации значения lightLevel от 0 до 255.
  • Это нужно, чтобы подстроиться под разные условия освещения (например, разная погода).

Выводы

  • Код функциональный и работоспособный.
  • Основные цели проекта — реакция на температуру и освещение — реализованы.
  • Можно доработать:
    • температурные пороги;
    • использовать map() для расчёта угла серво на основе температуры (например: map(temp, 20, 30, 0, 180)).