Реєстратор даних теплиці + автополив теплиці

Привіт, вирішив викласти своє творіння, черговий автополив в теплиці з записом даних на SD.

система поки тестується в горщику, навесні буду монтувати в теплицю.

читаючи на форумах про автополив, нічого цікавого на жаль не знайшов, люди прив'язуються до вологості грунту, як тільки вона висихає починають її поливати, в результаті коріння не розвиваються, біля коріння повинні бути стимул до зростання. Як поливати і коли це ціла наука. (Так до слова).

Природно для кожного городу, догляд за рослинами індивідуальний.

мій город в Лен області, багниста, торфянників, солца немає, вітру. Ну вобщем "це Пітер дитинко"

тому вирішив почати з запису даних на карту, для поледующего виведення графіка і аналізу даних.

провітрювання в теплиці скоріше за все буде окремо від системи, на гідропоршне.

а полив буде по таймеру і днях тижня.

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

дані записуються кожні 5 хв, новий фаил кожен день.

ну і полив через реле, час початку і час завершення + дні тижня.

в принципі в коді все зрозуміло, я новачок тому скетч виглядає смішно, але працює.

цікава ваша думка пропозиції і зауваження. в подальшому думаю додати датчик дощу.

і вже далі з аналізу даних прив'язувати полив до вологості температурі і тд.

може до речі кому і скетч знадобиться.

/ * Скетч для реєстрації даних теплиці + полив по таймеру код написаний любителем і можливо має ряд недоліків, але функціонал працює якщо у Вас є питання, зауваження і пропозиції за кодом надсилайте на пошту [email protected] в проекті використовуються датчики та модулі: dht - датчики вологості повітря і температури всередині і зовні датчик вологості грунту датчик світла датчик температури герметичний годинник реального часу модуль запису на SD arduino mega 2560 дисплей nextion реле * / #include <DHT.h> #include < OneWire.h> #include <DallasTemperature.h> #include <SPI.h> #include <SD.h> #include <Wire.h> #include <DS3231.h> #include <SoftwareSerial.h> #include <Nextion .h> SoftwareSerial nextion (11, 10); // Nextion TX to pin 11 and RX to pin 10 of Arduino Nextion myNextion (nextion, 9600); #define moisture_sensor A0 // датчик вологості грунту int very_moist_value = 200; // Показання датчика вологості грунту при дуже мокрому ґрунті (для калібрування процентного виведення) DHT dht1 (4, DHT22); // датчик влажносі і температури DHT dht2 (5, DHT11); // датчик влажносі і температури #define ONE_WIRE_BUS 3 // герметичний датчик температури // int photocellPin = A1; // датчик світла #define photocellPin A1 int photocellReading; long secund; long minut; long hor; String days; const int chipSelect = 53; // пін sd карти DS3231 clock; RTCDateTime dt; // const int ledPin = 2; // пін подачі живлення на датчики long secstar; long minstar; long horstar; long secfin; long minfin; long horfin; long Curent_Time; long Curent_Alarm_On1; long Curent_Alarm_Off1; boolean Monday = false; boolean Tuesday = false; boolean Wednesday = false; boolean Thursday = false; boolean Friday = false; boolean Saturday = false; boolean Sunday = false; boolean N = false; // чи є день тижня з встановленим зараз boolean W = false; // запис даних на sd карту в встановлені хвилини boolean G = false; // подача харчування на пін для датчиків у встановлені хвилини boolean z = false; // (delay для nextion крім моменту запису) OneWire oneWire (ONE_WIRE_BUS); // Повідомляємо бібліотеці про пристрій, що працює по протоколу 1-Wire DallasTemperature sensors (& oneWire); // Зв'язуємо функції бібліотеки DallasTemperature з нашим 1-Wire пристроєм (DS18B20) void setup () {sensors.begin (); dht1.begin (); dht2.begin (); // pinMode (ledPin, OUTPUT); pinMode (2, OUTPUT); // пін харчування датчиків pinMode (7, OUTPUT); // пін реле pinMode (8, OUTPUT); Serial.begin (9600); myNextion.init (); clock.begin (); {If (! SD.begin (chipSelect)) {myNextion.setComponentText ( "t3", "error"); } MyNextion.setComponentText ( "t3", "ready"); } // Set from UNIX timestamp // clock.setDateTime (1397408400); // Manual (YYYY, MM, DD, HH, II, SS // Set sketch compiling time //clock.setDateTime(__DATE__, __TIME__); // // clock.setDateTime (2016, 11, 30, 17, 54, 00);} void loop () {dt = clock.getDateTime (); secund = (dt.second); minut = (dt.minute); hor = (dt.hour); days = (clock.dateFormat ( "N ", dt)); Curent_Time = ((hor * 3600) + (minut * 60)) + secund; // поточний час Curent_Alarm_On1 = (horstar * 3600) + (minstar * 60) + secstar; // початок роботи реле Curent_Alarm_Off1 = (horfin * 3600) + (minfin * 60) + secfin; // завершення роботи реле {String message = myNextion.listen (); if (message! = "") {Serial.println (message);} // * ************************* функції кнопок таймера ********************** ************************ if (message == "65 1 5 1 ffff ffff ffff") {secstar ++;} if (message == "65 1 6 1 ffff ffff ffff ") {secstar--;} if (message ==" 65 1 3 1 ffff ffff ffff ") {minstar ++;} if (message ==" 65 1 4 1 ffff ffff ffff ") {mins tar--;} if (message == "65 1 f 1 ffff ffff ffff") {horstar ++;} if (message == "65 1 10 1 ffff ffff ffff") {horstar--; } If (message == "65 1 b 1 ffff ffff ffff") {secfin ++; } If (message == "65 1 c 1 ffff ffff ffff") {secfin--; } If (message == "65 1 9 1 ffff ffff ffff") {minfin ++; } If (message == "65 1 a 1 ffff ffff ffff") {minfin--; } If (message == "65 1 7 1 ffff ffff ffff") {horfin ++; } If (message == "65 1 8 1 ffff ffff ffff") {horfin--; } // **************************** режим роботи по днях тижня ************** ****************************** if ((message == "65 2 3 1 ffff ffff ffff")) {Monday = ! Monday; } If (Monday == true) {myNextion.sendCommand ( "b16.bco = 63488"); / Т} else if (Monday == false) {myNextion.sendCommand ( "b16.bco = 48631"); } If ((message == "65 2 4 1 ffff ffff ffff")) {Tuesday =! Tuesday; } If (Tuesday == true) {myNextion.sendCommand ( "b17.bco = 63488"); } Else if (Tuesday == false) {myNextion.sendCommand ( "b17.bco = 48631"); } If ((message == "65 2 5 1 ffff ffff ffff")) {Wednesday =! Wednesday; } If (Wednesday == true) {myNextion.sendCommand ( "b18.bco = 63488"); } Else if (Wednesday == false) {myNextion.sendCommand ( "b18.bco = 48631"); } If ((message == "65 2 6 1 ffff ffff ffff")) {Thursday =! Thursday; } If (Thursday == true) {myNextion.sendCommand ( "b19.bco = 63488"); } Else if (Thursday == false) {myNextion.sendCommand ( "b19.bco = 48631"); } If ((message == "65 2 7 1 ffff ffff ffff")) {Friday =! Friday; } If (Friday == true) {myNextion.sendCommand ( "b20.bco = 63488"); } Else if (Friday == false) {myNextion.sendCommand ( "b20.bco = 48631"); } If ((message == "65 2 8 1 ffff ffff ffff")) {Saturday =! Saturday; } If (Saturday == true) {myNextion.sendCommand ( "b21.bco = 63488"); } Else if (Saturday == false) {myNextion.sendCommand ( "b21.bco = 48631"); } If ((message == "65 2 9 1 ffff ffff ffff")) {Sunday =! Sunday; } If (Sunday == true) {myNextion.sendCommand ( "b22.bco = 63488"); } Else if (Sunday == false) {myNextion.sendCommand ( "b22.bco = 48631"); }} If (Curent_Time> = Curent_Alarm_On1 && Curent_Time <= Curent_Alarm_Off1 && N == true) {// включення реле за таймером (мабуть китайська версія починає працювати при LOW) digitalWrite (7, LOW); } Else {digitalWrite (7, HIGH); } // ****************************************** змінна на влюченія реле по днях тижня ************************************************ ******************** if ((days == "1") && (Monday == true)) {N = true; } Else if ((days == "2") && (Tuesday == true)) {N = true; } Else if ((days == "3") && (Wednesday == true)) {N = true; } Else if ((days == "4") && (Thursday == true)) {N = true; } Else if ((days == "5") && (Friday == true)) {N = true; } Else if ((days == "6") && (Saturday == true)) {N = true; } Else if ((days == "7") && (Sunday == true)) {N = true; } Else {N = false; } // *********************************** тут все зрозуміло ********* *********************************************** if (horstar > 23) {horstar = 0; } If (horfin> 23) {horfin = 0; } If (minstar> 59) {minstar = 0; } If (minfin> 59) {minfin = 0; } If (secstar> 59) {secstar = 0; } If (secfin> 59) {secfin = 0; } If (horstar <0) {horstar = 23; } If (horfin <0) {horfin = 23; } If (minstar <0) {minstar = 59; } If (minfin <0) {minfin = 59; } If (secstar <0) {secstar = 59; } If (secfin <00) {secfin = 59; } If ((minut == 59) || (minut == 04) || (minut == 9) || (minut == 14) || (minut == 19) || (minut == 24) | | (minut == 29) || (minut == 34) || (minut == 39) || (minut == 44) || (minut == 49) || (minut == 54)) {G = true; } Else {G = false; } If ((minut == 00) || (minut == 05) || (minut == 10) || (minut == 15) || (minut == 20) || (minut == 25) | | (minut == 30) || (minut == 35) || (minut == 40) || (minut == 45) || (minut == 50) || (minut == 55)) {W = true; } Else {W = false; } // ******************************* змінні датчиків ************** ***************************************** static int hh1; static int tt1; static int hh2; static int tt2; static int fff; static int hhh; static int ggg; // ************************************** функція читання змінних з датчиків ***** ************************************************* if ((secund == 57 && G == true) || (secund == 58 && G == true)) {boolean z = true; int moisture_value = analogRead (moisture_sensor); fff = map (moisture_value, very_moist_value, 1023, 100, 0); // Переводимо показання датчика вологості грунту в відсотки photocellReading = analogRead (photocellPin); hhh = photocellReading / 10; hh1 = dht1.readHumidity (); tt1 = dht1.readTemperature (); hh2 = dht2.readHumidity (); tt2 = dht2.readTemperature (); sensors.requestTemperatures (); ggg = (sensors.getTempCByIndex (0)); } Else {boolean z = false; } // ****************************** включення Піна подачі живлення на датчики (досвідченим шляхом встановлення, що для стабілізації живлення для читання , необхідно 3 секунди) ********************************************* ********* if ((secund == 56 && G == true) || (secund == 57 && G == true) || (secund == 58 && G == true)) { digitalWrite (2, HIGH); } Else {digitalWrite (2, LOW); } // ******************************* запис даних на SD карту *********** ******************************************* if (secund == 00 && W == true) {boolean z = true; String dataString = String (clock.dateFormat ( "H: i: s", dt)) + "," + String (hhh) + "," + String (fff) + "," + String (hh2) + ", "+ String (tt2) +", "+ String (hh1) +", "+ String (tt1) +", "+ String (ggg); String dat = String (clock.dateFormat ( "d_m_y", dt)) + ".csv"; // кожен день новий фаил File dataFile = SD.open (dat, FILE_WRITE); if (dataFile) {delay (740); // затримка на запис (для запису в межах секунди) dataFile.println (dataString); dataFile.close (); myNextion.setComponentText ( "t1", "Rec"); }} Else {myNextion.setComponentText ( "t1", "NO Rec"); boolean z = false; } MyNextion.setComponentText ( "t12", String (secstar)); myNextion.setComponentText ( "t11", String (minstar)); myNextion.setComponentText ( "t10", String (horstar)); myNextion.setComponentText ( "t15", String (secfin)); myNextion.setComponentText ( "t14", String (minfin)); myNextion.setComponentText ( "t13", String (horfin)); myNextion.setComponentText ( "t7", String (fff)); myNextion.setComponentText ( "t0", String (hhh)); myNextion.setComponentText ( "t2", String (tt2)); myNextion.setComponentText ( "t4", String (hh2)); myNextion.setComponentText ( "t16", String (tt1)); myNextion.setComponentText ( "t17", String (hh1)); myNextion.setComponentText ( "t6", String (clock.dateFormat ( "H: i: sd: m: y", dt))); myNextion.setComponentText ( "t5", String (clock.dateFormat ( "l", dt))); myNextion.setComponentText ( "t18", String (ggg)); if (z == false) {delay (350); // потрібна для роботи сенсорних Кнопа (мабуть особливість роботи бібліотеки)}}