Доработать скетч, Полив по таймеру и датчику влажности
- Войдите на сайт для отправки комментариев
Ср, 20/01/2021 - 14:02
Добрый День.
Необходимо дописать готовый скетч (добавить опрос датчиков влажности)
ТЗ:
Во вложении скетч, таймер времени, на 4 зоны.
На данный момент выглядит сейчас вот так:
Необходимо дописать готовый скетч (добавить опрос датчиков влажности)
ТЗ:
Во вложении скетч, таймер времени, на 4 зоны.
На данный момент выглядит сейчас вот так:
Хочу его применить для полива газона на 4 зоны, соответственно он будет подавать на выход сигнал который будет открывать электроклапан воды.
Необходимо что бы перед включением каждого таймера был опрос (подавалось питание и считывалась информация) емкостного датчика влажности. (только перед включением таймера, один раз)
В скетче нужно поле для того что бы указывать какое значение с датчика влажности является 0% а какое 100%, можно одно поле для всех датчиков (+/- значения будут одинаковые).
Датчиков влажности будет 4, как и каналов для реле. По умолчанию датчик №1 должен быть подвязан к каналу №1, датчик №2 должен быть подвязан к каналу №2 и тд.
В таймерах есть настройка "УРОВЕНЬ СИГНАЛА" - это поле нужно заменить на "УРОВЕНЬ ВЛАЖНОСТИ", соответственно перед запуском таймера ардуино должно считать с датчика % влажности, проверить какой стоит % в настройках таймера и если он равен или меньше установленного то запустить таймер, если значение выше то не запускать таймер.
001 | #include <avr/pgmspace.h> // Подключаем библиотеку для работы с PROGMEM Arduino для хранения символов дисплея |
002 | #include <EEPROM.h> // Подключаем библиотеку для работы с EEPROM Arduino для хранения значений таймеров |
003 | #include <Wire.h> // Подключаем библиотеку для работы с шиной I2C |
004 | #include <LiquidCrystal_I2C.h> // Подключаем библиотеку для работы с LCD дисплеем по шине I2C |
005 | #include <iarduino_Encoder_tmr.h> // Подключаем библиотеку GyverEncoder для работы с энкодерами через аппаратный таймер |
006 | #include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с часами реального времени |
007 | // |
008 | // ОБЪЯВЛЯЕМ КОНСТАНТЫ КОТОРЫЕ МОЖНО РЕДАКТИРОВАТЬ: // |
009 | const uint8_t pinEncA = 7; // Определяем константу с указанием № вывода Arduino к которому подключён вывод «A» энкодера |
010 | const uint8_t pinEncB = 8; // Определяем константу с указанием № вывода Arduino к которому подключён вывод «B» энкодера |
011 | const uint8_t pinEncBTN = 4; // Определяем константу с указанием № вывода Arduino к которому подключён вывод «S» энкодера (кнопка) |
012 | const uint8_t pinChanel_1 = 5; // Определяем константу с указанием № вывода Arduino который будет являеться выводом 1 канала (указываются только выводы с ШИМ, кроме выводов используемых 2 таймером Arduino) |
013 | const uint8_t pinChanel_2 = 6; // Определяем константу с указанием № вывода Arduino который будет являеться выводом 2 канала (указываются только выводы с ШИМ, кроме выводов используемых 2 таймером Arduino) |
014 | const uint8_t pinChanel_3 = 9; // Определяем константу с указанием № вывода Arduino который будет являеться выводом 3 канала (указываются только выводы с ШИМ, кроме выводов используемых 2 таймером Arduino) |
015 | const uint8_t pinChanel_4 = 10; // Определяем константу с указанием № вывода Arduino который будет являеться выводом 4 канала (указываются только выводы с ШИМ, кроме выводов используемых 2 таймером Arduino) |
016 | const uint8_t maxTimers = 20; // Определяем константу с указанием максимального количества таймеров. Число не должно превышать количество байт EEPROM/8 (для Arduino Uno максимальное значение 128) |
017 | // |
018 | // ОБЪЯВЛЯЕМ КОНСТАНТЫ И ПЕРЕМЕННЫЕ НЕОБХОДИМЫЕ ДЛЯ РАБОТЫ СКЕТЧА: // |
019 | const byte rusMem[38][8] PROGMEM = { // Определяем массив в области памяти программ, каждый элемент которого является матрицей (еще одим массивом) представления символа на дисплее |
020 | {31,16,16,30,17,17,30, 0}, { 0, 0,30,17,30,17,30, 0}, // Б, в, № матрицы символа в массиве: 00, 01 |
021 | {31,16,16,16,16,16,16, 0}, { 0, 0,30,16,16,16,16, 0}, // Г, г, № матрицы символа в массиве: 02, 03 |
022 | { 6,10,10,10,10,10,31,17}, {10,10,14, 2, 2, 0, 0, 0}, // Д, 4, № матрицы символа в массиве: 04, 05 |
023 | {17,17,17,19,21,25,17, 0}, { 0, 0,17,19,21,25,17, 0}, // И, и, № матрицы символа в массиве: 06, 07 |
024 | {21,17,17,19,21,25,17, 0}, { 10,4,17,19,21,25,17, 0}, // Й, й, № матрицы символа в массиве: 08, 09 |
025 | { 0, 0,18,20,24,20,18, 0}, { 0, 0,17,27,21,17,17, 0}, // к, м, № матрицы символа в массиве: 10, 11 |
026 | { 7, 9, 9, 9, 9, 9,17, 0}, { 0, 0, 7, 9, 9, 9,17, 0}, // Л, л, № матрицы символа в массиве: 12, 13 |
027 | {31,17,17,17,17,17,17, 0}, { 0, 0,17,17,31,17,17, 0}, // П н, № матрицы символа в массиве: 14, 15 |
028 | {17,17,17,15, 1,17,14, 0}, { 0, 0,31, 4, 4, 4, 4, 0}, // У, т, № матрицы символа в массиве: 16, 17 |
029 | {17,17,17,15, 1, 1, 1, 0}, { 0, 0,17,17,15, 1, 1, 0}, // Ч, ч, № матрицы символа в массиве: 18, 19 |
030 | {17,17,17,29,19,19,29, 0}, { 0, 0,17,17,29,19,29, 0}, // Ы, ы, № матрицы символа в массиве: 20, 21 |
031 | {16,16,16,30,17,17,30, 0}, { 0, 0, 0, 0, 0, 0,21, 0}, // Ь, ..., № матрицы символа в массиве: 22, 23 |
032 | {18,21,21,29,21,21,18, 0}, { 0, 0,18,21,29,21,18, 0}, // Ю, ю, № матрицы символа в массиве: 24, 25 |
033 | {15,17,17,15, 5, 9,17, 0}, { 0, 0,15,17,15, 5, 9, 0}, // Я, я, № матрицы символа в массиве: 26, 27 |
034 | {31, 4,31, 0,31,16,31, 0}, {16,31,16, 0,10,21,31, 0}, // ПН, ВТ № матрицы символа в массиве: 28, 29 |
035 | {28,20,31, 0,17,17,31, 0}, {16,31,16, 0,31, 4,28, 0}, // СР, ЧТ № матрицы символа в массиве: 30, 31 |
036 | {16,31,16, 0,31,16,31, 0}, {23,21,31, 0,17,17,31, 0}, // ПТ, СБ № матрицы символа в массиве: 32, 33 |
037 | {17,17,31, 0,10,21,31, 0}, { 4,12, 4, 4,14, 0, 0, 0}, // ВС, 1 № матрицы символа в массиве: 34, 35 |
038 | {14, 2,14, 8,14, 0, 0, 0}, {14, 2,14, 2,14, 0, 0, 0}}; // 2, 3 № матрицы символа в массиве: 36, 37 |
039 | uint8_t valArray[7] = {0,0,0,0,0,0,0}; // Определяем массив элементы которого будут хранить различную информацию в зависимости от режима |
040 | char valChar[5] = " " ; // Определяем массив символов (строку) информация которой будет отображаться на дисплее мигая |
041 | uint8_t valMode = 0; // Определяем переменную для хранения текущего режима (например: режим 31 - установка времени) |
042 | uint8_t valSubMode = 0; // Определяем переменную для хранения текущего подрежима (например: режим 31, подрежим 0 - установка часов, подрежим 1 - установка минут, подрежим 2 - установка секунд) |
043 | uint8_t valTimerNum = 0; // Определяем переменную для хранения номера выбранного таймера (от 0 до maxTimers-1) |
044 | bool flgDisplayUpdate = 1; // Определяем флаговую переменную, установка которой будет сигнализировать о необходимости обновления дисплея |
045 | void funcEncoderRead ( void ); // Объявляем функцию в которой будут выполняться действия зависящие от состояния энкодера и режима |
046 | void funcDisplayUpdate ( void ); // Объявляем функцию в которой будет обновляться информация дисплея в зависимости от режима, подрежима, выбранного таймера и значений массива valArray |
047 | void funcSetPWM ( void ); // Объявляем функцию которая будет устанавливать сигналы ШИМ на каналах если текущее время совпало с временем таймеров |
048 | void funcSetChars (uint8_t=255,uint8_t=255,uint8_t=255,uint8_t=255,uint8_t=255,uint8_t=255,uint8_t=255); // Объявляем функцию записывающую до 7 символов из массива rusMem по номерам его элементов в область CGRAM дисплея |
049 | uint8_t funcReadTimer (uint8_t=0, uint8_t=0); // Объявляем функцию для чтения одного из параметров таймера (№ таймера, № параметра) |
050 | void funcSaveTimer (uint8_t=0, uint8_t=0, uint8_t=0); // Объявляем функцию для записи одного из параметров таймера (№ таймера, № параметра, значение параметра) |
051 | uint8_t funcFindTimer ( void ); // Объявляем функцию для поиска № следующего свободного (не установленного) таймера |
052 | bool funcTestTimer ( void ); // Объявляем функцию для проверки соответствия данных в ячейках EEPROM Arduino значениям таймеров (если скетч запускается впервые, то данные в ячейках не будут соответствовать значениям таймеров и можно будет подготовить EEPROM к первому запуску скетча) |
053 | LiquidCrystal_I2C lcd (0x27,16,2); // Объявляем объект lcd для работы с дисплеем указывая (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2) |
054 | iarduino_Encoder_tmr enc (pinEncA,pinEncB); // Объявляем объект enc для работы с энкодером указывая (№ вывода A, № вывода B) |
055 | iarduino_RTC time (RTC_DS3231); // Объявляем объект time для работы с часами RTC указывая (тип модуля) |
056 | #define encPRESS 3 // Определяем константу для удобочитаемости при определении состояния энкодера |
057 | // |
058 | void setup (){ // |
059 | enc.begin(); // Инициируем работу с энкодером |
060 | time.begin(); // Инициируем работу с RTC модулем |
061 | pinMode(pinEncBTN, INPUT_PULLUP); // Переводим вывод с кнопкой энкодера в режим входа |
062 | pinMode(pinChanel_1, OUTPUT); // Переводим вывод 1 канала в режим выхода |
063 | pinMode(pinChanel_2, OUTPUT); // Переводим вывод 1 канала в режим выхода |
064 | pinMode(pinChanel_3, OUTPUT); // Переводим вывод 1 канала в режим выхода |
065 | pinMode(pinChanel_4, OUTPUT); // Переводим вывод 1 канала в режим выхода |
066 | lcd.init(); // Инициируем работу с LCD дисплеем |
067 | lcd.backlight(); // Включаем подсветку LCD дисплея |
068 | funcSetChars(12,6); // Загружаем элементы 12 и 6 массива rusMem в память CGRAM LCD дисплея. Эти элементы содержат графическое представление символов: «Л» и «И» |
069 | lcd.setCursor(0,0); // Устанавливаем курсор в верхний левый угол экрана (0 столбец, 0 строка) |
070 | lcd.print(F( "PE\1E BPEMEH\2" )); // Выводим надпись «PEЛE BPEMEHИ». Буквы «Л» и «И» заменяем знаком '\' и №, под которыми их графические представления были загружены в память CGRAM LCD дисплея. |
071 | lcd.setCursor(5,1); // Устанавливаем курсор в 5 столбец 1 строки (нумерация начинается с 0) |
072 | lcd.print(F( "YV1" )); // Выводим надпись «iarduino.ru». |
073 | delay(2000); // Ждём, что бы надпись отображаемую на дисплее успели прочитать |
074 | lcd.clear(); // Чистим экран, |
075 | if (!funcTestTimer()){ // Если значения в EEPROM не соответствуют значениям таймера (например первый запуск данного скетча), то ... |
076 | funcSetChars(14,4,2); // Загружаем элементы 14, 4 и 2 массива rusMem в память CGRAM LCD дисплея. Эти элементы содержат графическое представление символов: «П», «Д» и «Г» |
077 | lcd.setCursor(0,0); // Устанавливаем курсор в верхний левый угол экрана (0 столбец, 0 строка) |
078 | lcd.print(F( "\1O\2\3OTOBKA..." )); // Выводим надпись «ПOДГOTOBKA...». Буквы «П», «Д» и «Г» заменяем знаком '\' и №, под которыми их графические представления были загружены в память CGRAM LCD дисплея. |
079 | for (uint8_t i=0; i<maxTimers; i++){ // Проходим по всем возможным таймерам |
080 | for (uint8_t j=0; j<8; j++){ // Проходим по всем возможным параметрам каждого таймера |
081 | funcSaveTimer(i,j,0); // Обнуляем все возможные параметры каждого таймера |
082 | }} delay(1000); lcd.clear(); // Ждём, что бы надпись отображаемую на дисплее успели прочитать, а потом чистим экран |
083 | } // |
084 | } // |
085 | // |
086 | void loop (){ // |
087 | funcEncoderRead(); // Выполняем действия в соответствии с состоянием энкодера и режимом valMode |
088 | funcDisplayUpdate(); // Обновляем информацию на дисплее в соответствии с режимом valMode и только если установлен флаг flgDisplayUpdate |
089 | funcSetPWM(); // Выводим ШИМ |
090 | } // |
091 | // |
092 | // ВЫПОЛНЕНИЕ ДЕЙСТВИЙ ПРИ ИЗМЕНЕНИИ СОТОЯНИЯ ЭНКОДЕРА И В ЗАВИСИМОСТИ ОТ ТЕКУЩЕГО РЕЖИМА // |
093 | void funcEncoderRead( void ){ // |
094 | int i=enc.read(); // Определяем переменную i в которую читаем состояние энкодера (может принимать 1 из 3 значений: 0, encLEFT, encRIGHT а далее к ним прибавится еще и значение encPRESS) |
095 | int j=255; // Определяем переменную j для хранения № режима меню, в который требуется перейти (значение 255 означает что переход в другой режим не требуется) |
096 | if (!digitalRead(pinEncBTN)){i=encPRESS;} // Если нажата кнопка энкодера, то устанавливаем переменную i в значение encPRESS |
097 | switch (valMode){ // Далее действуем в зависимости от значения переменной valMode (которая хранит № текущего режима меню) |
098 | case 0: if (i==encPRESS){j= 1;} // Если установлен режим 0 "Вне меню", то ... |
099 | /* "00:00:00 " */ flgDisplayUpdate=1; // Устанавливаем флаг flgDisplayUpdate сигнализирующий о необходимости обновить информацию на дисплее |
100 | /* "00.00.0000 XX " */ // |
101 | break ; // |
102 | case 1: if (i==encPRESS){j=funcReadTimer()?11:12; valTimerNum=0;} // Если установлен режим 1: "Меню" и нажав на энкодер, можно выбрать пункт "ТАЙМЕРЫ", то ... |
103 | /* "меню: " */ if (i==encLEFT ){j= 3;} // Если энкодер поворачивается влево, то переходим в режим 3 |
104 | /* "< ТАЙМЕРЫ >" */ if (i==encRIGHT){j= 2;} // Если энкодер поворачивается вправо, то переходим в режим 2 |
105 | break ; // |
106 | case 2: if (i==encPRESS){j=21;} // Если установлен режим 2: "Меню" и нажав на энкодер, можно выбрать пункт "ЧАСЫ", то ... |
107 | /* "меню: " */ if (i==encLEFT ){j= 1;} // Если энкодер поворачивается влево, то переходим в режим 1 |
108 | /* "< ЧАСЫ >" */ if (i==encRIGHT){j= 3;} // Если энкодер поворачивается вправо, то переходим в режим 3 |
109 | break ; // Если установлен режим 3: "Меню" и нажав на энкодер, можно выбрать пункт "ВЫХОД", то ... |
110 | case 3: if (i==encPRESS){j= 0; valArray[0]=valArray[1]=valArray[2]=valArray[3]=0;} |
111 | /* "меню: " */ if (i==encLEFT ){j= 2;} // Если энкодер поворачивается влево, то переходим в режим 2 |
112 | /* "< ВЫХОД >" */ if (i==encRIGHT){j= 1;} // Если энкодер поворачивается вправо, то переходим в режим 1 |
113 | break ; // |
114 | case 11: if (i==encPRESS){j=51;} // Если установлен режим 11: "Меню>таймеры" и нажав на энкодер, можно выбрать один из таймеров, то ... |
115 | /* "меню>таймеры: " */ if (i==encLEFT ){ if (valTimerNum){valTimerNum--; lcd.clear(); flgDisplayUpdate=1;} else {j=14;}} |
116 | /* "< 00:00-00:00-1>" */ if (i==encRIGHT){valTimerNum++; if (valTimerNum>=maxTimers){j=13;} else if (funcReadTimer(valTimerNum)){lcd.clear(); flgDisplayUpdate=1;} else {j=12;}} |
117 | break ; // |
118 | case 12: if (i==encPRESS){j=41;} // Если установлен режим 12: "Меню>таймеры" и нажав на энкодер, можно выбрать пункт "НОВЫЙ ТАЙМЕР", то ... |
119 | /* "меню>таймеры: " */ if (i==encLEFT ){j=funcReadTimer()?11:14; if (funcReadTimer()){valTimerNum=funcFindTimer()-1;}} |
120 | /* "< НОВЫЙ ТАЙМЕР >" */ if (i==encRIGHT){j=funcReadTimer()?13:14;} // Если энкодер поворачивается вправо, то переходим в режим 13 или 14 (зависит от наличия установленных таймеров) |
121 | break ; // |
122 | case 13: if (i==encPRESS){j=42;} // Если установлен режим 13: "Меню>таймеры" и нажав на энкодер, можно выбрать пункт "CTEPETЬ BCE ТАЙМЕРЫ", то ... |
123 | /* "меню>таймеры: " */ if (i==encLEFT ){j=funcFindTimer()<maxTimers?12:11; valTimerNum=j==11?maxTimers-1:0;} |
124 | /* "< CTEPETЬ BCE >" */ if (i==encRIGHT){j=14; valTimerNum=0;} // Если энкодер поворачивается вправо, то переходим в режим 14 и указываем что выбран таймер № 0 |
125 | break ; // |
126 | case 14: if (i==encPRESS){j= 1;} // Если установлен режим 14: "Меню>таймеры" и нажав на энкодер, можно выбрать пункт "ВЫХОД", то ... |
127 | /* "меню>таймеры: " */ if (i==encLEFT ){j=funcReadTimer()?13:(funcFindTimer()<maxTimers?12:11); valTimerNum=0;} |
128 | /* "< ВЫХОД >" */ if (i==encRIGHT){j=funcReadTimer()?11:(funcFindTimer()<maxTimers?12:13); valTimerNum=0;} |
129 | break ; // Если установлен режим 21: "Меню>часы" и нажав на энкодер, можно выбрать пункт "ВРЕМЯ", то ... |
130 | case 21: if (i==encPRESS){j=31; valSubMode=0; time.gettime(); valArray[0]=time.Hours; valArray[1]=time.minutes; valArray[2]=time.seconds;} |
131 | /* "меню>часы: " */ if (i==encLEFT ){j=23;} // Если энкодер поворачивается влево, то переходим в режим 23 |
132 | /* "< ВРЕМЯ >" */ if (i==encRIGHT){j=22;} // Если энкодер поворачивается вправо, то переходим в режим 22 |
133 | break ; // Если установлен режим 22: "Меню>часы" и нажав на энкодер, можно выбрать пункт "ДАТА", то ... |
134 | case 22: if (i==encPRESS){j=32; valSubMode=0; time.gettime(); valArray[0]=time.day; valArray[1]=time.month; valArray[2]=time.year; valArray[3]=time.weekday;} |
135 | /* "меню>часы: " */ if (i==encLEFT ){j=21;} // Если энкодер поворачивается влево, то переходим в режим 21 |
136 | /* "< ДАТА >" */ if (i==encRIGHT){j=23;} // Если энкодер поворачивается вправо, то переходим в режим 23 |
137 | break ; // |
138 | case 23: if (i==encPRESS){j= 2;} // Если установлен режим 23: "Меню>часы" и нажав на энкодер, можно выбрать пункт "ВЫХОД", то ... |
139 | /* "меню>часы: " */ if (i==encLEFT ){j=22;} // Если энкодер поворачивается влево, то переходим в режим 22 |
140 | /* "< ВЫХОД >" */ if (i==encRIGHT){j=21;} // Если энкодер поворачивается вправо, то переходим в режим 21 |
141 | break ; // Если установлен режим 31: "Меню>часы>вpeмя" и управляя энкодером, можно установить время, то ... |
142 | case 31: if (i==encPRESS){ if (valSubMode==0){valSubMode=1;} else if (valSubMode==1){valSubMode=2;} else if (valSubMode==2){time.settime(valArray[2],valArray[1],valArray[0]); j=21;}} |
143 | /* "меню>часы>вpeмя:" */ if (i==encLEFT ){valArray[valSubMode]--; if (valArray[0]>23){valArray[0]=23;} if (valArray[1]>59){valArray[1]=59;} if (valArray[2]>59){valArray[2]=59;}} |
144 | /* " 00:00:00 " */ if (i==encRIGHT){valArray[valSubMode]++; if (valArray[0]>23){valArray[0]= 0;} if (valArray[1]>59){valArray[1]= 0;} if (valArray[2]>59){valArray[2]= 0;}} |
145 | flgDisplayUpdate=1; // Устанавливаем флаг flgDisplayUpdate сигнализирующий о необходимости обновить информацию на дисплее |
146 | break ; // Если установлен режим 32: "Меню>часы>дата" и управляя энкодером, можно установить дату, то ... |
147 | case 32: if (i==encPRESS){ if (valSubMode==0){valSubMode=1;} else if (valSubMode==1){valSubMode=2;} else if (valSubMode==2){valSubMode=3;} else if (valSubMode==3){time.settime(-1,-1,-1,valArray[0],valArray[1],valArray[2],valArray[3]); j=22;}} |
148 | /* "MEHЮ>ЧACЫ>ДATA: " */ if (i==encLEFT ){valArray[valSubMode]--; if (valArray[0]==0){valArray[0]=31;} if (valArray[1]==0){valArray[1]=12;} if (valArray[2]>99){valArray[2]=99;} if (valArray[3]>6){valArray[3]=6;}} |
149 | /* " 00.00.0000 пт " */ if (i==encRIGHT){valArray[valSubMode]++; if (valArray[0]>31){valArray[0]= 1;} if (valArray[1]>12){valArray[1]= 1;} if (valArray[2]>99){valArray[2]= 0;} if (valArray[3]>6){valArray[3]=0;}} |
150 | flgDisplayUpdate=1; // Устанавливаем флаг flgDisplayUpdate сигнализирующий о необходимости обновить информацию на дисплее |
151 | break ; // |
152 | case 41: // Если установлен режим 41: "HOBЫЙ TAЙMEP CO3ДAH", то данный режим сбросится в режим 61 через 2 секунды вне зависимости от состояния энкодера ... |
153 | /* " HOBЫЙ TAЙMEP " */ j=61; valTimerNum=funcFindTimer(); valSubMode=0; valArray[0]=0; valArray[1]=0; valArray[2]=0; valArray[3]=0; valArray[4]=1; funcSaveTimer(valTimerNum,0,1); funcSaveTimer(valTimerNum,1); funcSaveTimer(valTimerNum,2); funcSaveTimer(valTimerNum,3); funcSaveTimer(valTimerNum,4); funcSaveTimer(valTimerNum,5,1); funcSaveTimer(valTimerNum,6,100); funcSaveTimer(valTimerNum,7,127); |
154 | /* " CO3ДAH " */ delay(2000); // |
155 | break ; // |
156 | case 42: // Если установлен режим 42: "BCE TAЙMEPЫ УДAЛEHЫ", то данный режим сбросится в режим 12 через 2 секунды вне зависимости от состояния энкодера ... |
157 | /* " BCE TAЙMEPЫ " */ j=12; for (valArray[0]=0; valArray[0]<maxTimers; valArray[0]++){funcSaveTimer(valArray[0]);} |
158 | /* " УДAЛEHЫ " */ delay(2000); // |
159 | break ; // |
160 | case 43: // Если установлен режим 43: "TAЙMEP УДAЛEH", то данный режим сбросится в режим 11 или 12 через 2 секунды вне зависимости от состояния энкодера ... |
161 | /* " TAЙMEP " */ j=12; valArray[0]=valTimerNum; valArray[1]=funcFindTimer()-1; if (valArray[0]<valArray[1]){j=11; valTimerNum=valArray[0];} else if (valArray[1]>0){j=11; valTimerNum=valArray[0]-1;} for ( int k=valArray[0]; k<valArray[1]; k++){ for (uint8_t l=0; l<8; l++){funcSaveTimer(k,l,funcReadTimer(k+1,l));}} funcSaveTimer(valArray[1]); |
162 | /* " УДAЛEH " */ delay(2000); // |
163 | break ; // Если установлен режим 51: "Меню>тайmеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "BPEMЯ И KAHAЛ", то ... |
164 | case 51: if (i==encPRESS){j=61; valSubMode=0; valArray[0]=funcReadTimer(valTimerNum,1); valArray[1]=funcReadTimer(valTimerNum,2); valArray[2]=funcReadTimer(valTimerNum,3); valArray[3]=funcReadTimer(valTimerNum,4); valArray[4]=funcReadTimer(valTimerNum,5);} |
165 | /* "m>тайmеры>00:00." */ if (i==encLEFT ){j=55;} // Если энкодер поворачивается влево, то переходим в режим 55 |
166 | /* "<BPEMЯ И KAHAЛ>" */ if (i==encRIGHT){j=52;} // Если энкодер поворачивается вправо, то переходим в режим 52 |
167 | break ; // Если установлен режим 52: "Меню>тайmеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "ПOBTOPЫ", то ... |
168 | case 52: if (i==encPRESS){j=62; valSubMode=0; valArray[0]=bitRead(funcReadTimer(valTimerNum,7),6); valArray[1]=bitRead(funcReadTimer(valTimerNum,7),5); valArray[2]=bitRead(funcReadTimer(valTimerNum,7),4); valArray[3]=bitRead(funcReadTimer(valTimerNum,7),3); valArray[4]=bitRead(funcReadTimer(valTimerNum,7),2); valArray[5]=bitRead(funcReadTimer(valTimerNum,7),1); valArray[6]=bitRead(funcReadTimer(valTimerNum,7),0);} |
169 | /* "m>тайmеры>00:00." */ if (i==encLEFT ){j=51;} // Если энкодер поворачивается влево, то переходим в режим 51 |
170 | /* "<ПО ДНЯМ НЕДЕЛИ>" */ if (i==encRIGHT){j=53;} // Если энкодер поворачивается вправо, то переходим в режим 53 |
171 | break ; // Если установлен режим 53: "Меню>тайmеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "УPOBEHЬ CИГНАЛА", то ... |
172 | case 53: if (i==encPRESS){j=63; valArray[0]=funcReadTimer(valTimerNum,6);} |
173 | /* "m>тайmеры>00:00." */ if (i==encLEFT ){j=52;} // Если энкодер поворачивается влево, то переходим в режим 52 |
174 | /* "< УPOBEHb CИГН.>" */ if (i==encRIGHT){j=54;} // Если энкодер поворачивается вправо, то переходим в режим 54 |
175 | break ; // |
176 | case 54: if (i==encPRESS){j=43;} // Если установлен режим 54: "Меню>тайmеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "CTEPETЬ TAЙMEP", то ... |
177 | /* "m>тайmеры>00:00." */ if (i==encLEFT ){j=53;} // Если энкодер поворачивается влево, то переходим в режим 53 |
178 | /* "<CTEPETЬ TAЙMEP>" */ if (i==encRIGHT){j=55;} // Если энкодер поворачивается вправо, то переходим в режим 55 |
179 | break ; // |
180 | case 55: if (i==encPRESS){j=11;} // Если установлен режим 55: "Меню>тайmеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "ВЫХОД", то ... |
181 | /* "m>тайmеры>00:00." */ if (i==encLEFT ){j=54;} // Если энкодер поворачивается влево, то переходим в режим 54 |
182 | /* "< ВЫХОД >" */ if (i==encRIGHT){j=51;} // Если энкодер поворачивается вправо, то переходим в режим 51 |
183 | break ; // Если установлен режим 61: "Меню>тайmеры>выбранный_таймер>время_и_канал" и управляя энкодером, можно установить время и канал таймера, то ... |
184 | case 61: if (i==encPRESS){ if (valSubMode==0){valSubMode=1;} else if (valSubMode==1){valSubMode=2;} else if (valSubMode==2){valSubMode=3;} else if (valSubMode==3){valSubMode=4;} else if (valSubMode==4){ |
185 | j=51; funcSaveTimer(valTimerNum,0,1); funcSaveTimer(valTimerNum,1,valArray[0]); funcSaveTimer(valTimerNum,2,valArray[1]); funcSaveTimer(valTimerNum,3,valArray[2]); funcSaveTimer(valTimerNum,4,valArray[3]); funcSaveTimer(valTimerNum,5,valArray[4]);}} |
186 | /* "м>таймер>вpeмя: " */ if (i==encLEFT ){valArray[valSubMode]--; if (valArray[0]>23){valArray[0]=23;} if (valArray[1]>59){valArray[1]=59;} if (valArray[2]>23){valArray[2]=23;} if (valArray[3]>59){valArray[3]=59;} if (valArray[4]==0){valArray[4]=4;}} |
187 | /* " 00:00-00:00 к0 " */ if (i==encRIGHT){valArray[valSubMode]++; if (valArray[0]>23){valArray[0]= 0;} if (valArray[1]>59){valArray[1]= 0;} if (valArray[2]>23){valArray[2]= 0;} if (valArray[3]>59){valArray[3]= 0;} if (valArray[4]> 4){valArray[4]=1;}} |
188 | flgDisplayUpdate=1; // Устанавливаем флаг flgDisplayUpdate сигнализирующий о необходимости обновить информацию на дисплее |
189 | break ; // Если установлен режим 62: "Меню>тайmеры>выбранный_таймер>повторы" и управляя энкодером, можно установить повторы таймера, то ... |
190 | case 62: if (i==encPRESS){flgDisplayUpdate=1; if (valSubMode==0){valSubMode=1;} else if (valSubMode==1){valSubMode=2;} else if (valSubMode==2){valSubMode=3;} else if (valSubMode==3){valSubMode=4;} else if (valSubMode==4){valSubMode=5;} else if (valSubMode==5){valSubMode=6;} else if (valSubMode==6){ |
191 | j=52; uint8_t k=0; bitWrite(k,6,valArray[0]); bitWrite(k,5,valArray[1]); bitWrite(k,4,valArray[2]); bitWrite(k,3,valArray[3]); bitWrite(k,2,valArray[4]); bitWrite(k,1,valArray[5]); bitWrite(k,0,valArray[6]); funcSaveTimer(valTimerNum,7,k); lcd.noBlink();}} |
192 | /* " * * * * * * * " */ if (i==encLEFT ){flgDisplayUpdate=1; if (valArray[valSubMode]){valArray[valSubMode]=0;} else {valArray[valSubMode]=1;}} |
193 | /* " ^ ^ ^ ^ ^ ^ ^ " */ if (i==encRIGHT){flgDisplayUpdate=1; if (valArray[valSubMode]){valArray[valSubMode]=0;} else {valArray[valSubMode]=1;}} |
194 | break ; // Если установлен режим 63: "Меню>тайmеры>выбранный_таймер>уровень_сигнала" и управляя энкодером, можно установить уровень сигнала таймера, то ... |
195 | case 63: if (i==encPRESS){j=53; funcSaveTimer(valTimerNum,6,valArray[0]);} |
196 | /* "м>тaймep>cигнaл:" */ if (i==encLEFT ){flgDisplayUpdate=1; valArray[0]-=5; if (valArray[0]>100){valArray[0]= 5;} if (valArray[0]<5){valArray[0]=5;}} |
197 | /* " 100% " */ if (i==encRIGHT){flgDisplayUpdate=1; valArray[0]+=5; if (valArray[0]>100){valArray[0]=100;}} |
198 | break ; // |
199 | } // |
200 | if (j<255){lcd.clear(); flgDisplayUpdate=1; valMode=j;} // Если требуется сменить режим, то чистим экран, устанавливаем флаг необходимости обновления экрана flgDisplayUpdate и устанавливаем новый режим valMode |
201 | if (i==encPRESS){ while (!digitalRead(pinEncBTN)){delay(50);}} // Если была нажата кнопка энкодера, то ждём пока она не будет отпущена (с задержками по 50мс для подавления дребезга) |
202 | } // |
203 | // |
204 | // ОБНОВЛЕНИЕ ИНФОРМАЦИИ НА ДИСПЛЕЕ // |
205 | void funcDisplayUpdate(){ // |
206 | if (flgDisplayUpdate){ flgDisplayUpdate=0; // Обновление дисплея происходит только если был установлен флаг flgDisplayUpdate |
207 | switch (valMode){ // Далее действуем в зависимости от значения переменной valMode (которая хранит № текущего режима меню) |
208 | case 0: funcSetChars(35,36,37,5,3,0,time.weekday==4?18:14); // Если установлен режим 0, то загружаем символы в CGRAM лисплея в следующем порядке: 1-«1» 2-«2» 3-«3» 4-«4» 5-«г» 6-«Б» 7-«П/Ч» и выводим информацию для данного режима на дисплей ... |
209 | /* "00:00:00 " */ lcd.setCursor(0, 0); lcd.print(time.gettime( "H:i:s" )); // Выводим верхнюю строку |
210 | /* "00.00.0000г. ПН " */ lcd.setCursor(0, 1); lcd.print(time.gettime( "d.m.Y\5." )); // |
211 | lcd.setCursor(13,1); lcd.print(time.weekday==1? "\7H" :(time.weekday==2? "BT" :(time.weekday==3? "CP" :(time.weekday==4? "\7T" :(time.weekday==5? "\7T" :(time.weekday==6? "C\6" :( "BC" ))))))); |
212 | lcd.setCursor(12,0); lcd.print( " " ); valArray[4]=15; if (valArray[3]){lcd.setCursor(valArray[4],0); lcd.print( "\4" ); valArray[4]--;} if (valArray[2]){lcd.setCursor(valArray[4],0); lcd.print( "\3" ); valArray[4]--;} if (valArray[1]){lcd.setCursor(valArray[4],0); lcd.print( "\2" ); valArray[4]--;} if (valArray[0]){lcd.setCursor(valArray[4],0); lcd.print( "\1" ); valArray[4]--;} |
213 | break ; // |
214 | case 1: funcSetChars(11,15,25,9,20); // Если установлен режим 1, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2н 3ю 4Й 5Ы и выводим информацию для данного режима на дисплей ... |
215 | /* "меню: " */ lcd.setCursor(0, 0); lcd.print(F( "\1e\2\3:" )); // Выводим верхнюю строку |
216 | /* "< ТАЙМЕРЫ >" */ lcd.setCursor(0, 1); lcd.print(F( "< TA\4MEP\5 >" )); // |
217 | break ; // |
218 | case 2: funcSetChars(11,15,25,18,20); // Если установлен режим 2, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2н 3ю 4Ч 5Ы и выводим информацию для данного режима на дисплей ... |
219 | /* "меню: " */ lcd.setCursor(0, 0); lcd.print(F( "\1e\2\3:" )); // Выводим верхнюю строку |
220 | /* "< ЧАСЫ >" */ lcd.setCursor(0, 1); lcd.print(F( "< \4AC\5 >" )); // |
221 | break ; // |
222 | case 3: funcSetChars(11,15,25,4,20); // Если установлен режим 3, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2н 3ю 4Д 5Ы и выводим информацию для данного режима на дисплей ... |
223 | /* "меню: " */ lcd.setCursor(0, 0); lcd.print(F( "\1e\2\3:" )); // Выводим верхнюю строку |
224 | /* "< ВЫХОД >" */ lcd.setCursor(0, 1); lcd.print(F( "< B\5XO\4 >" )); // |
225 | break ; // |
226 | case 11: funcSetChars(15,25,17,9,21); // Если установлен режим 11, то загружаем символы в CGRAM лисплея в следующем порядке: 1н 2ю 3т 4й 5ы и выводим информацию для данного режима на дисплей ... |
227 | /* "меню>таймеры: " */ lcd.setCursor(0, 0); lcd.print(F( "me\1\2>\3a\4mep\5:" )); // Выводим верхнюю строку |
228 | /* "< 00:00-00:00-1>" */ lcd.setCursor(0, 1); lcd.print(F( "< 00:00-00:00-0>" )); // |
229 | lcd.setCursor(2, 1); lcd.print(funcReadTimer(valTimerNum,1)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,1)); |
230 | lcd.setCursor(5, 1); lcd.print(funcReadTimer(valTimerNum,2)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,2)); |
231 | lcd.setCursor(8, 1); lcd.print(funcReadTimer(valTimerNum,3)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,3)); |
232 | lcd.setCursor(11,1); lcd.print(funcReadTimer(valTimerNum,4)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,4)); |
233 | lcd.setCursor(14,1); lcd.print(funcReadTimer(valTimerNum,5)); |
234 | break ; // |
235 | case 12: funcSetChars(15,25,17,9,21,8,20); // Если установлен режим 12, то загружаем символы в CGRAM лисплея в следующем порядке: 1н 2ю 3т 4й 5ы 6Й 7Ы и выводим информацию для данного режима на дисплей ... |
236 | /* "меню>таймеры: " */ lcd.setCursor(0, 0); lcd.print(F( "me\1\2>\3a\4mep\5:" )); // Выводим верхнюю строку |
237 | /* "< НОВЫЙ ТАЙМЕР >" */ lcd.setCursor(0, 1); lcd.print(F( "< HOB\7\6 TA\6MEP >" )); // |
238 | break ; // |
239 | case 13: funcSetChars(15,25,17,9,21,22); // Если установлен режим 13, то загружаем символы в CGRAM лисплея в следующем порядке: 1н 2ю 3т 4й 5ы 6Ь и выводим информацию для данного режима на дисплей ... |
240 | /* "меню>таймеры: " */ lcd.setCursor(0, 0); lcd.print(F( "me\1\2>\3a\4mep\5:" )); // Выводим верхнюю строку |
241 | /* "< CTEPETь BCE >" */ lcd.setCursor(0, 1); lcd.print(F( "< CTEPET\6 BCE >" )); // |
242 | break ; // |
243 | case 14: funcSetChars(15,25,17,9,21,4,20); // Если установлен режим 14, то загружаем символы в CGRAM лисплея в следующем порядке: 1н 2ю 3т 4й 5ы 6Д 7Ы и выводим информацию для данного режима на дисплей ... |
244 | /* "меню>таймеры: " */ lcd.setCursor(0, 0); lcd.print(F( "me\1\2>\3a\4mep\5:" )); // Выводим верхнюю строку |
245 | /* "< ВЫХОД >" */ lcd.setCursor(0, 1); lcd.print(F( "< B\7XO\6 >" )); // |
246 | break ; // |
247 | case 21: funcSetChars(11,15,25,19,21,26); // Если установлен режим 21, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2н 3ю 4ч 5ы 6Я и выводим информацию для данного режима на дисплей ... |
248 | /* "меню>часы: " */ lcd.setCursor(0, 0); lcd.print(F( "\1e\2\3>\4ac\5:" )); // Выводим верхнюю строку |
249 | /* "< ВРЕМЯ >" */ lcd.setCursor(0, 1); lcd.print(F( "< BPEM\6 >" )); // |
250 | break ; // |
251 | case 22: funcSetChars(11,15,25,19,21,4); // Если установлен режим 22, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2н 3ю 4ч 5ы 6Д и выводим информацию для данного режима на дисплей ... |
252 | /* "меню>часы: " */ lcd.setCursor(0, 0); lcd.print(F( "\1e\2\3>\4ac\5:" )); // Выводим верхнюю строку |
253 | /* "< ДАТА >" */ lcd.setCursor(0, 1); lcd.print(F( "< \6ATA >" )); // |
254 | break ; // |
255 | case 23: funcSetChars(11,15,25,19,21,4,20); // Если установлен режим 23, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2н 3ю 4ч 5ы 6Д 7Ы и выводим информацию для данного режима на дисплей ... |
256 | /* "меню>часы: " */ lcd.setCursor(0, 0); lcd.print(F( "\1e\2\3>\4ac\5:" )); // Выводим верхнюю строку |
257 | /* "< ВЫХОД >" */ lcd.setCursor(0, 1); lcd.print(F( "< B\7XO\6 >" )); // |
258 | break ; // |
259 | case 31: funcSetChars(11,15,25,19,21,1,27); // Если установлен режим 31, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2н 3ю 4ч 5ы 6в 7я и выводим информацию для данного режима на дисплей ... |
260 | /* "меню>часы>вpeмя:" */ lcd.setCursor(0, 0); lcd.print(F( "\1e\2\3>\4ac\5>\6pe\1\7:" )); // Выводим верхнюю строку |
261 | /* " 00:00:00 " */ lcd.setCursor(4, 1); valChar[0]=valArray[0]/10+48; valChar[1]=valArray[0]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==0)? " " :valChar); lcd.print( ":" ); |
262 | lcd.setCursor(7, 1); valChar[0]=valArray[1]/10+48; valChar[1]=valArray[1]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==1)? " " :valChar); lcd.print( ":" ); |
263 | lcd.setCursor(10,1); valChar[0]=valArray[2]/10+48; valChar[1]=valArray[2]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==2)? " " :valChar); |
264 | break ; // |
265 | case 32: funcSetChars(24,18,20,4,14,0); // Если установлен режим 32, то загружаем символы в CGRAM лисплея в следующем порядке: 1Ю 2Ч 3Ы 4Д 5П 6Б и выводим информацию для данного режима на дисплей ... |
266 | /* "MEHЮ>ЧACЫ>ДATA: " */ lcd.setCursor(0, 0); lcd.print(F( "MEH\1>\2AC\3>\4ATA:" )); // Выводим верхнюю строку |
267 | /* " 00.00.0000 пт " */ lcd.setCursor(1, 1); valChar[0]=valArray[0]/10+48; valChar[1]=valArray[0]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==0)? " " :valChar); lcd.print( "." ); |
268 | lcd.setCursor(4, 1); valChar[0]=valArray[1]/10+48; valChar[1]=valArray[1]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==1)? " " :valChar); lcd.print( "." ); |
269 | lcd.setCursor(7, 1); valChar[0]= '2' ; valChar[1]= '0' ; valChar[2]=valArray[2]/10+48; valChar[3]=valArray[2]%10+48; valChar[4]=0; lcd.print((millis()%1000<500 && valSubMode==2)? " " :valChar); |
270 | lcd.setCursor(12,1); strcpy(valChar,(valArray[3]==1? "\5H" :(valArray[3]==2? "BT" :(valArray[3]==3? "CP" :(valArray[3]==4? "\2T" :(valArray[3]==5? "\5T" :(valArray[3]==6? "C\6" :( "BC" )))))))); valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==3)? " " :valChar); |
271 | break ; // |
272 | case 41: funcSetChars(20,8,4); // Если установлен режим 41, то загружаем символы в CGRAM лисплея в следующем порядке: 1Ы 2Й 3Д и выводим информацию для данного режима на дисплей ... |
273 | /* " HOBЫЙ TAЙMEP " */ lcd.setCursor(2, 0); lcd.print(F( "HOB\1\2 TA\2MEP" )); // Выводим верхнюю строку |
274 | /* " CO3ДAH " */ lcd.setCursor(5, 1); lcd.print(F( "CO3\3AH" )); // |
275 | break ; // |
276 | case 42: funcSetChars(20,8,4,16,12); // Если установлен режим 42, то загружаем символы в CGRAM лисплея в следующем порядке: 1Ы 2Й 3Д 4У 5Л и выводим информацию для данного режима на дисплей ... |
277 | /* " BCE TAЙMEPЫ " */ lcd.setCursor(2, 0); lcd.print(F( "BCE TA\2MEP\1" )); // Выводим верхнюю строку |
278 | /* " УДAЛEHЫ " */ lcd.setCursor(4, 1); lcd.print(F( "\4\3A\5EH\1" )); // |
279 | break ; // |
280 | case 43: funcSetChars(8,16,4,12); // Если установлен режим 43, то загружаем символы в CGRAM лисплея в следующем порядке: 1Й 2У 3Д 4Л и выводим информацию для данного режима на дисплей ... |
281 | /* " TAЙMEP " */ lcd.setCursor(5, 0); lcd.print(F( "TA\1MEP" )); // Выводим верхнюю строку |
282 | /* " УДAЛEH " */ lcd.setCursor(5, 1); lcd.print(F( "\2\3A\4EH" )); // |
283 | break ; // |
284 | case 51: funcSetChars(17,9,21,23,26,6,12); // Если установлен режим 51, то загружаем символы в CGRAM лисплея в следующем порядке: 1т 2й 3ы 4. 5Я 6И 7Л и выводим информацию для данного режима на дисплей ... |
285 | /* "m>тайmеры>00:00." */ lcd.setCursor(0, 0); lcd.print(F( "m>\1a\2mep\3>" )); // Выводим верхнюю строку |
286 | /* "<BPEM* * KAHA*>" */ lcd.setCursor(10,0); lcd.print(funcReadTimer(valTimerNum,1)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,1)); lcd.print( ":" ); |
287 | lcd.setCursor(13,0); lcd.print(funcReadTimer(valTimerNum,2)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,2)); lcd.print( "\4" ); |
288 | lcd.setCursor(0, 1); lcd.print(F( "<BPEM\5 \6 KAHA\7>" )); // |
289 | break ; // |
290 | case 52: funcSetChars(17,9,21,23,14,20); // Если установлен режим 52, то загружаем символы в CGRAM лисплея в следующем порядке: 1т 2й 3ы 4. 5П 6Ы и выводим информацию для данного режима на дисплей ... |
291 | /* "m>тайmеры>00:00." */ lcd.setCursor(0, 0); lcd.print(F( "m>\1a\2mep\3>" )); // Выводим верхнюю строку |
292 | /* "<ПО ДНЯМ НЕДЕЛИ>" */ lcd.setCursor(10,0); lcd.print(funcReadTimer(valTimerNum,1)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,1)); lcd.print( ":" ); |
293 | lcd.setCursor(13,0); lcd.print(funcReadTimer(valTimerNum,2)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,2)); lcd.print( "\4" ); |
294 | lcd.setCursor(0, 1); lcd.print(F( "< \5OBTOP\6 >" )); // |
295 | break ; // |
296 | case 53: funcSetChars(17,9,21,23,16,6,2); // Если установлен режим 53, то загружаем символы в CGRAM лисплея в следующем порядке: 1т 2й 3ы 4. 5У 6И 7Г и выводим информацию для данного режима на дисплей ... |
297 | /* "m>тайmеры>00:00." */ lcd.setCursor(0, 0); lcd.print(F( "m>\1a\2mep\3>" )); // Выводим верхнюю строку |
298 | /* "< УPOBEHb CИГН.>" */ lcd.setCursor(10,0); lcd.print(funcReadTimer(valTimerNum,1)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,1)); lcd.print( ":" ); |
299 | lcd.setCursor(13,0); lcd.print(funcReadTimer(valTimerNum,2)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,2)); lcd.print( "\4" ); |
300 | lcd.setCursor(0, 1); lcd.print(F( "< \5POBEHb C\6\7H.>" )); // |
301 | break ; // |
302 | case 54: funcSetChars(17,9,21,23,22,8); // Если установлен режим 54, то загружаем символы в CGRAM лисплея в следующем порядке: 1т 2й 3ы 4. 5Ь 6Й и выводим информацию для данного режима на дисплей ... |
303 | /* "m>тайmеры>00:00." */ lcd.setCursor(0, 0); lcd.print(F( "m>\1a\2mep\3>" )); // Выводим верхнюю строку |
304 | /* "<CTEPETЬ TAЙMEP>" */ lcd.setCursor(10,0); lcd.print(funcReadTimer(valTimerNum,1)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,1)); lcd.print( ":" ); |
305 | lcd.setCursor(13,0); lcd.print(funcReadTimer(valTimerNum,2)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,2)); lcd.print( "\4" ); |
306 | lcd.setCursor(0, 1); lcd.print(F( "<CTEPET\5 TA\6MEP>" )); // |
307 | break ; // |
308 | case 55: funcSetChars(17,9,21,23,20,4); // Если установлен режим 55, то загружаем символы в CGRAM лисплея в следующем порядке: 1т 2й 3ы 4. 5Ы 6Д и выводим информацию для данного режима на дисплей ... |
309 | /* "m>тайmеры>00:00." */ lcd.setCursor(0, 0); lcd.print(F( "m>\1a\2mep\3>" )); // Выводим верхнюю строку |
310 | /* "< ВЫХОД >" */ lcd.setCursor(10,0); lcd.print(funcReadTimer(valTimerNum,1)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,1)); lcd.print( ":" ); |
311 | lcd.setCursor(13,0); lcd.print(funcReadTimer(valTimerNum,2)<10? "0" : "" ); lcd.print(funcReadTimer(valTimerNum,2)); lcd.print( "\4" ); |
312 | lcd.setCursor(0, 1); lcd.print(F( "< B\5XO\6 >" )); // |
313 | break ; // |
314 | case 61: funcSetChars(11,17,9,21,1,27,10); // Если установлен режим 61, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2т 3й 4ы 5в 6я 7к и выводим информацию для данного режима на дисплей ... |
315 | /* "м>таймер>вpeмя: " */ lcd.setCursor(0, 0); lcd.print(F( "\1>\2a\3\1ep>\5pe\1\6:" )); // Выводим верхнюю строку |
316 | /* " 00:00-00:00 к0 " */ lcd.setCursor(1, 1); valChar[0]=valArray[0]/10+48; valChar[1]=valArray[0]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==0)? " " :valChar); lcd.print( ":" ); |
317 | lcd.setCursor(4, 1); valChar[0]=valArray[1]/10+48; valChar[1]=valArray[1]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==1)? " " :valChar); lcd.print( "-" ); |
318 | lcd.setCursor(7, 1); valChar[0]=valArray[2]/10+48; valChar[1]=valArray[2]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==2)? " " :valChar); lcd.print( ":" ); |
319 | lcd.setCursor(10,1); valChar[0]=valArray[3]/10+48; valChar[1]=valArray[3]%10+48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==3)? " " :valChar); |
320 | lcd.setCursor(13,1); valChar[0]=7; valChar[1]=valArray[4] +48; valChar[2]=0; lcd.print((millis()%1000<500 && valSubMode==4)? " " :valChar); |
321 | break ; // |
322 | case 62: funcSetChars(28,29,30,31,32,33,34); // Если установлен режим 62, то загружаем символы в CGRAM лисплея в следующем порядке: 1-ПН 2-ВТ 3-СР 4-ЧТ 5-ПТ 6-ВТ 7-СР и выводим информацию для данного режима на дисплей ... |
323 | /* " * * * * * * * " */ lcd.setCursor(1, 0); lcd.print( "\1 \2 \3 \4 \5 \6 \7" ); // Выводим верхнюю строку |
324 | /* " ^ ^ ^ ^ ^ ^ ^ " */ lcd.setCursor(1, 1); lcd.print(valArray[0]? "^" : " " ); lcd.setCursor(3, 1); lcd.print(valArray[1]? "^" : " " ); lcd.setCursor(5, 1); lcd.print(valArray[2]? "^" : " " ); lcd.setCursor(7, 1); lcd.print(valArray[3]? "^" : " " ); lcd.setCursor(9, 1); lcd.print(valArray[4]? "^" : " " ); lcd.setCursor(11,1); lcd.print(valArray[5]? "^" : " " ); lcd.setCursor(13,1); lcd.print(valArray[6]? "^" : " " ); |
325 | lcd.setCursor(valSubMode*2+1, 1); lcd.blink(); // |
326 | break ; // |
327 | case 63: funcSetChars(11,17,9,7,3,15,13); // Если установлен режим 63, то загружаем символы в CGRAM лисплея в следующем порядке: 1м 2т 3й 4и 5г 6н 7л и выводим информацию для данного режима на дисплей ... |
328 | /* "м>тaймep>cигнaл:" */ lcd.setCursor(0, 0); lcd.print(F( "\1>\2a\3\1ep>c\4\5\6a\7:" )); // Выводим верхнюю строку |
329 | /* " 100% " */ lcd.setCursor(6, 1); valChar[0]=valArray[0]/100+48; valChar[1]=valArray[0]%100/10+48; valChar[2]=valArray[0]%10+48; valChar[3]=0; lcd.print(valChar); lcd.print( "%" ); |
330 | break ; // |
331 | } }} // |
332 | // |
333 | // ВЫВОД СИГНАЛОВ ШИМ // |
334 | void funcSetPWM( void ){ // |
335 | static uint8_t setChanel[4] = {0,0,0,0}; // Определяем массив, каждый элемент которого соответствует уровню сигнала (от 0 до 100%) установленного на соответствующем канале |
336 | if (valMode==0){ // Если текущий режим равен 0 "Вне меню", то ... |
337 | uint8_t getChanel[4] = {0,0,0,0}; // Определяем массив, каждый элемент которого соответствует уровню сигнала (от 0 до 100%) прочитанного из октивированного таймера для соответствующего канала |
338 | uint32_t timeRTC = 0; // Определяем переменную для хранения текущего времени ввиде секунд прошедших с полуночи текущего дня (от 00:00:00) |
339 | uint32_t timeTimerStart = 0; // Определяем переменную для хранения времени старта таймера (для каждого таймера в теле цикла for) ввиде секунд прошедших с полуночи текущего дня (от 00:00:00) |
340 | uint32_t timeTimerStop = 0; // Определяем переменную для хранения времени сброса таймера (для каждого таймера в теле цикла for) ввиде секунд прошедших с полуночи текущего дня (от 00:00:00) |
341 | uint8_t timeWeekday = 0; // Определяем переменную для хранения текущего деня недели в формате: 1-ПН, 2-ВТ, 3-СР, 4-ЧТ, 5-ПТ, 6-СБ, 7-ВС |
342 | valArray[0]=valArray[1]=valArray[2]=valArray[3]=0; // В первые 4 элемента массива valArray будет записана 1, если на соответствующем канале будет установлен сигнал |
343 | timeRTC = (uint32_t) time.Hours*3600+time.minutes*60+time.seconds; // Получаем количество секунд прошедшее с полуночи текущего дня (от 00:00:00). Значения переменных объекта time являются актуальными, т.к. в данном режиме (valMode) в функции funcDisplayUpdate было обращение к функции time.gettime |
344 | timeWeekday = time.weekday; if (timeWeekday==0){timeWeekday=7;} // Получаем текущий день недели в формате: 1-ПН, 2-ВТ, 3-СР, 4-ЧТ, 5-ПТ, 6-СБ, 7-ВС |
345 | for (uint8_t i=0; i<maxTimers; i++){ // Проходим по всем таймерам, ... |
346 | if (funcReadTimer(i)){ // Если очередной таймер является установленным, то ... |
347 | if (bitRead(funcReadTimer(i,7),7-timeWeekday)){ // Если день недели повтора таймера совпал с текушим днём недели, то ... |
348 | timeTimerStart=(uint32_t)funcReadTimer(i,1)*3600+funcReadTimer(i,2)*60; // Читаем время старта очередного таймера ввиде количества секунд прошедших от полуночи текущего дня (от 00:00:00) |
349 | timeTimerStop =(uint32_t)funcReadTimer(i,3)*3600+funcReadTimer(i,4)*60; // Читаем время сброса очередного таймера ввиде количества секунд прошедших от полуночи текущего дня (от 00:00:00) |
350 | if (timeTimerStart<=timeRTC && timeRTC<timeTimerStop){ // Если текущее время находится между временем старта и сброса таймера, то ... |
351 | getChanel[funcReadTimer(i,5)-1]=funcReadTimer(i,6); // Читаем из таймера уровень сигнала который требуется установить на требуемом канале |
352 | valArray [funcReadTimer(i,5)-1]=1; // Сохраняем тот факт, что установлен сигнал на требуемом канале |
353 | } // |
354 | }}} // |
355 | if (setChanel[0]!=getChanel[0]){setChanel[0]=getChanel[0]; analogWrite(pinChanel_1, map(getChanel[0], 0,100, 0,255));} // выводим ШИМ на 1 канал |
356 | if (setChanel[1]!=getChanel[1]){setChanel[1]=getChanel[1]; analogWrite(pinChanel_2, map(getChanel[1], 0,100, 0,255));} // выводим ШИМ на 2 канал |
357 | if (setChanel[2]!=getChanel[2]){setChanel[2]=getChanel[2]; analogWrite(pinChanel_3, map(getChanel[2], 0,100, 0,255));} // выводим ШИМ на 3 канал |
358 | if (setChanel[3]!=getChanel[3]){setChanel[3]=getChanel[3]; analogWrite(pinChanel_4, map(getChanel[3], 0,100, 0,255));} // выводим ШИМ на 4 канал |
359 | } // |
360 | } // |
361 | // ЗАПИСЬ ДО 7 СИМВОЛОВ В CGRAM ДИСПЛЕЯ // |
362 | void funcSetChars(uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7){ byte i[8]; |
363 | if (i1<255){memcpy_P(i, rusMem[i1], 8); lcd.createChar(1, i);} // Записываем символ i (взятый из элемента № i1 массива rusMem хранящегося в PROGMEM Arduino) в CGRAM дисплея под номером 1 |
364 | if (i2<255){memcpy_P(i, rusMem[i2], 8); lcd.createChar(2, i);} // Записываем символ i (взятый из элемента № i2 массива rusMem хранящегося в PROGMEM Arduino) в CGRAM дисплея под номером 2 |
365 | if (i3<255){memcpy_P(i, rusMem[i3], 8); lcd.createChar(3, i);} // Записываем символ i (взятый из элемента № i3 массива rusMem хранящегося в PROGMEM Arduino) в CGRAM дисплея под номером 3 |
366 | if (i4<255){memcpy_P(i, rusMem[i4], 8); lcd.createChar(4, i);} // Записываем символ i (взятый из элемента № i4 массива rusMem хранящегося в PROGMEM Arduino) в CGRAM дисплея под номером 4 |
367 | if (i5<255){memcpy_P(i, rusMem[i5], 8); lcd.createChar(5, i);} // Записываем символ i (взятый из элемента № i5 массива rusMem хранящегося в PROGMEM Arduino) в CGRAM дисплея под номером 5 |
368 | if (i6<255){memcpy_P(i, rusMem[i6], 8); lcd.createChar(6, i);} // Записываем символ i (взятый из элемента № i6 массива rusMem хранящегося в PROGMEM Arduino) в CGRAM дисплея под номером 6 |
369 | if (i7<255){memcpy_P(i, rusMem[i7], 8); lcd.createChar(7, i);} // Записываем символ i (взятый из элемента № i7 массива rusMem хранящегося в PROGMEM Arduino) в CGRAM дисплея под номером 7 |
370 | } // |
371 | // ЧТЕНИЕ ОДНОГО ИЗ ПАРАМЕТРОВ ТАЙМЕРА // |
372 | uint8_t funcReadTimer(uint8_t i, uint8_t j){ return EEPROM[i*8+j];} // |
373 | // ПОИСК НОВОГО ТАЙМЕРА // |
374 | uint8_t funcFindTimer( void ){uint8_t i=0; while (funcReadTimer(i)){i++; if (i>=maxTimers){ break ;}} return i;} |
375 | // СОХРАНЕНИЕ ОДНОГО ИЗ ПАРАМЕТРОВ ТАЙМЕРА // |
376 | void funcSaveTimer(uint8_t i, uint8_t j, uint8_t k){EEPROM[i*8+j]=k;} // |
377 | // ПРОВЕРКА ДАННЫХ ТАЙМЕРОВ В EEPROM // |
378 | bool funcTestTimer( void ){ for (uint8_t i=0; i<maxTimers; i++){ if (funcReadTimer(i,0)>1){ return false ;} if (funcReadTimer(i,1)>23){ return false ;} if (funcReadTimer(i,2)>59){ return false ;} if (funcReadTimer(i,3)>23){ return false ;} if (funcReadTimer(i,4)>59){ return false ;}} return true ;} |
Я совсем не уверен что датчик влажности и датчик дождя это одно и то же.
Например у меня в системе заводской датчик дождя выглядит
как пачка пластин которые намокают и разбухают просто нажимая микрик.
И высыхают.
При этом всё происходит достаточно медленно.
То есть ведут себя как почва.
Программа, скорее всего, написана кубиками. За одно это дописывание обойдётся в $100.
дешевле новую программу написать, чем в такой простыне разбираться.
если будет внятное полное тз - пишите 7808543@gmail.com
htpicc@gmail.com
Если писать не кубиками, программа будет раз в пять короче.
1000р
kakmycmail@gmail.com
Бесплатный совет ТСу. Единственный способ использовать датчик влажности для ухода за газоном, это заглубить его сантиметров на 30. Датчик дождя вообще противопоказан газону. Там множество погодных факторов влияет, но дождь в их число попадает только в том случае, если выпало за сутки 15-20 мм, а это редкость. Мониторить нужно температуру воздуха и инсоляцию в первую очередь. Исходя из этих показателей, сезона и из особенностей почвы устанавливать режим и норму полива, которая летом может составлять 10-25 литром на м2 в сутки. И да, газон должен проливаться сантиметров на 30-40 сразу, потом время на подсушку верних 10-15 см и снова обильный пролив. Иначе дернина будет слабенькая
Датчик такой?
Судя по моим датчикам (DHT20 и BME280 с али) - достаточно просто выдохнуть даже не на них, а просто рядом - у них уже показания подпрыгивают. Это даже если без перегара. ;)
Спасибо.
Датчик влажности хочу подключить к этому скетчу для того что бы к примеру во время дождя не происходил полив газона....
Да, Такой
Имхо - достаточно его положить на грунт и накрыть сверху каким-нить колпаком.
Показывать влажность он будет. Но если на этих показаниях построить логику управления поливом - газону хана.