Разные условия включения розеток для дня и ночи

Juzzo
Offline
Зарегистрирован: 06.03.2018

Хочу сделать прибор, котрый будет автоматически следить за климатом в теплице. Есть готовый скетч либо для дня либо для ночи. Нужно сделать так, чтобы днем условия для включения розеток были одни, а ночью другие, и при этом был цикл (12 часов дня 12 часов ночи). Подскажите как это сделать?

Вот сам код:

#include <TimeAlarms.h> // Подключаем библиотеку для работы с таймерами
#include <DHT.h> // Подключаем библиотеку для работы с датчиками температуры/влажности на базе чипов AM23xx
#define DHTPIN 12 // Цифровой пин, к которому подключен датчик тепрературы/влажности (12 = D12)
#define DHTTYPE DHT22 // Модель датчика (AM2301 = DHT21, AM2302 и AM2321 = DHT22)
// Релейные модули, в зависимости от модели, включаются либо высоким, либо низким уровнем на порте.
#define S_ON 0 // Значение пина для ВКЛЮЧЕНИЯ розетки
#define S_OFF 1 // Значение пина для ВЫКЛЮЧЕНИЯ розетки
// Режим включения нагрузки
#define NO_ACTION 0 // Значение датчика не учитывается
#define IN_RANGE 1 // Включать нагрузку, когда значение В ПРЕДЕЛАХ диапазона
#define OUT_RANGE 2 // Включать нагрузку, когда значение ВНЕ ПРЕДЕЛОВ диапазона
// Определяем структуру, в которой содержатся условия для подключения розетки.
typedef struct RunCondition {
  int socketPin; // Пин, который управляет розеткой
  float tempBegin; // Температура. Начало диапазона.
  float tempEnd; // Температура. Конец диапазона.
  int tempMode; // Режим включения нагрузки по температуре
  float humBegin; // Влажность. Начало диапазона.
  float humEnd; // Влажность. Конец диапазона.
  int humMode; // Режим включения нагрузки по влажности.
};
#define NUM_SOCKETS 5 // Количество розеток в системе
// Определяем массив структур, определяющих условия для 3-х розеток (нумерация с 0 по 2)
RunCondition sockets[NUM_SOCKETS] = {
  {
    2, // Розетка №1: Приточный вентилятор. Управляющий пин - D2.
    0.0, // Минимальная температура
    0.0, // Максимальная температура
    IN_RANGE,
    0.0,
    0.0,
    NO_ACTION // Влажность не учитывается
  },
    {
    3, // Розетка №2: Обогреватель. Управляющий пин - D3.
    0.0, // Минимальная температура
    0.0, // Максимальная температура
    IN_RANGE,
    0.0, // Минимальная влажность
    0.0, // Максимальная влажность
    IN_RANGE
  },
  {
    4, // Розетка №3: Тепловентилятор. Управляющий пин - D3.
    0.0, // Минимальная температура
    0.0, // Максимальная температура
    IN_RANGE,
    0.0, // Минимальная влажность
    0.0, // Максимальная влажность
    IN_RANGE 
  },
  {
    5, // Розетка №4: Кондиционер. Управляющий пин - D4.
    0.0, // Минимальная температура
    0.0, // Максимальная температура
    IN_RANGE,
    0.0,
    0.0,
    NO_ACTION // Влажность не учитывается
  }
  {
    6, // Розетка №5: Увлажнитель. Управляющий пин - D4.
    0.0, // Минимальная температура
    0.0, // Максимальная температура
    NO_ACTION,
    0.0, // Минимальная влажность
    0.0, // Максимальная влажность
    IN_RANGE
  }
};
int socketStatus[NUM_SOCKETS]; // Определяем массив переменных, в которых хранится текущее состояние розеток. S_OFF - выключено, S_ON - включено.
DHT dht(DHTPIN, DHTTYPE); // Создаем объект для работы с датчиком
// Определяем глобальные переменные, в которых будем хранить показания датчиков
float temp = 0;
float hum = 0;
void setSockets() {// Эта функция устанавливает состояние розеток
  for (int i = 0; i < NUM_SOCKETS; i++) {// Перебираем все определенные ранее розетки, устанавливая для них соответствующий статус
    digitalWrite(sockets[i].socketPin, socketStatus[i]);
  }
}
void printSensors() {// Эта функция выводит в консоль состояние датчиков для помощи при отладке.
  Serial.print("[ >> ] Temperature: ");
  Serial.print(temp);
  Serial.print(" C;\tHumidity: ");
  Serial.print(hum);
  Serial.println("%");
}
void setup() {// Эта функция выполняется один раз при включении контроллера.
  Serial.begin(115200); // Подключаем COM-порт для вывода информации из контроллера.
  Serial.println("Climate control");
  dht.begin(); // Инициализируем датчик температуры/влажности.
  for (int i = 0; i < NUM_SOCKETS; i++) {socketStatus[i] = S_OFF; // Устанавливаем розетку в ВЫКЛЮЧЕНО по умолчаниюp
  inMode(sockets[i].socketPin, OUTPUT); // Переключаем управляющие пины всех определенных ранее розеток в режим "выход"}
  setSockets(); // Переводим розетки в состояние по умолчанию
  Alarm.timerRepeat(5, printSensors); // Включаем таймер для запуска функции printSensors каждые 5 секунд.
}
void loop() {// Эта функция выполняется по бесконечному кругу. Здесь мы будем проверять показания датчиков и управлять нагрузками.
  Alarm.delay(1000); // Вносим задержку в 1 секунду, чтобы датчик успел передать предыдущие данные.
  temp = dht.readTemperature(); // Получаем текущую температуру.
  hum = dht.readHumidity(); // Получаем текущую влажность.
  if (isnan(temp) || isnan(hum)) {// Что-то пошло не так, потому что данные с датчика не поступают! Отключаем все нагрузки и возвращаемся в начало!
    for (int i = 0; i < NUM_SOCKETS; i++) socketStatus[i] = S_OFF;
    setSockets(); 
    Serial.println("[FAIL] Can't read sensor data! Turn everithing OFF!");
    return;
  }// Теперь сравним полученные данные с условиями, заданными для каждой розетки.
  for (int s = 0; s < NUM_SOCKETS; s++) {// Проверяем условия для включения розетки по датчику температуры.
    int tempStatus = S_OFF;
    switch (sockets[s].tempMode) {
      case NO_ACTION: tempStatus = S_ON;
        break;
      case IN_RANGE: if ((temp >= sockets[s].tempBegin) && (temp <= sockets[s].tempEnd)) tempStatus = S_ON;
        break;
      case OUT_RANGE: if ((temp <= sockets[s].tempBegin) || (temp >= sockets[s].tempEnd)) tempStatus = S_ON;
        break;
    }// Проверяем условия для включения розетки по датчику влажности
    int humStatus = S_OFF;
    switch (sockets[s].humMode) {
      case NO_ACTION: humStatus = S_ON;
        break;
      case IN_RANGE: if ((hum >= sockets[s].humBegin) && (hum <= sockets[s].humEnd)) humStatus = S_ON;
        break;
      case OUT_RANGE: if ((hum <= sockets[s].humBegin) || (hum >= sockets[s].humEnd)) humStatus = S_ON;
        break;
    }// Объединяем оба результата в один новый статус розетки.
    int newStatus = S_OFF;
    if ((tempStatus == S_ON) && (humStatus == S_ON)) newStatus = S_ON;
    if (socketStatus[s] != newStatus) { // Статус розетки изменился! Отправим сообщение об этом в консоль и установим новое значение.
      Serial.print("[ OK ] Socket #");
      Serial.print(s);
      Serial.print(" status has changed to ");
      Serial.println(newStatus);
      socketStatus[s] = newStatus;
    }// Обновляем статусы розеток.
    setSockets();
  }// Конец функции loop. Сейчас контроллер запустит ее снова.}
}
}

 

DenSyo
Offline
Зарегистрирован: 13.01.2017

завести второй массив RunCondition sockets2[NUM_SOCKETS], подключить часики или придумать иной способ получения текущего времени, и везде в коде где идет обращение к массиву sockets добавить проверку текущего времени и выбор одного из массивов в зависимости от него. дальнейшие подробности зависят от способа определения времени который вы выберите. 

и еще. вы не диодиками моргаете, а с серьезным током работаете. стройте алгоритм серьезнее. если программа принимает решение включить прибор, нет смысла его выключать ближайшие полчаса-час. соответственно, если прибор только выключили, дайте ему остыть. плюс датчики имеют погрешности, надо это учитывать. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

день ночь можно по датчику света определять

bwn
Offline
Зарегистрирован: 25.08.2014

MaksVV пишет:

день ночь можно по датчику света определять

Уху, особенно на Питерских широтах и выше. У меня в июне, в грозу днем, бывает темнее чем ночью.))))

MaksVV
Offline
Зарегистрирован: 06.08.2015

)