Я новичок не пинайтк сильно. Код писал полностью сам, готов принятт критику.
Проблема, ардуина перезагружается как то рандомно, не могу понять пока почему, но есть теория что стоит рядом с четырехканальным реле и из за наводок…, но может пробоеиа с кодом.
Ткните носом на ошибки кода, может я перемудрил. А так код вроде рабочий))
Также прошу знатоков скзаать на счет меню, энкодер туговато отзывается когда поворачиваешь и меняешь значения.
#include <GyverEncoder.h> // библиотека энкодера
#include <DHT.h> // библиотека датчика температуры и влажности
#include <Wire.h> //Подключения библиотеке для работы I2C
#include <LiquidCrystal_I2C.h> // Подключения библиотеке LCD
#include <microDS3231.h> // Подключения библиотеке датчика реального времени
#define CLK 6 // Установка пина энкодера
#define DT 7 // Установка пина энкодера
#define SW 8 // Установка пина энкодера
#define DHTPIN 2 // вывод, к которому подключается датчик температуры и влажности
#define DHTTYPE DHT22 // модель датчика
#define Light 3 // Пин освещения
#define Hidro 4 // Пин увлажнителя
#define Fan 5 // Пин вентиляции
Encoder enc1(CLK, DT, SW, TYPE2); // Установка типа энкодера и количества кнопок
MicroDS3231 rtc; // установка датчика реального времени
LiquidCrystal_I2C lcd(0x27,16,2); // установка дисплея (0x27 адрес, 16 символов, 2 строки)
DHT dht(DHTPIN, DHTTYPE); // создаём объект dht с которым будем работать
float maxTemp = 30; // Включения вентиляции
float minTemp = 27; // Выключения вентиляции
int minH = 60; // Включения увлажнителя
int maxH = 70; // Выключения увлажнителя
int maxT = 22; // Вермя выключения освещения
int minT = 8; // Время включения освещения
float T; // Средний показатель температуры за 15 секунд (5 измерений)
float t1; // 1 показание температуры
float t2; // 2 показание температуры
float t3; // 3 показание температуры
float t4; // 4 показание температуры
float t5; // 5 показание температуры
int tt = 1; // Переменная номера измерений температуры
float H; // Средний показатель влажности за 15 секунд (5 измерений)
float h1; // 1 показание влажности
float h2; // 2 показание влажности
float h3; // 3 показание влажности
float h4; // 4 показание влажности
float h5; // 5 показание влажности
int hh = 1; // Переменная номера измерений влажности
int days = 0; // Переменная дней
int i = 0, j = 0, k = 0, p = 0; // Переменные для работы с меню, подсветкой LCD, флаг вентиляции для вытяжки
unsigned long time_dht22; // Опрос датчика влажности и температуры
unsigned long time_lcd; // Обновления LCD в меню HOME
unsigned long last_mod; // Обновления LCD в настройках
unsigned long backlightLCD; // Время подсветки LCD
unsigned long time_dht22_sredne; // Подсчет средних результатов за 15 секунд
unsigned long good_time; // Переменная секундамера
unsigned long good = 0; // Переменная секунд
unsigned long last_mod_home; // Переменная отвечающая за возврат в меню HOME через 30 секунд
void setup() {
rtc.setTime(COMPILE_TIME); // Установка веремни на часах == веремя компиляции скетча
pinMode (Light, OUTPUT); // Обозначения пина как выхода
digitalWrite(Light, 0); // Установка отключения реле по умолчанию
pinMode (Hidro, OUTPUT); // Обозначения пина как выхода
digitalWrite(Hidro, 0); // Установка отключения реле по умолчанию
pinMode (Fan, OUTPUT); // Обозначения пина как выхода
digitalWrite(Fan, 0); // Установка отключения реле по умолчанию
enc1.setType(TYPE2); // тип энкодера
enc1.setFastTimeout(20);
lcd.init(); // Инициализация LCD
lcd.backlight(); // Включение подсветки LCD
dht.begin(); // Инициализация датчика влажности
//Serial.begin(9600); // Инициализация открытия порта для отладки программы
// проверка наличия модуля на линии i2c
// вызов rtc.begin() не обязателен для работы
if (!rtc.begin()) {
Serial.println("DS3231 not found");
for(;;);
}
}
void loop() {
if (millis() - good_time > 1000){ // Секундный таймер на последнем экране
good++;
good_time = millis();
}
if (good >= 2592000){ // Дневной таймер на последнем экране
good = 0;
days++;
}
if (days > 30){ // Дневной таймер сброс каждые 30 дней
days = 0;
}
enc1.tick();
if (enc1.isTurn()) { // если был совершён поворот (индикатор поворота в любую сторону)
// ваш код
}
if (k == 0 && millis() - backlightLCD > 30000){ // при истечениее 30 секунд выключение подсветки дисплея
lcd.noBacklight();
k = 1;
}
if (k == 1){ // при долгом нажатии включение подсветки дисплея на 30 секунд
if (enc1.isHolded()){
lcd.backlight();;
k = 0;
backlightLCD = millis();
}
}
// Меню построенное на условиях и переменных
if (i == 1 && j == 0){
lcd.clear();
j = 1;
last_mod_home = millis();
}
if (i == 1 && j == 1 && millis() - last_mod > 100){
lcd.setCursor(2,0);
lcd.print("Temperature");
lcd.setCursor(0,1);
lcd.print("OFF Fan");
if (enc1.isRight()) minTemp = minTemp - 0.2; // если был поворот направо, увеличиваем на 1
if (enc1.isLeft()) minTemp = minTemp + 0.2;
lcd.setCursor(10,1);
lcd.print(minTemp, 2);
lcd.setCursor(14,1);
lcd.print("*C");
//Serial.println("LCD MIN TEMP 100 mlsecond");
//Serial.println(minTemp);
last_mod = millis();
}
if (i == 2 && j == 1){
lcd.clear();
j = 2;
last_mod_home = millis();
}
if (i == 2 && j == 2 && millis() - last_mod > 100){
lcd.setCursor(2,0);
lcd.print("Temperature");
lcd.setCursor(0,1);
lcd.print("ON Fan ");
if (enc1.isRight()) maxTemp = maxTemp - 0.2; // если был поворот направо, увеличиваем на 1
if (enc1.isLeft()) maxTemp = maxTemp + 0.2;
lcd.setCursor(10,1);
lcd.print(maxTemp, 2);
lcd.setCursor(14,1);
lcd.print("*C");
//Serial.println("LCD MAX TEMP 100 mlsecond");
//Serial.println(maxTemp);
last_mod = millis();
}
if (i == 3 && j == 2){
lcd.clear();
j = 3;
last_mod_home = millis();
}
if (i == 3 && j == 3 && millis() - last_mod > 100){
lcd.setCursor(5,0);
lcd.print("Hidro");
lcd.setCursor(0,1);
lcd.print("ON ");
if (enc1.isRight()) minH = minH - 1; // если был поворот направо, уменьшает на 1
if (enc1.isLeft()) minH = minH + 1; // если был поворот налево, увеличиваем на 1
lcd.setCursor(13,1);
lcd.print(minH);
lcd.setCursor(15,1);
lcd.print("%");
//Serial.println("LCD MIN HIDRO 100 mlsecond");
//Serial.println(minH);
last_mod = millis();
}
if (i == 4 && j == 3){
lcd.clear();
j = 4;
last_mod_home = millis();
}
if (i == 4 && j == 4 && millis() - last_mod > 100){
lcd.setCursor(5,0);
lcd.print("Hidro");
lcd.setCursor(0,1);
lcd.print("OFF ");
if (enc1.isRight()) maxH = maxH - 1; // если был поворот направо, увеличиваем на 1
if (enc1.isLeft()) maxH = maxH + 1;
lcd.setCursor(13,1);
lcd.print(maxH);
lcd.setCursor(15,1);
lcd.print("%");
//Serial.println("LCD MAX HIDRO 100 mlsecond");
//Serial.println(minH);
last_mod = millis();
}
if (i == 5 && j == 4){
lcd.clear();
j = 5;
last_mod_home = millis();
}
if (i == 5 && j == 5 && millis() - last_mod > 100){
lcd.setCursor(5,0);
lcd.print("Light");
lcd.setCursor(0,1);
lcd.print("ON");
if (enc1.isRight()) minT = minT - 1; // если был поворот направо, увеличиваем на 1
if (enc1.isLeft()) minT = minT + 1;
lcd.setCursor(11,1);
lcd.print(minT);
lcd.setCursor(13,1);
lcd.print(":00");
//Serial.println("LCD ON LIGHT 100 mlsecond");
//Serial.println(minT);
last_mod = millis();
}
if (i == 6 && j == 5){
lcd.clear();
j = 6;
last_mod_home = millis();
}
if (i == 6 && j == 6 && millis() - last_mod > 100){
lcd.setCursor(5,0);
lcd.print("Light");
lcd.setCursor(0,1);
lcd.print("OFF");
if (enc1.isRight()) maxT = maxT - 1; // если был поворот направо, увеличиваем на 1
if (enc1.isLeft()) maxT = maxT + 1;
lcd.setCursor(11,1);
lcd.print(maxT);
lcd.setCursor(13,1);
lcd.print(":00");
//Serial.println("LCD OFF LIGHT 100 mlsecond");
//Serial.println(maxT);
last_mod = millis();
}
if (i == 7 && j == 6){
lcd.clear();
j = 7;
last_mod_home = millis();
}
if (i == 7 && j == 7){
lcd.setCursor(0,0);
lcd.print("*");
lcd.setCursor(1,0);
lcd.print(minTemp, 1);
lcd.setCursor(5,0);
lcd.print("*C");
lcd.setCursor(9,0);
lcd.print("*");
lcd.setCursor(10,0);
lcd.print(maxTemp, 1);
lcd.setCursor(14,0);
lcd.print("*C");
lcd.setCursor(0,1);
lcd.print("*");
lcd.setCursor(1,1);
lcd.print(minH);
lcd.setCursor(3,1);
lcd.print("%");
lcd.setCursor(6,1);
lcd.print(minT);
lcd.setCursor(8,1);
lcd.print("-");
lcd.setCursor(9,1);
lcd.print(maxT);
lcd.setCursor(12,1);
lcd.print("*");
lcd.setCursor(13,1);
lcd.print(maxH);
lcd.setCursor(15,1);
lcd.print("%");;
j = 8;
}
if (i == 8 && j == 8){
lcd.clear();
j = 9;
last_mod_home = millis();
}
if (i == 8 && j == 9){
lcd.setCursor(0,0);
lcd.print("Time:");
lcd.setCursor(6,0);
lcd.print(good);
lcd.setCursor(0,1);
lcd.print("Day:");
lcd.setCursor(6,1);
lcd.print(days);
}
if (i == 9 && j == 9){
lcd.clear();
j = 0;
i = 0;
}
if (i != 0 && millis() - last_mod_home > 30000) {
lcd.clear();
j = 0;
i = 0;
}
// КОНЕЦ МЕНЮ
if (enc1.isClick()) i++; // отпускание кнопки (+ дебаунс)
//if (enc1.isRight() && i == 1) minTemp = minTemp - 0.2; // если был поворот направо, увеличиваем на 1
//if (enc1.isLeft() && i == 1) minTemp = minTemp + 0.2; // если был поворот налево, уменьшаем на 1
//if (enc1.isRight() && i == 2) maxTemp = maxTemp - 0.2; // если был поворот направо, увеличиваем на 1
//if (enc1.isLeft() && i == 2) maxTemp = maxTemp + 0.2; // если был поворот налево, уменьшаем на 1
//if (enc1.isRightH()) Serial.println("Right holded"); // если было удержание + поворот
//if (enc1.isLeftH()) Serial.println("Left holded");
//if (enc1.isPress()) ; // нажатие на кнопку (+ дебаунс)
//if (enc1.isRelease()) Serial.println("Release"); // то же самое, что isClick
//if (enc1.isHolded()) Serial.println("Holded"); // если была удержана и энк не поворачивался
//if (enc1.isHold()) Serial.println("Hold"); // возвращает состояние кнопки
//if (millis() - time_dht22 > 3000)
//{
// H = dht.readHumidity();
// T = dht.readTemperature();
// Serial.print("H: ");
//Serial.print(H);
//Serial.print(" %\t");
//Serial.print("T: ");
//Serial.print(T);
//Serial.print(" *C ");
//Serial.println("3 seconds");
//time_dht22 = millis();
//}
//ВЫВОД СРЕДНЕГО - Опрос каждые 3 секунды и вывод среднего за 15 секунд!
if (millis() - time_dht22 > 3000 && tt == 1) {
t1 = dht.readTemperature();
h1 = dht.readHumidity();
time_dht22 = millis();
//Serial.println("tt1");
tt++;
}
if (millis() - time_dht22 > 3000 && tt == 2) {
t2 = dht.readTemperature();
h2 = dht.readHumidity();
time_dht22 = millis();
//Serial.println("tt2");
tt++;
}
if (millis() - time_dht22 > 3000 && tt == 3) {
t3 = dht.readTemperature();
h3 = dht.readHumidity();
time_dht22 = millis();
//Serial.println("tt3");
tt++;
}
if (millis() - time_dht22 > 3000 && tt == 4) {
t4 = dht.readTemperature();
h4 = dht.readHumidity();
time_dht22 = millis();
//Serial.println("tt4");
tt++;
}
if (millis() - time_dht22 > 3000 && tt == 5) {
t5 = dht.readTemperature();
h5 = dht.readHumidity();
time_dht22 = millis();
//Serial.println("tt5");
tt = 1;
}
if (millis() - time_dht22_sredne > 2500){
T = (t1 + t2 + t3 + t4 + t5) / 5; // средняя температора за 15 секкунд (5 измерений)
H = (h1 + h2 + h3 + h4 + h5) / 5; // средняя влажность за 15 секунд (5 измерений)
//Serial.print(T);
//Serial.println(" Srednee za 15 seconds");
//Serial.print(H);
//Serial.println(" Srednee za 15 seconds");
time_dht22_sredne = millis();
}
if (i == 0 && millis() - time_lcd > 200) // Вывод LCD дисплей HOME
{
lcd.setCursor(0,0);
lcd.print(rtc.getTimeString());
lcd.setCursor(0,1);
lcd.print("T: ");
lcd.setCursor(2,1);
lcd.print(T, 1);
if (digitalRead(Light) == 1){
//Serial.println("Light On");
lcd.setCursor(12,0);
lcd.print("L");
} else {
lcd.setCursor(12,0);
lcd.print("-");
}
if (digitalRead(Hidro) == 1){
lcd.setCursor(13,0);
lcd.print("H");
} else {
lcd.setCursor(13,0);
lcd.print("-");
}
if (digitalRead(Fan) == 1){
lcd.setCursor(14,0);
lcd.print("F");
} else {
lcd.setCursor(14,0);
lcd.print("-");
}
lcd.setCursor(15,0);
lcd.print("-");
lcd.setCursor(10,1);
lcd.print("H: ");
lcd.setCursor(12,1);
lcd.print(H, 1);
time_lcd = millis();
//Serial.println(" LCD 200 mlsekond");
}
if (T >= maxTemp && digitalRead(Fan) == 0 && p == 0){ // Включение вентиляции с проверкой переменной для увлажнителя
digitalWrite(Fan, 1);
}
if (T <= minTemp && digitalRead(Fan) == 1){ // Выключение вентиляции
digitalWrite(Fan, 0);
}
if (H >= maxH && digitalRead(Hidro) == 1){ // Включение увлажнителя и закрытие переменной для вентиляции
digitalWrite(Hidro, 0);
p = 0;
}
if (H <= minH && digitalRead(Hidro) == 0){ // Выключение вентиляции и включение увлажнителя
digitalWrite(Fan, 0);
p = 1;
digitalWrite(Hidro, 1);
}
if (rtc.getHours() >= minT && rtc.getHours() < maxT && digitalRead(Light) == 0) { // Включение света в диапазоне
digitalWrite(Light, 1);
//Serial.println(" ON LIGHT");
//Serial.println(minT);
//Serial.println(maxT);
//Serial.println(rtc.getHours());
}
if (rtc.getHours() >= minT && rtc.getHours() >= maxT && digitalRead(Light) == 1) { // Выключение света в верхнем диапазоне
digitalWrite(Light, 0);
//Serial.println(" OFF LIGHT 2");
//Serial.println(minT);
//Serial.println(maxT);
//Serial.println(rtc.getHours());
}
if (rtc.getHours() < minT && rtc.getHours() <= maxT && digitalRead(Light) == 1) { // Включение света в нижнем диапазоне
digitalWrite(Light, 0);
//Serial.println(" OFF LIGHT 3");
//Serial.println(minT);
//Serial.println(maxT);
//Serial.println(rtc.getHours());
}
}