Параметры включение розеток
- Войдите на сайт для отправки комментариев
Ср, 04/04/2018 - 23:29
Делаю авто климат контроль для теплицы, нашел в интеренете код, но в нем нет нужного мне режима, есть включить нагрузку, если температура в диапазоне и если температура не в диапазоне.
Хочу сделать так - включить, если температура достигла 25 и выключить розетку когда опуститься до 20 и т.п.
Подскажите как лучше сделать?
// Релейные модули, в зависимости от модели, включаются либо высоким, либо низким уровнем на порте.
#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 1 // Количество розеток в системе
// Определяем массив структур, определяющих условия для 3-х розеток (нумерация с 0 по 2)
RunCondition sockets[NUM_SOCKETS] = {
{
2, // Розетка №1: Приточный вентилятор. Управляющий пин - D2.
26.0, // Минимальная температура
28.0, // Максимальная температура
IN_RANGE, // Вентилятор включается, если температура более 0 градусов и менее 0
0.0,
0.0,
NO_ACTION // Влажность не учитывается
},
...
}// Теперь сравним полученные данные с условиями, заданными для каждой розетки.
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;
Весь код
#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.
26.0, // Минимальная температура
28.0, // Максимальная температура
IN_RANGE, // Вентилятор включается, если температура более 26 градусов и менее 28
0.0,
0.0,
NO_ACTION // Влажность не учитывается
},
{
3, // Розетка №2: Обогреватель. Управляющий пин - D3.
0.0, // Минимальная температура
26.5, // Максимальная температура
IN_RANGE, // Обогреватель включается, если температура больше 0 и меньше 26 градусов
0.0, // Минимальная влажность (в %)
100.0, // Максимальная влажность
IN_RANGE // Обогреватель включается, если влажность в диапазоне от 0% до 70%
},
{
4, // Розетка №3: Тепловентилятор. Управляющий пин - D3.
0.0, // Минимальная температура
26.5, // Максимальная температура
IN_RANGE, // Тепловентилятор включается, если температура больше 0 и меньше 26 градусов
60.0, // Минимальная влажность (в %)
100.0, // Максимальная влажность
IN_RANGE // Тепловентилятор включается, если влажность в диапазоне от 60% до 100%
},
{
5, // Розетка №4: Кондиционер. Управляющий пин - D4.
27.5, // Минимальная температура
50.0, // Максимальная температура
IN_RANGE, // Кондиционер включается, если температура в диапазоне от 27 до 50 градусов
0.0,
0.0,
NO_ACTION // Влажность не учитывается
}
{
6, // Розетка №5: Увлажнитель. Управляющий пин - D4.
0.0,
0.0,
NO_ACTION, // Температура не учитывается
0.0, // Минимальная влажность (в %)
70.0, // Максимальная влажность
IN_RANGE // Увлажнитель включается, если влажность в диапазоне от 0% до 70%
}
};
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. Сейчас контроллер запустит ее снова.}
}
}
это какой-то невероятно сложный код для столь элементарной задачи. Всего-то нужно - если писать на псевдокоде:
EСЛИ (Температура > 25) { включить розетку} EСЛИ (Температура < 20) { выключить розетку}Вместо розеток указываете управляющие пины реле, добавляете код измерения температуры - и скетч готов. Не думаю, что в нем будет больше 10-15 "активных"строк.
И не надо искать заумные примеры в инете...
Я изучаю этот код и немного вникаю в ардуино, учу из него переменные, он мне как родной)
case IN_RANGE: if (temp = sockets[s].tempBegin) tempStatus = S_ON; if (temp = sockets[s].tempEnd) tempStatus = S_OFF;Я изучаю этот код и немного вникаю в ардуино, учу из него переменные, он мне как родной)
case IN_RANGE: if (temp = sockets[s].tempBegin) tempStatus = S_ON; if (temp = sockets[s].tempEnd) tempStatus = S_OFF;откуда ж я знаю. Вы не написали, что что означают переменные и что должен делать этот код.
есть включить нагрузку, если температура в диапазоне и если температура не в диапазоне.
Хочу сделать так - включить, если температура достигла 25 и выключить розетку когда опуститься до 20
Чем отличается
"включить, если температура достигла 25 " ОТ "включить нагрузку, если температура в диапазоне 25-50"????
Всё, что Вам нужно в сети есть, просто осознайте нормально задачу и пользуйтесь.
и т.п.
Немедленно прекращйте всякую возню с кодом. Садитесь над бумажкой, чешите репу и расписывайте логику до тех пор, пока никаких "и т.п." не останется.
Вы никогда не запрограммируете задачу, логику которой не понимаете до конца.