Система контроля гроубокса. (столкнулся с проблемой)
- Войдите на сайт для отправки комментариев
До прочтения Вами всего что ниже, стоит учитывать:
1) я не программист
2) я не радиолюбитель
просто я воплощаю идею своими руками, и это крик о помощи.
В общем: решил для себя построить гроубокс, но так как график не нормированный, а живу я один, было принято решение автоматизировать его, на сколько этого требует ситуация. помозговав немного были поставлены задачи:
1. Включение/выключение света по времени, с выбором режима света (18/6, 20/4, 12/12...). ориентиры - часы с батарейкой. возможность указания начала цикла (во сколько начинать светить).
2. Полив по двум датчикам влажности. По умолчанию датчики должны быть обесточены ( иначе окисляются быстро). Опрос датчиков каждые n секунд. датчики должны колиброваться на минимум.
3. Тепмература и влажность воздуха. Сначала задумывал поставить увлажнитель воздуха, сейчас не знаю нужен ли. вытяжка все заберет.
После постановки задач решил покопаться по загашникам - чо есть, чо докупить =))
По итогам "ревизии" нашлось:
- дисплей LCD1602 (я решил что мне его хватит, исходя из размера)
- часы RTC_DS1302
- датчик влажности и температуры воздуха DHT11
- модуль реле 4 канала на 5v
-arduino nano v3
- корпус для устройства взял в строительном магазе
- с кнопками некая проблема (вообще не было времени их искать, купил какие нашел)
схематично указал, ибо у меня вопрос:
при включении реле полива (2 и 3 канал) наглухо виснут часы. Прям совсем, на дисплее висит - по факту тоже висит, батарея в порядке. помогает только полный ребут устройства. Источник тока - автомобильный кабель для регистратора, выдает полтора ампера. есть подозрение на просадку, ибо на форуме видел кто то жаловался на похожую ситуацию с этими часами, при переходе компьютера, от которого запитывается система, в режим сна.
Код:
#include <dht11.h>
#include <LiquidCrystal_I2C.h>
#include <iarduino_RTC.h>
#include <EEPROM.h>
iarduino_RTC time(RTC_DS1302,9,11,10);
LiquidCrystal_I2C lcd(0x3F,16,2);
#define PolivPower 4
#define Rele1Pin 5
#define Rele2Pin 6
#define Rele3Pin 7
#define Rele4Pin 8
#define DHT11_PIN 12
dht11 DHT11;
int buttonPin = A0;
int sensorPin1 = A2;
int sensorPin2 = A3;
int screensaver = 0;
int lightmenu = 0;
int hum = 0;
int tim = 0;
int tostart = 0;
int lightmode = 0;
int lmset = 0;
int dat1menu = 0;
int dat2menu = 0;
int minset = 0;
int houset = 0;
int mintimeset = 0;
int houtimeset = 0;
int dat1norm = 0;
int dat1min = 0;
int dat2norm = 0;
int dat2min = 0;
int Hit;
int Mit = 0;
int Sit = 0;
int Check;
int CheckHum;
unsigned long polivTime = 0;
unsigned long polivTime2 = 0;
long polivRange = 10000;
unsigned long sec = 3600; // количество секунд в часе
int Hi = 0; //Переменные настройки времени
int Mi = 0;
int Si = 0;
unsigned long TimeOn; //время включения по таймеру
unsigned long TimeOff; //время выключения по таймеру
unsigned long TimeAll = 86400; //всего времени
unsigned long Twake = 0; //время пробуждения
int Tcon; //коэфицент размера переменной относительно Tall
int dat1 = 0; //переменные датчиков влажности
int dat2 = 0;
int dat1vis = 000;
int dat2vis = 000;
int hum1min;
int hum1norm;
int hum2min;
int hum2norm;
String RegSvet; //Тектовое значение режима полива на экран
int reg; //перемення режима полива
int avalue=0; // переменная для сохранения значения датчика
int minvalue=220; // значение полного полива
int maxvalue=600; // значение критической сухости
unsigned long currentTime;
unsigned long LastCheckTime = 0;
unsigned long loopTime = 5000; //переменная интервала полива
unsigned long LoopToCheck = 0;
void setup()
{
lcd.init();
Serial.begin(9600);
lcd.backlight();
time.begin();
pinMode(Rele1Pin, OUTPUT);
pinMode(Rele2Pin, OUTPUT);
pinMode(Rele3Pin, OUTPUT);
pinMode(Rele4Pin, OUTPUT);
pinMode(PolivPower, OUTPUT);
digitalWrite(Rele1Pin, HIGH);
digitalWrite(Rele2Pin, HIGH);
digitalWrite(Rele3Pin, HIGH);
digitalWrite(Rele4Pin, HIGH);
digitalWrite(PolivPower, LOW);
currentTime = millis();
polivTime2 = currentTime;
polivTime = currentTime;
hum1norm = (EEPROM.read(1) * 4);
hum1min = (EEPROM.read(2) * 4);
hum2norm = (EEPROM.read(3) * 4);
hum2min = (EEPROM.read(4) * 4);
reg = EEPROM.read(5);
TimeOn = ((EEPROM.read(6))*sec);
Serial.println(TimeOn);
Check = 1;
CheckHum = 1;
}
int select = 0;
byte Key()
{
if (analogRead(0) < 200) return 1; //красная кнопка
else if (analogRead(0) < 400) return 3; //желтая кнопка
else if (analogRead(0) < 600) return 2; //зеленая кнопка
else if (analogRead(0) > 600) return 6; //еленая кнопка
}
void loop() {
currentTime = millis();
if (lightmenu == 0 && hum == 0 && tim == 0 && tostart == 0 && lightmode == 0 && lmset == 0 && dat1menu == 0 && dat2menu == 0 && minset == 0 && houset == 0 && mintimeset == 0 && houtimeset == 0 && dat1norm == 0 && dat2norm == 0 && dat1min == 0 && dat2min == 0) {
screensaver = 0;
}
else {
screensaver = 1;
}
//--------------------------------Check-------------------------------
if (Check == 1) {
Twake = (time.Hours*sec);
if (reg == 0) {
digitalWrite (Rele1Pin, HIGH); //вылючено реле света (1)
Tcon = 2;
}
else if (reg == 1) {
TimeOff = TimeOn + 43200;
if (TimeOff >= TimeAll) {
TimeOff = TimeOff - TimeAll;
Tcon = 1;
}
else {
Tcon = 0;
}
}
else if (reg == 2) {
TimeOff = TimeOn + 64800;
if (TimeOff >= TimeAll) {
TimeOff = TimeOff - TimeAll;
Tcon = 1;
}
else {
Tcon = 0;
}
}
else if (reg == 3) {
TimeOff = TimeOn + 72000;
if (TimeOff >= TimeAll) {
TimeOff = TimeOff - TimeAll;
Tcon = 1;
}
else {
Tcon = 0;
}
}
else if (reg == 4) {
digitalWrite (Rele1Pin, LOW); //включение
Tcon = 2;
}
if (Tcon == 1) {
if ((TimeOn <= Twake && Twake <= TimeAll) || (0 <= Twake && Twake <= (TimeOff))){
digitalWrite (Rele1Pin, LOW); //Включено реле света (1)
}
else {
digitalWrite (Rele1Pin, HIGH); //выключенно реле света (1)
}
}
if (Tcon == 0) {
if ((TimeOn <= Twake) && (Twake <= TimeOff)){
digitalWrite (Rele1Pin, LOW ); //Включено реле света (1)
}
else {
digitalWrite (Rele1Pin, HIGH); //выключенно реле света (1)
}
}
Serial.println(TimeOff);
Serial.println(Twake);
Serial.println(Check);
Serial.println(Tcon);
Serial.println(EEPROM.read(6));
Serial.println(sec);
Serial.println(Hit);
if (TimeOn == time.Hours * 3600 ) {
digitalWrite (Rele1Pin, HIGH); //Включено реле света (1)
}
if (TimeOff == time.Hours * 3600) {
digitalWrite (Rele1Pin, LOW); //выключенно реле света (1)
}
Check = 0;
}
//----------------------------------------------------Check End ---------------------------------------------------
//----------------------------------------------------Check Hum ---------------------------------------------------
if (CheckHum == 1) {
digitalWrite (PolivPower, HIGH);
delay(200);
dat1 = analogRead(sensorPin1);
dat1vis = dat1;
//delay(200);
dat2 = analogRead(sensorPin2);
dat2vis = dat2;
//delay(200);
digitalWrite (PolivPower, LOW);
//delay(200);
CheckHum = 0;
}
//================================================работа датчиков====================================================
if (currentTime >= (LoopToCheck + 30000)) {
CheckHum = 1;
if (hum1min <= dat1) {
digitalWrite(Rele2Pin, LOW);
polivTime = currentTime;
}
if (hum2min <= dat2) {
digitalWrite(Rele3Pin, LOW);
polivTime2 = currentTime;
}
LoopToCheck = currentTime;
}
//------------------------------------выключение клапанов----------
if (currentTime >= (polivTime + 10000)) {
digitalWrite(Rele2Pin, HIGH);
Serial.println(currentTime);
polivTime = (currentTime + 20000);
}
if (currentTime >= (polivTime2 + 10000)) {
digitalWrite(Rele3Pin, HIGH);
Serial.println(currentTime);
polivTime2 = (currentTime+20000);
}
//--------------------------------включение/выключение по времени---------------------------------------------------
if (TimeOn == time.Hours * 3600 ) {
digitalWrite (Rele1Pin, LOW); //Включено реле света (1)
}
if (TimeOff == time.Hours * 3600) {
digitalWrite (Rele1Pin, HIGH); //выключенно реле света (1)
}
//-----------------------------------Сброс минут и часов при установке timetostart -------------------
if (Hit >= 24){
Hit = 0;
}
if (Mit >=60) {
Mit = 0;
}
if (Hi >=24) {
Mi = 0;
}
if (Mi >=60) {
Mi = 0;
}
//-----------------------------------режимы света ----------------
if (reg == 0) {
RegSvet = "Off ";
}
else if (reg == 1){
RegSvet = "12/12";
}
else if (reg == 2) {
RegSvet = "18/6 ";
}
else if (reg == 3) {
RegSvet = "20/4 ";
}
else if (reg ==4) {
RegSvet = "On ";
}
//-----------------------------------MENU-------------------------
//-------------------------------первый уровень меню-----------------
if (lightmenu == 1) // первый экран первая страница и выбран 1 элемент
{
lcd.clear(); //очистка экрана
lcd.setCursor(0, 0);
lcd.print("->");
lcd.print("Light");
lcd.setCursor(0, 1);
lcd.print(" Hum. data");
delay(200);
}
if (hum == 1) // первый экран первая страница и выбран 2 элемент
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Light ");
lcd.setCursor(0, 1);
lcd.print("->");
lcd.print("Hum. data ");
delay(200);
}
if (tim == 1) // первый экран вторая страница и выбран 3 элемент
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("->");
lcd.print("Time ");
delay(200);
}
// __________________________Второй уровень меню______________________
// ______________________________LIGHT________________________________
if (tostart == 1) {
lcd.clear(); //очистка экрана
lcd.setCursor(0, 0);
lcd.print("->");
lcd.print("Time to start");
lcd.setCursor(0, 1);
lcd.print(" Light mode");
delay(200);
}
if (lightmode == 1) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Time to start ");
lcd.setCursor(0, 1);
lcd.print("->");
lcd.print("Light mode ");
delay(200);
}
//_______________________________HUM_____________________________________
if (dat1menu == 1) {
lcd.clear(); //очистка экрана
lcd.setCursor(0, 0);
lcd.print("->");
lcd.print("Calibr. 1 dat ");
lcd.setCursor(0, 1);
lcd.print(" Calibr. 2 dat ");
delay(200);
}
if (dat2menu == 1) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Calibr. 1 dat ");
lcd.setCursor(0, 1);
lcd.print("->");
lcd.print("Calibr. 2 dat ");
delay(200);
}
//_______________________________Time__________________________________
if (houtimeset == 1) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(5,0);
lcd.print(Hi);
lcd.setCursor(7,0);
lcd.print(":");
lcd.setCursor(8,0);
lcd.print(Mi);
lcd.setCursor(5,1);
lcd.print("HH");
lcd.setCursor(8,1);
lcd.print(" ");
delay(200);
}
if (mintimeset == 1) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(5,0);
lcd.print(Hi);
lcd.setCursor(7,0);
lcd.print(":");
lcd.setCursor(8,0);
lcd.print(Mi);
lcd.setCursor(5,1);
lcd.print(" ");
lcd.setCursor(8,1);
lcd.print("MM");
delay(200);
}
//--------------------------------tostartset-----------------------
if (houset == 1 ) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(5,0);
lcd.print(Hit);
lcd.setCursor(7,0);
lcd.print(":");
lcd.setCursor(8,0);
lcd.print(Mit);
lcd.setCursor(5,1);
lcd.print("HH");
lcd.setCursor(8,1);
lcd.print(" ");
delay(200);
}
if (minset == 1) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(5,0);
lcd.print(Hit);
lcd.setCursor(7,0);
lcd.print(":");
lcd.setCursor(8,0);
lcd.print(Mit);
lcd.setCursor(5,1);
lcd.print(" ");
lcd.setCursor(8,1);
lcd.print("MM");
delay(200);
}
//----------------------------------lightmode set---------------------
if (lmset == 1) {
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Light Mode");
lcd.setCursor(6,1);
lcd.print(RegSvet);
delay(200);
}
// ----------------------------------dat norm-------------------------
if (dat1norm == 1) {
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Select norm");
lcd.setCursor(7,1);
lcd.print(dat1);
lcd.setCursor(1,1);
lcd.print(hum1norm);
delay(200);
}
if (dat2norm == 1) {
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Select norm");
lcd.setCursor(7,1);
lcd.print(dat2);
lcd.setCursor(1,1);
lcd.print(hum2norm);
delay(200);
}
// ---------------------------------dat min--------------------------
if (dat1min == 1) {
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Select min");
lcd.setCursor(7,1);
lcd.print(dat1);
lcd.setCursor(1,1);
lcd.print(hum1min);
delay(200);
}
if (dat2min == 1) {
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Select min");
lcd.setCursor(7,1);
lcd.print(dat2);
lcd.setCursor(1,1);
lcd.print(hum2min);
delay(200);
}
//---------------------------------------------------------------------
//----------------------------действия с кнопками---------------------
switch (Key())
{
case 1: //красная
if (lightmenu == 1 || hum == 1 || tim == 1) {
lightmenu = 0;
hum = 0;
tim = 0;
tostart = 0;
lightmode = 0;
lmset = 0;
dat1menu = 0;
dat2menu = 0;
minset = 0;
houset = 0;
mintimeset = 0;
houtimeset = 0;
dat1norm = 0;
dat2norm = 0;
dat1min = 0;
dat2min = 0;
}
else if (tostart == 1) {
tostart = 0;
lightmenu = 1;
delay(50);
}
else if (lightmode == 1) {
lightmode = 0;
lightmenu = 1;
delay(50);
}
else if (lmset == 1) {
lmset = 0;
lightmode = 1;
Check = 1;
delay(50);
}
else if (dat1menu == 1) {
dat1menu = 0;
hum = 1;
delay(50);
}
else if (dat2menu == 1) {
dat2menu = 0;
hum = 1;
delay(50);
}
else if (houtimeset == 1) {
houtimeset = 0;
tim = 1;
delay(50);
}
else if (mintimeset == 1) {
mintimeset = 0;
houtimeset = 1;
delay(50);
}
else if (minset == 1) {
minset = 0;
tostart = 1;
delay(50);
}
else if (houset == 1) {
houset = 0;
minset = 1;
delay(50);
}
else if (dat1norm == 1) {
dat1norm = 0;
dat1menu = 1;
delay(50);
}
else if (dat1min == 1) {
dat1min = 0;
dat1menu = 1;
delay(50);
}
else if (dat2norm == 1) {
dat2norm = 0;
dat2menu = 1;
delay(50);
}
else if (dat2min == 1) {
dat2min = 0;
dat2menu = 1;
delay(50);
}
break;
case 2: //желтая
if (lightmenu == 1) {
lightmenu = 0;
hum = 1;
delay(50);
}
else if (hum == 1) {
hum = 0;
tim = 1;
delay(50);
}
else if (tim == 1) {
tim = 0;
lightmenu = 1;
delay(50);
}
else if (tostart == 1) {
tostart = 0;
lightmode = 1;
delay(50);
}
else if (lightmode == 1) {
lightmode = 0;
tostart = 1;
delay(50);
}
else if (dat1menu == 1) {
dat1menu = 0;
dat2menu = 1;
delay(50);
}
else if (dat2menu == 1) {
dat2menu = 0;
dat1menu = 1;
delay(50);
}
else if (mintimeset == 1) {
Mi = Mi + 1;
if (Mi >=60) {
Mi = 0;
}
delay(50);
}
else if (houtimeset == 1) {
Hi = Hi + 1;
if (Hi >=24) {
Hi = 0;
}
delay(50);
}
else if (minset == 1) {
Mit = Mit + 1;
if (Mit >=60) {
Mit = 0;
}
delay(50);
}
else if (houset == 1) {
Hit = Hit + 1;
if (Hit >=24) {
Hit = 0;
}
delay(50);
}
else if (dat1norm ==1) {
dat1norm = 0;
dat1min = 1;
delay(50);
}
else if (dat1min == 1) {
dat1min = 0;
dat1norm = 1;
delay(50);
}
else if (lmset == 1) {
reg = reg + 1;
EEPROM.write(5, reg);
if (reg >=5) {
reg = 0;
delay(200);
}
Check = 1;
delay(50);
}
else if (dat2norm ==1) {
dat2norm = 0;
dat2min = 1;
delay(50);
}
else if (dat2min == 1) {
dat2min = 0;
dat2norm = 1;
delay(50);
}
break;
case 3: //зеленая
if (lightmenu == 0 && hum == 0 && tim == 0 && tostart == 0 && lightmode == 0 && lmset == 0 && dat1menu == 0 && dat2menu == 0 && minset == 0 && houset == 0 && mintimeset == 0 && houtimeset == 0 && dat1norm == 0 && dat2norm == 0 && dat1min == 0 && dat2min == 0) {
lightmenu = 1;
delay(50);
}
else if (lightmenu == 1) {
lightmenu = 0;
tostart = 1;
delay(50);
}
else if (tostart == 1) {
tostart = 0;
houset = 1;
delay(50);
}
else if ( minset == 1) {
minset = 0;
houset = 1;
delay(50);
}
else if ( houset == 1) {
houset = 0;
TimeOn = Hit * 3600;
EEPROM.write(6, Hit);
Check = 1;
delay(50);
}
else if (lightmode == 1) {
lightmode = 0;
lmset = 1;
delay(50);
}
else if (hum == 1) {
hum = 0;
dat1menu = 1;
delay(50);
}
else if ( dat1menu == 1) {
dat1menu = 0;
dat1norm = 1;
delay(50);
}
else if ( dat1norm == 1 ) {
dat1norm = 0;
hum1norm = dat1;
EEPROM.write(1, hum1norm/4);
delay(50);
}
else if (dat1min == 1) {
dat1min = 0;
hum1min = dat1;
EEPROM.write(2, hum1min/4);
delay(50);
}
else if ( dat2menu == 1) {
dat2menu = 0;
dat2norm = 1;
delay(50);
}
else if ( dat2norm == 1 ) {
dat2norm = 0;
hum2norm = (dat2);
EEPROM.write(3, hum2norm/4);
delay(50);
}
else if (dat2min == 1) {
dat2min = 0;
hum2min = (dat2);
EEPROM.write(4, hum2min/4);
delay(50);
}
else if (tim == 1) {
tim = 0;
Hi = time.Hours;
Mi = time.minutes;
houtimeset = 1;
delay(50);
}
else if (houtimeset == 1) {
houtimeset = 0;
mintimeset = 1;
delay(50);
}
else if (mintimeset == 1) {
mintimeset = 0;
time.settime(Si,Mi,Hi);
Check = 1;
delay(50);
}
break;
}
//-----------------------------Screensaver (SS)------------------------
if (screensaver == 0) {
//---------------------------------Режим света-------------------
lcd.setCursor(11,1);
lcd.print(RegSvet);
delay(100);
//-------------------------------вывод времени-------------------
lcd.setCursor (8,0);
lcd.print(time.gettime("H:i:s"));
delay(100);
//----------------------------------------DHT-------------------
lcd.setCursor(0, 0);
lcd.print("T");
lcd.print(DHT11.temperature);
lcd.setCursor(3, 0);
lcd.print(" ");
lcd.setCursor(4, 0);
lcd.print("B");
lcd.print(DHT11.humidity);
lcd.setCursor(7, 0);
lcd.print(" ");
int chk;
// Мониторинг ошибок
chk = DHT11.read(DHT11_PIN); // Чтение данных
switch (chk){
case DHTLIB_OK:
break;
case DHTLIB_ERROR_CHECKSUM:
break;
case DHTLIB_ERROR_TIMEOUT:
break;
default:
break;
}
//---------------------------------датчики влажности------------------
if(millis()%2==0){ //датчики влажности
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(1, 1);
lcd.print(dat1vis);
lcd.setCursor(4, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print(dat2vis);
lcd.setCursor(9,1);
lcd.print(" ");
}
}
//--------------------------------------SS_END------------------------------

До прочтения Вами всего что ниже, стоит учитывать:
1) я не программист
2) я не радиолюбитель
А кто, если не секрет?
при включении реле полива (2 и 3 канал) наглухо виснут часы.
Помехи по питанию. Решений много, одно из них - искрогасящая RC-цепочка на выходах реле. Ещё одно - защитный диод. Ещё одно - опторазвязка. Да кучу решений фильтрации помех, в гугле тонны инфы, надо только вбить пару ключевых слов ;)
не секрет ) я занимаюсь тех. оснащением развлекательных мероприятий (свук, свет, лед экраны).
большое спасибо, ушел курить гугл )
В общем немного покурив Гугл, стало понятно, что нифига не понятно ) Если кому не влом, просто напишите что куда припаять ) мне так проще будет понять ) инфа по реле: замыкается 220В идущие к клапанам. потребление клапанов не знаю, но если я правильно понял то, что на них написано - 27 милиампер(?). фото клапана прилагаю
Гуглите снабберная цепь.
Мне помогло когда контроллер для электрокаменки делал. Тоже зависания были, обычно в момент размыкания пускателя.
Самый простой выход - заменить релюшки на твердотельные.
Не самый экономически выгодный варийант.
65 руб за шт. разве дорого? зато просто и надежно.
https://ru.aliexpress.com/item/2PCS-Lot-G3MB-202P-5VDC-G3MB-202P-5V-DC-AC-SSR-IN-5VDC-Out-240VAC-2A/32672489659.html?
Его релюшки с оптронами, надо арду и релюшки запитать от разных бп, или подать 12в на релюшки, а пять вольт сделать импульсным понижающим преобразователем, которым запитать все остальное.
А можно вышли библеотеки
здраствуй... а можно библиотеку?