Ви не увійшли.
Сторінки 1
Всем привет! У меня есть уже готовый проект.Он работает и реализован в железе. В двух словах это суточное реле времени на 3 канала которое включает и выключает нагрузку 12v. в определеное время. проблема в том что минимальное время работы таймера 1 мин. а для меня это много.( Видимо так в скетче прописано.А так как не я писал код я не знаю как это изменить) Нужно переделать время включения от 1 сек. с возможностью регулировки. Вся схема управляется через энкодер.
Вопрос такой: насколько сложно это переписать? Сколько это стоит?
Неактивний
Для ответа на вопрос сначала нужно увидеть код
куда его можно скинуть?
Над формой ответа есть кнопочка с надписью Code. Сюда и вставляйте
#include <avr/pgmspace.h> // Подключаем библиотеку для работы с PROGMEM Arduino для хранения символов индикаторов
#include <EEPROM.h> // Подключаем библиотеку для работы с EEPROM Arduino для хранения счетчиков таймеров
#include <Wire.h> // Подключаем библиотеку для работы с шиной I2C
#include <LiquidCrystal_I2C.h> // Подключаем библиотеку для работы с ЖК-дисплеем по блестящему I2C
#include <iarduino_Encoder_tmr.h> // Подключаем плагин iarduino_Encoder_tmr для работы с энкодерами через аппаратный таймер
#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с часами реального времени
// ОБЪЯВЛЯЕМ КОНСТАНТЫ КОТОРЫЕ МОЖНО РЕДАКТИРОВАТЬ: //
#define pinEncA 2 // Определяем константу с ключом № вывода Arduino к этому подключённому выводу «A» энкодера
#define pinEncB 3 // Определяем константу с ключом № вывода Arduino к этому подключённому выводу «B» энкодера
#define pinEncBTN 4 // Определяем константу с кодом № вывода Arduino к этому подключённому выводу «S» энкодера (кнопка)
#define pinChanel_1 5 // Определяем константу с номером вывода Arduino, который будет являться выводом 1 канала (указываются только выводы с ШИМ, кроме выводов подключения 2 таймером Arduino)
#define pinChanel_2 6 // Определяем константу с номером вывода Arduino, который будет проявляться выводом 2 канала (указываются только выводы с ШИМ, кроме выводов подключения 2 таймером Arduino)
#define pinChanel_3 9 // Определяем константу с номером вывода Arduino, который будет являться выводом 3 канала (указываются только выводы с ШИМ, кроме выводов подключения 2 таймером Arduino)
#define pinChanel_4 10 // Определяем константу с номером вывода Arduino, который будет являться выводом 4 канала (указываются только выводы с ШИМ, кроме выводов вывода 2 таймером Arduino)
#define maxTimers 20 // Определяем константу с указанием максимального количества таймеров. Число не должно превышать количество байт EEPROM/8 (для Arduino Uno максимальное значение 128)
// ОБЪЯВЛЯЕМ КОНСТАНТЫ И ПЕРЕМЕННЫЕ НЕОБХОДИМЫЕ ДЛЯ РАБОТЫ СКЕТЧА: //
const byte rusMem[38][8] PROGMEM = { // Определяем массив в области памяти программ, каждый элемент которого является матрицей (еще одним массивом) представление символа на дисплее
{ 31, 16, 16, 30, 17, 17, 30, 0 },
{ 0, 0, 30, 17, 30, 17, 30, 0 }, // Б, в, № матрицы символа в массиве: 00, 01
{ 31, 16, 16, 16, 16, 16, 16, 0 },
{ 0, 0, 30, 16, 16, 16, 16, 0 }, // Г, г, № матрицы символа в массиве: 02, 03
{ 6, 10, 10, 10, 10, 10, 31, 17 },
{ 10, 10, 14, 2, 2, 0, 0, 0 }, // Д, 4, № матрицы символа в массиве: 04, 05
{ 17, 17, 17, 19, 21, 25, 17, 0 },
{ 0, 0, 17, 19, 21, 25, 17, 0 }, // И, и, № матрицы символа в массиве: 06, 07
{ 21, 17, 17, 19, 21, 25, 17, 0 },
{ 10, 4, 17, 19, 21, 25, 17, 0 }, // Й, й, № матрицы, символа в массиве: 08, 09
{ 0, 0, 18, 20, 24, 20, 18, 0 },
{ 0, 0, 17, 27, 21, 17, 17, 0 }, // к, м, № матрицы символа в массиве: 10, 11
{ 7, 9, 9, 9, 9, 9, 17, 0 },
{ 0, 0, 7, 9, 9, 9, 17, 0 }, // Л, л, № матрицы, символа в массиве: 12, 13
{ 31, 17, 17, 17, 17, 17, 17, 0 },
{ 0, 0, 17, 17, 31, 17, 17, 0 }, // П н, № матрицы символа в массиве: 14, 15
{ 17, 17, 17, 15, 1, 17, 14, 0 },
{ 0, 0, 31, 4, 4, 4, 4, 0 }, // У, т, № матрицы, символа в массиве: 16, 17
{ 17, 17, 17, 15, 1, 1, 1, 0 },
{ 0, 0, 17, 17, 15, 1, 1, 0 }, // Ч, ч, № матрицы, символа в массиве: 18, 19
{ 17, 17, 17, 29, 19, 19, 29, 0 },
{ 0, 0, 17, 17, 29, 19, 29, 0 }, // Ы, ы, № символа матрицы в массиве: 20, 21
{ 16, 16, 16, 30, 17, 17, 30, 0 },
{ 0, 0, 0, 0, 0, 0, 21, 0 }, // Ь, ..., № матрицы, символа в массиве: 22, 23
{ 18, 21, 21, 29, 21, 21, 18, 0 },
{ 0, 0, 18, 21, 29, 21, 18, 0 }, // Ю, ю, № матрицы символа в массиве: 24, 25
{ 15, 17, 17, 15, 5, 9, 17, 0 },
{ 0, 0, 15, 17, 15, 5, 9, 0 }, // Я, я, № матрицы символа в массиве: 26, 27
{ 31, 4, 31, 0, 31, 16, 31, 0 },
{ 16, 31, 16, 0, 10, 21, 31, 0 }, // ПН, ВТ № матрицы, символа в массиве: 28, 29
{ 28, 20, 31, 0, 17, 17, 31, 0 },
{ 16, 31, 16, 0, 31, 4, 28, 0 }, // СР, ЧТ № символа матрицы в массиве: 30, 31
{ 16, 31, 16, 0, 31, 16, 31, 0 },
{ 23, 21, 31, 0, 17, 17, 31, 0 }, // ПТ, СБ № матрицы, символа в массиве: 32, 33
{ 17, 17, 31, 0, 10, 21, 31, 0 },
{ 4, 12, 4, 4, 14, 0, 0, 0 }, // ВС, 1 № матрицы символа в массиве: 34, 35
{ 14, 2, 14, 8, 14, 0, 0, 0 },
{ 14, 2, 14, 2, 14, 0, 0, 0 }
}; // 2, 3 № матрицы, символа в массиве: 36, 37
uint8_t valArray[7] = { 0, 0, 0, 0, 0, 0, 0 }; // Определяем элементы массива, которые будут хранить различную информацию в зависимости от режима
uint32_t мс;
char valChar[5] = " "; // Определим символы массива (строку), информацию, которая будет использоваться в физическом языке на дисплее мигая.
uint8_t valMode = 0; // Определяем переменную для хранения текущего режима (например: режим 31 - установка времени)
uint8_t valSubMode = 0; // Определим переменную для хранения текущего режима подрежима (например: режим 31, подрежим 0 - установка часов, подрежим 1 - установка минут, подрежим 2 - установка секунд)
uint8_t valTimerNum = 0; // Определяем переменную для хранения номера таймера (от 0 до maxTimers-1)
bool flgDisplayUpdate = 1; // Определяем флаговую переменную, установка которой будет сигнализировать о необходимости обновления дисплея
недействительный funcEncoderRead (недействительный); // Объявляем функцию, в которой будут выполняться действия определения от состояния энкодера и режима
недействительный funcDisplayUpdate (недействительный); // Объявляем функцию, в которой будет обновляться информация дисплея в зависимости от режима, подрежима, плотности таймера и результатов массива valArray
недействительный funcSetPWM (недействительный); // Объявляем функцию, которая будет сохранять сигналы ШИМ на каналах, если время тока совпало с таймерами таймеров
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
uint8_t funcReadTimer(uint8_t = 0, uint8_t = 0); // Объявляем функцию для чтения одного из параметров таймера (№ таймера, № параметра)
void funcSaveTimer(uint8_t = 0, uint8_t = 0, uint8_t = 0); // Объявляем функцию для записи одного из параметров таймера (№ таймера, № параметра, значение параметра)
uint8_t funcFindTimer (недействительный); // Объявляем функцию для поиска № следующего свободного (не установленного) таймера
bool funcTestTimer (недействительный); // Объявляем функцию для проверки соответствия данных в ячейках EEPROM значениям таймеров Arduino (если скетч запускается первоначально, то данные в ячейках не соответствуют значениям таймеров и можно будет подготовить EEPROM к первому запуску скетча)
LiquidCrystal_I2C ЖК (0x27, 16, 2); // Объявляем объект lcd для работы с отображением указателя (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2)
iarduino_Encoder_tmr enc(pinEncA, pinEncB); // Объявляем объект enc для работы с энкодером указывая (№ вывода A, № вывода B)
время iarduino_RTC (RTC_DS1307); // Объявляем время объекта для работы с часами RTC указывая (тип модуля)
#define encPRESS 2 // Определяем константу для удобочитаемости при определении состояния энкодера
недействительная настройка() {
enc.begin(); // Инициируемая работа с энкодером
время.begin(); // Инициируемая работа с модулем RTC
pinMode(pinEncBTN, INPUT); // Переводим вывод с ключом энкодера в режим входа
pinMode (pinChanel_1, ВЫХОД); // Переводим вывод 1 канала в режим выхода
pinMode (pinChanel_2, ВЫХОД); // Переводим вывод 2 канала в режим выхода
pinMode (pinChanel_3, ВЫХОД); // Переводим вывод 3 канала в режим выхода
pinMode (pinChanel_4, ВЫХОД); // Переводим вывод 4 канала в режим выхода
ЖК.инит(); // Инициируемая работа с ЖК-дисплеем
ЖК.подсветка(); // Включаем подсветку LCD дисплея
funcSetChars(12, 6); // Загружаем элементы 12 и 6 массива rusMem в память CGRAM LCD дисплея. Эти элементы содержат графическое представление символов: «Л» и «И».
lcd.setCursor(0, 0); // Устанавливаем курсор в верхний левый угол экрана (0 столбец, 0 строк)
lcd.print(F(" PE1E BPEMEH2")); // Выводим надпись «PEЛE BPEMEHИ». Буквы «L» и «I» заменяются знаками «» и №, в соответствии с которыми их графические изображения были загружены в память ЖК-дисплея CGRAM.
// lcd.setCursor(5, 1); // Устанавливаем курсор в 5 столбцов 1 строки (нумерация начинается с 0)
// lcd.print(F("iarduino.ru")); // Выводим надпись «iarduino.ru».
задержка (2000); // Ждём, что бы надпись отображаемую на дисплее удалось прочитать
ЖК.Очистить(); // Чистим экран,
if (!funcTestTimer()) { // Если значения в EEPROM не соответствуют значениям таймера (например, первый запуск данного скетча), то ...
funcSetChars(14, 4, 2); // Загружаем элементы 14, 4 и 2 массива rusMem в память CGRAM LCD дисплея. Эти элементы содержат графическое представление символов: «П», «Д» и «Г».
lcd.setCursor(0, 0); // Устанавливаем курсор в верхний левый угол экрана (0 столбец, 0 строк)
lcd.print(F("1O23ОТОБКА...")); // Выводим надпись «ПОДГОТОВКА...». Буквы «П», «Д» и «Г» заменяются знаком «» и №, в соответствии с которыми их графические представления загружены в память CGRAM ЖК-дисплея.
for (uint8_t i = 0; i < maxTimers; i++) { // Проходим по всем возможным таймерам
for (uint8_t j = 0; j < 8; j++) { // Проходим по всем возможным параметрам каждого таймера
funcSaveTimer (я, j, 0); // Обнуляем все возможные параметры каждого таймера
}
}
задержка(1000);
ЖК.Очистить(); // Ждём, что бы надпись отображаемую на дисплее удалось прочитать, а потом почистим экран
}
}
недействительный цикл() {
мс = миллис();
funcEncoderRead(); // Выполняем действие в соответствии с состоянием энкодера и режимом valMode
funcDisplayUpdate(); // Обновляем информацию на дисплее в соответствии с режимом valMode и только если установлен флаг flgDisplayUpdate
funcSetPWM(); // Выводим ШИМ
}
// ВЫПОЛНЕНИЕ ДЕЙСТВИЯ ПРИ ИЗМЕНЕНИЯХ СОТОЯНИЯ ЭНКОДЕРА И В ЗАВИСИМОСТИ ОТ ТЕКУЩЕГО РЕЖИМА //
недействительный funcEncoderRead (недействительный) {
статический uint32_t msBtn = 0;
статический bool btn = ложь;
int я = enc.read(); // Определяем переменную i в которой читаем состояние энкодера (может принять 1 из 3 результатов: 0, encLEFT, encRIGHT а далее к ним еще прибавится и значение encPRESS)
интервал j = 255; // Определим переменную j для хранения № режима меню, в котором необходимо перейти (значение 255 означает, что переход в другой режим не требуется)
если (!digitalRead(pinEncBTN)) {
if (!btn && ms - msBtn > 50) {
я = энкПРЕСС;
БТН = правда;
}
} // Если нажать кнопку энкодера, то можно установить переменную i в значение encPRESS
еще {
БТН = ложь;
мсБтн = мс;
}
switch (valMode) { // Далее действует в зависимости от значения переменной valMode (которая хранит № текущего режима меню)
случай 0:
если (я == encPRESS) {
j = 1;
} // Если установлен режим 0 "Вне меню", то ...
/* "00:00:00" */
flgDisplayUpdate = 1; // Устанавливаем флаг flgDisplayUpdate сигнализирующий о необходимости обновления информации на дисплее
/* "00.00.0000 ХХ" */
перерыв;
Дело 1:
если (я == encPRESS) {
j = funcReadTimer()? 11:12;
валТимерНум = 0;
} // Если установлен режим 1: «Меню» и кнопки на энкодер, можно выбрать пункт «ТАЙМЕРЫ», то ...
/* "меню: " */
если (я == encLEFT) {
j = 3;
} // Если энкодер поворачивается влево, то переходим в режим 3
/* "< ТАЙМЕРЫ >" */
если (я == encRIGHT) {
j = 2;
} // Если энкодер поворачивается вправо, то переходим в режим 2
перерыв;
случай 2:
если (я == encPRESS) {
j = 21;
} // Если установлен режим 2: «Меню» и кнопки на энкодер, можно выбрать пункт «ЧАСЫ», то...
/* "меню: " */
если (я == encLEFT) {
j = 1;
} // Если энкодер поворачивается влево, то переходим в режим 1
/* "< ЧАСЫ >" */
если (я == encRIGHT) {
j = 3;
} // Если энкодер поворачивается вправо, то переходим в режим 3
перерыв;
// Если установлен режим 3: «Меню» и кнопки на энкодер, можно выбрать пункт «ВЫХОД», то ...
случай 3:
если (я == encPRESS) {
j = 0;
valArray[0] = valArray[1] = valArray[2] = valArray[3] = 0;
}
/* "меню: " */
если (я == encLEFT) {
j = 2;
} // Если энкодер поворачивается влево, то переходим в режим 2
/* "< ВЫХОД >" */
если (я == encRIGHT) {
j = 1;
} // Если энкодер поворачивается вправо, то переходим в режим 1
перерыв;
случай 11:
если (я == encPRESS) {
j = 51;
} // Если установлен режим 11: «Меню>таймеры» и кнопки на энкодер, можно выбрать один из таймеров, то...
/* "меню>таймеры: " */
если (я == encLEFT) {
если (valTimerNum) {
valTimerNum--;
ЖК.Очистить();
flgDisplayUpdate = 1;
} еще {
j = 14;
}
}
/* "< 00:00-00:00-1>" */
если (я == encRIGHT) {
валТимерНум++;
if (valTimerNum >= maxTimers) {
j = 13;
} Еще если (funcReadTimer(valTimerNum)) {
ЖК.Очистить();
flgDisplayUpdate = 1;
} еще {
j = 12;
}
}
перерыв;
случай 12:
если (я == encPRESS) {
j = 41;
} // Если установлен режим 12: «Меню>таймеры» и кнопки на энкодер, можно выбрать пункт «НОВЫЙ ТАЙМЕР», то ...
/* "меню>таймеры: " */
если (я == encLEFT) {
j = funcReadTimer()? 11:14;
если (funcReadTimer()) {
valTimerNum = funcFindTimer() - 1;
}
}
/* "< НОВЫЙ ТАЙМЕР >" */
если (я == encRIGHT) {
j = funcReadTimer()? 13:14;
} // Если энкодер поворачивается вправо, то переходим в режим 13 или 14 (зависит от приложения установленных таймеров)
перерыв;
случай 13:
если (я == encPRESS) {
j = 42;
} // Если установлен режим 13: «Меню>таймеры» и кнопки на энкодер, можно выбрать пункт «CTEPETЬ BCE ТАЙМЕРЫ», то ...
/* "меню>таймеры: " */
если (я == encLEFT) {
j = funcFindTimer() <maxTimers? 12:11;
valTimerNum = j == 11? МаксТаймерс — 1:0;
}
/* "< CTEPETЬ BCE >" */
если (я == encRIGHT) {
j = 14;
валТимерНум = 0;
} // Если энкодер поворачивается вправо, то переходим в режим 14 и указываем, что выбран таймер № 0
перерыв;
случай 14:
если (я == encPRESS) {
j = 1;
} // Если установлен режим 14: "Меню>таймеры" и кнопки на энкодер, можно выбрать пункт "ВЫХОД", то...
/* "меню>таймеры: " */
если (я == encLEFT) {
j = funcReadTimer()? 13: (funcFindTimer() <maxTimers? 12: 11);
валТимерНум = 0;
}
/* "< ВЫХОД >" */
если (я == encRIGHT) {
j = funcReadTimer()? 11: (funcFindTimer() <maxTimers? 12: 13);
валТимерНум = 0;
}
перерыв;
// Если установлен режим 21: «Меню>часы» и кнопки на энкодер, можно выбрать пункт «ВРЕМЯ», то ...
случай 21:
если (я == encPRESS) {
j = 31;
валСубрежим = 0;
время.gettime();
valArray[0] = время.Часы;
valArray[1] = время.минуты;
valArray[2] = время.секунды;
}
/* "меню>часы: " */
если (я == encLEFT) {
j = 23;
} // Если энкодер поворачивается влево, то переходим в режим 23
/* "< ВРЕМЯ >" */
если (я == encRIGHT) {
j = 22;
} // Если энкодер поворачивается вправо, то переходим в режим 22
перерыв;
// Если установлен режим 22: «Меню>часы» и кнопки на энкодер, можно выбрать пункт «ДАТА», то ...
случай 22:
если (я == encPRESS) {
j = 32;
валСубрежим = 0;
время.gettime();
valArray[0] = время.день;
valArray[1] = время.месяц;
valArray[2] = время.год;
valArray[3] = время.день недели;
}
/* "меню>часы: " */
если (я == encLEFT) {
j = 21;
} // Если энкодер поворачивается влево, то переходим в режим 21
/* "< ДАТА >" */
если (я == encRIGHT) {
j = 23;
} // Если энкодер поворачивается вправо, то переходим в режим 23
перерыв;
случай 23:
если (я == encPRESS) {
j = 2;
} // Если установлен режим 23: «Меню>часы» и нажать на энкодер, можно выбрать пункт «ВЫХОД», то ...
/* "меню>часы: " */
если (я == encLEFT) {
j = 22;
} // Если энкодер поворачивается влево, то переходим в режим 22
/* "< ВЫХОД >" */
если (я == encRIGHT) {
j = 21;
} // Если энкодер поворачивается вправо, то переходим в режим 21
перерыв;
// Если установлен режим 31: "Меню>часы>впемя" и управляя энкодером, можно установить время, чтобы ...
случай 31:
если (я == encPRESS) {
если (valSubMode == 0) {
валСубрежим = 1;
} еще если (valSubMode == 1) {
валСубрежим = 2;
} еще если (valSubMode == 2) {
time.settime(valArray[2], valArray[1], valArray[0]);
j = 21;
}
}
/* "меню>часы>впемя:" */
если (я == encLEFT) {
valArray[valSubMode] --;
если (valArray[0] > 23) {
valArray[0] = 23;
}
если (valArray[1] > 59) {
valArray[1] = 59;
}
если (valArray[2] > 59) {
valArray[2] = 59;
}
}
/* " 00:00:00 " */
если (я == encRIGHT) {
valArray[valSubMode]++;
если (valArray[0] > 23)
valArray[0] = 0;
если (valArray[1] > 59)
valArray[1] = 0;
если (valArray[2] > 59)
valArray[2] = 0;
}
flgDisplayUpdate = 1; // Установим флаг flgDisplayUpdate сигнализирующий о необходимости обновить информацию на дисплее
перерыв;
// Если установлен режим 32: «Меню>часы>дата» и управление энкодером, можно установить метки, то ...
случай 32:
если (я == encPRESS) {
если (valSubMode == 0)
валСубрежим = 1;
иначе, если (valSubMode == 1)
валСубрежим = 2;
иначе, если (valSubMode == 2)
валСубрежим = 3;
иначе если (valSubMode == 3) {
time.settime(-1, -1, -1, valArray[0], valArray[1], valArray[2], valArray[3]);
j = 22;
}
}
/* "MEHЮ>ЧАСЫ>ДАННЫЕ: " */
если (я == encLEFT) {
valArray[valSubMode] --;
если (valArray[0] == 0)
valArray[0] = 31;
если (valArray[1] == 0)
valArray[1] = 12;
если (valArray[2] > 99)
valArray[2] = 99;
если (valArray[3] > 6)
valArray[3] = 6;
}
/* "00.00.0000 пт" */
если (я == encRIGHT) {
valArray[valSubMode]++;
если (valArray[0] > 31)
valArray[0] = 1;
если (valArray[1] > 12)
valArray[1] = 1;
если (valArray[2] > 99)
valArray[2] = 0;
если (valArray[3] > 6)
valArray[3] = 0;
}
flgDisplayUpdate = 1; // Устанавливаем флаг flgDisplayUpdate сигнализирующий о необходимости обновления информации на дисплее
перерыв;
случай 41:
// Если установлен режим 41: "HOBЫЙ ТАЙМЕП CO3ДАH", то данный режим сбрасывается в режим 61 через 2 секунды вне зависимости от состояния энкодера ...
/* " ХОБЫЙ ТАЙМЕП " */
j = 61;
valTimerNum = funcFindTimer();
валСубрежим = 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);
/* " CO3ДАH " */
задержка (2000);
перерыв;
случай 42:
// Если установлен режим 42: "BCE ТАЙМЕПЫ УДАЛЕХЫ", то данный режим сбрасывается в режим 12 через 2 секунды вне зависимости от состояния энкодера ...
/* "BCE ТАЙМЕПЫ" */
j = 12;
for (valArray[0] = 0; valArray[0] < maxTimers; valArray[0]++) {
funcSaveTimer(valArray[0]);
}
/* " УДАЛЕХЫ " */
задержка (2000);
перерыв;
случай 43:
// Если установлен режим 43: "ТАЙМЕП УДАЛЕХ", то данный режим сбрасывается в режим 11 или 12 через 2 секунды вне зависимости от состояния энкодера ...
/* " ТАЙМЕП " */
j = 12;
valArray[0] = valTimerNum;
valArray[1] = funcFindTimer() - 1;
если (valArray[0] < valArray[1]) {
j = 11;
valTimerNum = valArray[0];
} иначе если (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]);
/* " УДАЛЕХ " */
задержка (2000);
перерыв;
// Если установлен режим 51: "Меню>таймеры>выбранный_таймер" и нажмите на энкодер, можно выбрать пункт "БПЕМЯ И КАХАЛ", то...
случай 51:
если (я == encPRESS) {
j = 61;
валСубрежим = 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);
}
/* "m>таймеры>00:00." */
если (я == влево)
j = 55; // Если энкодер поворачивается влево, то переходим в режим 55
/* "<БПЕМЯ И КАХАЛ>" */
если (я == encRIGHT)
j = 52; // Если энкодер поворачивается вправо, то переходим в режим 52
перерыв;
// Если установлен режим 52: "Меню>таймеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "ПОБТОПЫ", то...
случай 52:
если (я == encPRESS) {
j = 62;
валСубрежим = 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);
}
/* "m>таймеры>00:00." */
если (я == влево)
j = 51; // Если энкодер поворачивается влево, то переходим в режим 51
/* "< ПОБТОПЫ >" */
если (я == encRIGHT)
j = 53; // Если энкодер поворачивается вправо, то переходим в режим 53
перерыв;
// Если установлен режим 53: "Меню>таймеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "УПОБЕХЬ ЦИГНАЛА", то ...
случай 53:
если (я == encPRESS) {
j = 63;
valArray[0] = funcReadTimer(valTimerNum, 6);
}
/* "m>таймеры>00:00." */
если (я == влево)
j = 52; // Если энкодер поворачивается влево, то переходим в режим 52
/* "< УPOBEHb CIGN.>" */
если (я == encRIGHT)
j = 54; // Если энкодер поворачивается вправо, то переходим в режим 54
перерыв;
случай 54:
если (я == encPRESS)
j = 43; // Если установлен режим 54: "Меню>таймеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "CTEPETЬ ТАЙМЕП", то ...
/* "m>таймеры>00:00." */
если (я == влево)
j = 53; // Если энкодер поворачивается влево, то переходим в режим 53
/* "<CTEPETЬ ТАЙМЕП>" */
если (я == encRIGHT)
j = 55; // Если энкодер поворачивается вправо, то переходим в режим 55
перерыв;
случай 55:
если (я == encPRESS)
j = 11; // Если установлен режим 55: "Меню>таймеры>выбранный_таймер" и нажав на энкодер, можно выбрать пункт "ВЫХОД", то...
/* "m>таймеры>00:00." */
если (я == влево)
j = 54; // Если энкодер поворачивается влево, то переходим в режим 54
/* "< ВЫХОД >" */
если (я == encRIGHT)
j = 51; // Если энкодер поворачивается вправо, то переходим в режим 51
перерыв;
// Если установлен режим 61: "Меню>таймеры>выбранный_таймер>время_и_канал" и управляя энкодером, можно установить время и таймер канала, чтобы ...
случай 61:
если (я == encPRESS) {
если (valSubMode == 0)
валСубрежим = 1;
иначе, если (valSubMode == 1)
валСубрежим = 2;
иначе, если (valSubMode == 2)
валСубрежим = 3;
иначе, если (valSubMode == 3)
валСубрежим = 4;
иначе если (valSubMode == 4) {
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]);
}
}
/* "м>таймер>впемя: " */
если (я == encLEFT) {
valArray[valSubMode] --;
если (valArray[0] > 23)
valArray[0] = 23;
если (valArray[1] > 59)
valArray[1] = 59;
если (valArray[2] > 23)
valArray[2] = 23;
если (valArray[3] > 59)
valArray[3] = 59;
если (valArray[4] == 0)
valArray[4] = 4;
}
/* " 00:00-00:00 к0 " */
если (я == encRIGHT) {
valArray[valSubMode]++;
если (valArray[0] > 23)
valArray[0] = 0;
если (valArray[1] > 59)
valArray[1] = 0;
если (valArray[2] > 23)
valArray[2] = 0;
если (valArray[3] > 59)
valArray[3] = 0;
если (valArray[4] > 4)
valArray[4] = 1;
}
flgDisplayUpdate = 1; // Устанавливаем флаг flgDisplayUpdate сигнализирующий о необходимости обновления информации на дисплее
перерыв;
//Есть выбранный режим 62: "Меню>таймеры>выбранный_таймер>повторы" и управляя энкодером, можно установить повторы таймера, чтобы ...
случай 62:
если (я == encPRESS) {
flgDisplayUpdate = 1;
если (valSubMode == 0)
валСубрежим = 1;
иначе, если (valSubMode == 1)
валСубрежим = 2;
иначе, если (valSubMode == 2)
валСубрежим = 3;
иначе, если (valSubMode == 3)
валСубрежим = 4;
иначе, если (valSubMode == 4)
валСубрежим = 5;
иначе, если (valSubMode == 5)
валСубрежим = 6;
иначе если (valSubMode == 6) {
j = 52;
uint8_t k = 0;
bitWrite(к, 6, valArray[0]);
bitWrite(к, 5, valArray[1]);
bitWrite(к, 4, valArray[2]);
bitWrite(к, 3, valArray[3]);
bitWrite(k, 2, valArray[4]);
bitWrite(k, 1, valArray[5]);
bitWrite(к, 0, valArray[6]);
funcSaveTimer (valTimerNum, 7, k);
ЖК.noBlink();
}
}
/* " * * * * * * * " */
если (я == encLEFT) {
flgDisplayUpdate = 1;
если (valArray[valSubMode])
valArray[valSubMode] = 0;
еще
valArray[valSubMode] = 1;
}
/* " ^ ^ ^ ^ ^ ^ ^ " */
если (я == encRIGHT) {
flgDisplayUpdate = 1;
если (valArray[valSubMode])
valArray[valSubMode] = 0;
еще
valArray[valSubMode] = 1;
}
перерыв;
// Если установлен режим 63: "Меню>таймеры>выбранный_таймер>уровень_сигнала" и управляя энкодером, можно установить уровень сигнала таймера, чтобы ...
случай 63:
если (я == encPRESS) {
j = 53;
funcSaveTimer(valTimerNum, 6, valArray[0]);
}
/* "м>таймеп>сигнал:" */
если (я == encLEFT) {
flgDisplayUpdate = 1;
valArray[0] -= 5;
если (valArray[0] > 100)
valArray[0] = 5;
если (valArray[0] <5)
valArray[0] = 5;
}
/* " 100% " */
если (я == encRIGHT) {
flgDisplayUpdate = 1;
valArray[0] += 5;
если (valArray[0] > 100)
valArray[0] = 100;
}
перерыв;
}
если (j < 255) {
ЖК.Очистить();
flgDisplayUpdate = 1;
valMode = j;
}
// Если требуется сменить режим, почистить экран, установить флаг Необходимо обновить экран flgDisplayUpdate и установить новый режим valMode
если (я == encPRESS) {
в то время как (digitalRead (pinEncBTN)) {
задержка(50);
}
} // Если была нажата кнопка энкодера, то ждём пока она не будет отпущена (с задержками на 50мс для подавления дребезга)
}
// ОБНОВЛЕНИЕ ИНФОРМАЦИИ НА ДИСПЛЕЕ //
недействительный funcDisplayUpdate() {
если (flgDisplayUpdate) {
флгдисплейупдате = 0; // Обновление дисплея происходит только если был установлен флаг flgDisplayUpdate
switch (valMode) { // Далее действует в зависимости от значения переменной valMode (которая хранит № текущего режима меню)
случай 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-« П/Ч» и выводим информацию для данного режима на индикаторе...
/* "00:00:00" */
lcd.setCursor(0, 0);
lcd.print(time.gettime("Ч:и:с")); // Выводим верхний текст
/* "00.00.0000г. ПН" */
lcd.setCursor(0, 1);
lcd.print(time.gettime("dmY5."));
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 ? "C6" : ("BC")))))));
lcd.setCursor(12, 0);
ЖК.принт(" ");
valArray[4] = 15;
если (valArray[3]) {
lcd.setCursor(valArray[4], 0);
lcd.print("4");
valArray[4]--;
}
если (valArray[2]) {
lcd.setCursor(valArray[4], 0);
lcd.print("3");
valArray[4]--;
}
если (valArray[1]) {
lcd.setCursor(valArray[4], 0);
lcd.print("2");
valArray[4]--;
}
если (valArray[0]) {
lcd.setCursor(valArray[4], 0);
lcd.print("1");
valArray[4]--;
}
перерыв;
Дело 1:
funcSetChars(11, 15, 25, 9, 20);
// Если установлен режим 1, загружаем символы в липлея CGRAM в следующем порядке: 1м 2н 3ю 4Й 5Ы и выводим информацию для данного режима на дисплее ...
/* "меню: " */
lcd.setCursor(0, 0);
lcd.print(F("1e23:")); // Выводим верхний текст
/* "< ТАЙМЕРЫ >" */
lcd.setCursor(0, 1);
lcd.print(F("<TA4MEP5 >"));
перерыв;
случай 2:
funcSetChars(11, 15, 25, 18, 20); // Если установлен режим 2, то загружаем символы в лисплея CGRAM в следующем порядке: 1м 2н 3ю 4Ч 5Ы и выводим информацию для данного режима на индикаторе ...
/* "меню: " */
lcd.setCursor(0, 0);
lcd.print(F("1e23:")); // Выводим верхний текст
/* "< ЧАСЫ >" */ lcd.setCursor(0, 1);
lcd.print(F("<4AC5 >")); //
перерыв;
случай 3:
funcSetChars(11, 15, 25, 4, 20); // Если установлен режим 3, загружаем символы в липлея CGRAM в следующем порядке: 1м 2н 3ю 4Д 5Ы и выводим информацию для данного режима на индикаторе ...
/* "меню: " */
lcd.setCursor(0, 0);
lcd.print(F("1e23:")); // Выводим верхний текст
/* "< ВЫХОД >" */
lcd.setCursor(0, 1);
lcd.print(F("< B5XO4 >"));
перерыв;
случай 11:
funcSetChars(15, 25, 17, 9, 21); // Если установлен режим 11, загружаем символы в лисплей CGRAM в следующем порядке: 1н 2ю 3т 4й 5ы и выводим информацию для данного режима на дисплее ...
/* "меню>таймеры: " */
lcd.setCursor(0, 0);
lcd.print(F("me12>3a4mep5:")); // Выводим верхний текст
/* "< 00:00-00:00-1>" */
lcd.setCursor(0, 1);
lcd.print(F("<00:00-00:00-0>"));
lcd.setCursor(2, 1);
lcd.print(funcReadTimer(valTimerNum, 1) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 1));
lcd.setCursor(5, 1);
lcd.print(funcReadTimer(valTimerNum, 2) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 2));
lcd.setCursor(8, 1);
lcd.print(funcReadTimer(valTimerNum, 3) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 3));
lcd.setCursor(11, 1);
lcd.print(funcReadTimer(valTimerNum, 4) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 4));
lcd.setCursor(14, 1);
lcd.print(funcReadTimer(valTimerNum, 5));
перерыв;
случай 12:
funcSetChars(15, 25, 17, 9, 21, 8, 20); // Если установлен режим 12, загружаем символы в лисплей CGRAM в следующем порядке: 1н 2ю 3т 4й 5ы 6Й 7Ы и выводим информацию для данного режима на дисплее ...
/* "меню>таймеры: " */
lcd.setCursor(0, 0);
lcd.print(F("me12>3a4mep5:")); // Выводим верхний текст
/* "< НОВЫЙ ТАЙМЕР >" */
lcd.setCursor(0, 1);
lcd.print(F("<HOB76 TA6MEP >"));
перерыв;
случай 13:
funcSetChars(15, 25, 17, 9, 21, 22); // Если установлен режим 13, загружаем символы в лисплей CGRAM в следующем порядке: 1н 2ю 3т 4й 5ы 6Ь и выводим информацию для данного режима на дисплее ...
/* "меню>таймеры: " */
lcd.setCursor(0, 0);
lcd.print(F("me12>3a4mep5:")); // Выводим верхний текст
/* "< CTEPETь BCE >" */
lcd.setCursor(0, 1);
lcd.print(F("< CTEPET6 BCE >"));
перерыв;
случай 14:
funcSetChars(15, 25, 17, 9, 21, 4, 20); // Если установлен режим 14, загружаем символы в лисплей CGRAM в следующем порядке: 1н 2ю 3т 4й 5ы 6Д 7Ы и выводим информацию для данного режима на дисплее ...
/* "меню>таймеры: " */
lcd.setCursor(0, 0);
lcd.print(F("me12>3a4mep5:")); // Выводим верхний текст
/* "< ВЫХОД >" */
lcd.setCursor(0, 1);
lcd.print(F("< B7XO6 >"));
перерыв;
случай 21:
funcSetChars(11, 15, 25, 19, 21, 26); // Если установлен режим 21, то загружаем символы в лисплей CGRAM в следующем порядке: 1м 2н 3ю 4ч 5ы 6Я и выводим информацию для данного режима на дисплее ...
/* "меню>часы: " */
lcd.setCursor(0, 0);
lcd.print(F("1e23>4ac5:")); // Выводим верхний текст
/* "< ВРЕМЯ >" */
lcd.setCursor(0, 1);
lcd.print(F("<BPEM6 >"));
перерыв;
случай 22:
funcSetChars(11, 15, 25, 19, 21, 4); // Если установлен режим 22, то загружаем символы в лисплей CGRAM в следующем порядке: 1м 2н 3ю 4ч 5ы 6Д и выводим информацию для данного режима на дисплее ...
/* "меню>часы: " */
lcd.setCursor(0, 0);
lcd.print(F("1e23>4ac5:")); // Выводим верхний текст
/* "< ДАТА >" */
lcd.setCursor(0, 1);
lcd.print(F("< 6ATA >"));
перерыв;
случай 23:
funcSetChars(11, 15, 25, 19, 21, 4, 20); // Если установлен режим 23, загружаем символы в лисплей CGRAM в следующем порядке: 1м 2н 3ю 4ч 5ы 6Д 7Ы и выводим информацию для данного режима на дисплее ...
/* "меню>часы: " */
lcd.setCursor(0, 0);
lcd.print(F("1e23>4ac5:")); // Выводим верхний текст
/* "< ВЫХОД >" */
lcd.setCursor(0, 1);
lcd.print(F("< B7XO6 >"));
перерыв;
случай 31:
funcSetChars(11, 15, 25, 19, 21, 1, 27); // Если установлен режим 31, загружаем символы в лисплей CGRAM в следующем порядке: 1м 2н 3ю 4ч 5ы 6в 7я и выводим информацию для данного режима на дисплее ...
/* "меню>часы>впемя:" */
lcd.setCursor(0, 0);
lcd.print(F("1e23>4ac5>6pe17:")); // Выводим верхний текст
/* " 00:00:00 " */
lcd.setCursor(4, 1);
valChar[0] = valArray[0] / 10 + 48;
valChar[1] = valArray[0] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 0) ? " " : valChar);
жк.принт(":");
lcd.setCursor(7, 1);
valChar[0] = valArray[1] / 10 + 48;
valChar[1] = valArray[1] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 1) ? " " : valChar);
жк.принт(":");
lcd.setCursor(10, 1);
valChar[0] = valArray[2] / 10 + 48;
valChar[1] = valArray[2] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 2) ? " " : valChar);
перерыв;
случай 32:
funcSetChars(24, 18, 20, 4, 14, 0); // Если установлен режим 32, загружаем символы в лисплей CGRAM в следующем порядке: 1Ю 2Ч 3Ы 4Д 5П 6Б и выводим информацию для данного режима на дисплее ...
/* "MEHЮ>ЧАСЫ>ДАННЫЕ: " */ lcd.setCursor(0, 0);
lcd.print(F("MEH1>2AC3>4ATA:")); // Выводим верхний текст
/* "00.00.0000 пт" */
lcd.setCursor(1, 1);
valChar[0] = valArray[0] / 10 + 48;
valChar[1] = valArray[0] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 0) ? " " : valChar);
жк.печать(".");
lcd.setCursor(4, 1);
valChar[0] = valArray[1] / 10 + 48;
valChar[1] = valArray[1] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 1) ? " " : valChar);
жк.печать(".");
lcd.setCursor(7, 1);
valChar[0] = '2';
valChar[1] = '0';
valChar[2] = valArray[2] / 10 + 48;
valChar[3] = valArray[2] % 10 + 48;
валЧар[4] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 2) ? " " : valChar);
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 ? "C6" : ("BC"))))))));
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 3) ? " " : valChar);
перерыв;
случай 41:
funcSetChars(20, 8, 4); // Если установлен режим 41, загружаем символы в лисплей CGRAM в следующем порядке: 1Ы 2Й 3D и выводим информацию для данного режима на дисплее ...
/* " ХОБЫЙ ТАЙМЕП " */
lcd.setCursor(2, 0);
lcd.print(F("HOB12 TA2MEP")); // Выводим верхний текст
/* " CO3ДАH " */
lcd.setCursor(5, 1);
lcd.print(F("CO33AH"));
перерыв;
случай 42:
funcSetChars(20, 8, 4, 16, 12); // Если установлен режим 42, загружаем символы в липлея CGRAM в следующем порядке: 1Ы 2Й 3Д 4У 5Л и выводим информацию для данного режима на индикаторе ...
/* "BCE ТАЙМЕПЫ" */
lcd.setCursor(2, 0);
lcd.print(F("BCE TA2MEP1")); // Выводим верхний текст
/* " УДАЛЕХЫ " */
lcd.setCursor(4, 1);
lcd.print(F("43A5EH1"));
перерыв;
случай 43:
funcSetChars(8, 16, 4, 12); // Если установлен режим 43, загружаем символы в лисплей CGRAM в следующем порядке: 1Й 2У 3Д 4Л и выводим информацию для данного режима на дисплее ...
/* " ТАЙМЕП " */
lcd.setCursor(5, 0);
lcd.print(F("TA1MEP")); // Выводим верхний текст
/* " УДАЛЕХ " */
lcd.setCursor(5, 1);
lcd.print(F("23A4EH"));
перерыв;
случай 51:
funcSetChars(17, 9, 21, 23, 26, 6, 12); // Если установлен режим 51, загружаем символы в лисплей CGRAM в следующем порядке: 1т 2й 3ы 4. 5Я 6И 7Л и выводим информацию для данного режима на дисплее ...
/* "m>таймеры>00:00." */
lcd.setCursor(0, 0);
lcd.print(F("m>1a2mep3>")); // Выводим верхний текст
/* "<BPEM* * КАХА*>" */
lcd.setCursor(10, 0);
lcd.print(funcReadTimer(valTimerNum, 1) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 1));
жк.принт(":");
lcd.setCursor(13, 0);
lcd.print(funcReadTimer(valTimerNum, 2) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 2));
lcd.print("4");
lcd.setCursor(0, 1);
lcd.print(F("<BPEM5 6 KAHA7>"));
перерыв;
случай 52:
funcSetChars(17, 9, 21, 23, 14, 20); // Если установлен режим 52, загружаем символы в лисплей CGRAM в следующем порядке: 1т 2й 3ы 4.5П 6Ы и выводим информацию для данного режима на дисплее ...
/* "m>таймеры>00:00." */
lcd.setCursor(0, 0);
lcd.print(F("m>1a2mep3>")); // Выводим верхний текст
/* "< ПОБТОПЫ >" */
lcd.setCursor(10, 0);
lcd.print(funcReadTimer(valTimerNum, 1) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 1));
жк.принт(":");
lcd.setCursor(13, 0);
lcd.print(funcReadTimer(valTimerNum, 2) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 2));
lcd.print("4");
lcd.setCursor(0, 1);
lcd.print(F("<5OBTOP6 >"));
перерыв;
случай 53:
funcSetChars(17, 9, 21, 23, 16, 6, 2); // Если установлен режим 53, загружаем символы в лисплей CGRAM в следующем порядке: 1т 2й 3ы 4. 5У 6И 7Г и выводим информацию для данного режима на дисплее ...
/* "m>таймеры>00:00." */
lcd.setCursor(0, 0);
lcd.print(F("m>1a2mep3>")); // Выводим верхний текст
/* "< УPOBEHb CIGN.>" */
lcd.setCursor(10, 0);
lcd.print(funcReadTimer(valTimerNum, 1) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 1));
жк.принт(":");
lcd.setCursor(13, 0);
lcd.print(funcReadTimer(valTimerNum, 2) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 2));
lcd.print("4");
lcd.setCursor(0, 1);
lcd.print(F("<5POBEHb C67H.>"));
перерыв;
случай 54:
funcSetChars(17, 9, 21, 23, 22, 8); // Если установлен режим 54, загружаем символы в лисплей CGRAM в следующем порядке: 1т 2й 3ы 4. 5Ь 6Й и выводим информацию для данного режима на дисплее ...
/* "m>таймеры>00:00." */
lcd.setCursor(0, 0);
lcd.print(F("m>1a2mep3>")); // Выводим верхний текст
/* "<CTEPETЬ ТАЙМЕП>" */
lcd.setCursor(10, 0);
lcd.print(funcReadTimer(valTimerNum, 1) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 1));
жк.принт(":");
lcd.setCursor(13, 0);
lcd.print(funcReadTimer(valTimerNum, 2) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 2));
lcd.print("4");
lcd.setCursor(0, 1);
lcd.print(F("<CTEPET5 TA6MEP>"));
перерыв;
случай 55:
funcSetChars(17, 9, 21, 23, 20, 4); // Если установлен режим 55, загружаем символы в лисплей CGRAM в следующем порядке: 1т 2й 3ы 4.5Ы 6Д и выводим информацию для данного режима на дисплее ...
/* "m>таймеры>00:00." */
lcd.setCursor(0, 0);
lcd.print(F("m>1a2mep3>")); // Выводим верхний текст
/* "< ВЫХОД >" */
lcd.setCursor(10, 0);
lcd.print(funcReadTimer(valTimerNum, 1) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 1));
жк.принт(":");
lcd.setCursor(13, 0);
lcd.print(funcReadTimer(valTimerNum, 2) < 10? "0": "");
lcd.print(funcReadTimer(valTimerNum, 2));
lcd.print("4");
lcd.setCursor(0, 1);
lcd.print(F("< B5XO6 >"));
перерыв;
случай 61:
funcSetChars(11, 17, 9, 21, 1, 27, 10); // Если установлен режим 61, загружаем символы в лисплей CGRAM в следующем порядке: 1м 2т 3й 4ы 5в 6я 7к и выводим информацию для данного режима на дисплее ...
/* "м>таймер>впемя: " */
lcd.setCursor(0, 0);
lcd.print(F("1>2a31ep>5pe16:")); // Выводим верхний текст
/* " 00:00-00:00 к0 " */
lcd.setCursor(1, 1);
valChar[0] = valArray[0] / 10 + 48;
valChar[1] = valArray[0] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 0) ? " " : valChar);
жк.принт(":");
lcd.setCursor(4, 1);
valChar[0] = valArray[1] / 10 + 48;
valChar[1] = valArray[1] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 1) ? " " : valChar);
жк.принт("-");
lcd.setCursor(7, 1);
valChar[0] = valArray[2] / 10 + 48;
valChar[1] = valArray[2] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 2) ? " " : valChar);
жк.принт(":");
lcd.setCursor(10, 1);
valChar[0] = valArray[3] / 10 + 48;
valChar[1] = valArray[3] % 10 + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 3) ? " " : valChar);
lcd.setCursor(13, 1);
валЧар[0] = 7;
valChar[1] = valArray[4] + 48;
валЧар[2] = 0;
lcd.print((millis() % 1000 < 500 && valSubMode == 4) ? " " : valChar);
перерыв;
случай 62:
funcSetChars(28, 29, 30, 31, 32, 33, 34); // Если установлен режим 62, загружаем символы в лисплей CGRAM в следующем порядке: 1-ПН 2-ВТ 3-СР 4-ЧТ 5-ПТ 6-ВТ 7-СР и выводим информацию для данного режима на дисплее ...
/* " * * * * * * * " */
lcd.setCursor(1, 0);
lcd.print("1 2 3 4 5 6 7"); // Выводим верхний текст
/* " ^ ^ ^ ^ ^ ^ ^ " */
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] ? "^" : " ");
lcd.setCursor(valSubMode * 2 + 1, 1);
ЖК.мигать();
перерыв;
случай 63:
funcSetChars(11, 17, 9, 7, 3, 15, 13); // Если установлен режим 63, загружаем символы в лисплей CGRAM в следующем порядке: 1м 2т 3й 4и 5г 6н 7л и выводим информацию для данного режима на дисплее ...
/* "м>таймеп>сигнал:" */
lcd.setCursor(0, 0);
lcd.print(F("1>2a31ep>c456a7:")); // Выводим верхний текст
/* " 100% " */
lcd.setCursor(6, 1);
valChar[0] = valArray[0] / 100 + 48;
valChar[1] = valArray[0] % 100/10 + 48;
valChar[2] = valArray[0] % 10 + 48;
валЧар[3] = 0;
lcd.print(valChar);
lcd.print("%");
перерыв;
}
}
}
// ВЫВОД СИГНАЛОВ ШИМ //
недействительный funcSetPWM (недействительный) {
статический uint8_t setChanel[4] = { 0, 0, 0, 0 }; // Определяем массив, каждый элемент которого соответствует сигналу от 0 до 100%, установленному на соответствующем канале
if (valMode == 0) { // Если текущий режим регулируется 0 "Вне меню", то ...
uint8_t getChanel[4] = { 0, 0, 0, 0 }; // Определяем массив, каждый элемент которого соответствует сигналу от 0 до 100%, прочитанному из активированного таймера для соответствующего канала.
uint32_t timeRTC = 0; // Определяем переменную для хранения текущего времени в виде секунд прошедших с полуночи текущего дня (от 00:00:00)
uint32_t timeTimerStart = 0; // Определяем переменную для хранения времени запуска таймера (для каждого таймера в теле цикле) в виде секунд прошедших с полуночей текущего дня (от 00:00:00)
uint32_t timeTimerStop = 0; // Определяем переменную для хранения времени сброса таймера (для каждого таймера в теле цикле) в виде секунд прошедших с полуночей текущего дня (от 00:00:00)
uint8_t timeWeekday = 0; // Определяем переменную для хранения текущего дня недели в формате: 1-ПН, 2-ВТ, 3-СР, 4-ЧТ, 5-ПТ, 6-СБ, 7-ВС
valArray[0] = valArray[1] = valArray[2] = valArray[3] = 0; // В первых 4 элементах массива valArray будет указано 1, если на соответствующем канале будет установлен сигнал
timeRTC = (uint32_t)время.Часы * 3600 + время.минуты * 60 + время.секунды; // Получаем количество секунд прошедшего с полуночи текущего дня (от 00:00:00). Значения запроса объекта времени являются актуальными, т.к. в данном режиме (valMode) в функции funcDisplayUpdate было обращение к функции time.gettime
timeWeekday = время.weekday;
если (времяWeekday == 0)
времяБудний день = 7; // Получаем текущий день недели в формате: 1-ПН, 2-ВТ, 3-СР, 4-ЧТ, 5-ПТ, 6-СБ, 7-ВС
for (uint8_t i = 0; i < maxTimers; i++) { // Проходим по всем таймерам, ...
if (funcReadTimer(i)) { // Если установлен очередной таймер, то ...
if (bitRead(funcReadTimer(i, 7), 7 - timeWeekday)) { // Если день недели повтора таймера совпал с текущим днём недели, то ...
timeTimerStart = (uint32_t)funcReadTimer(i, 1) * 3600 + funcReadTimer(i, 2) * 60; // Читаем время запуска очередного таймера в виде количества секунд, прошедших от полуночи текущего дня (от 00:00:00)
timeTimerStop = (uint32_t)funcReadTimer(i, 3) * 3600 + funcReadTimer(i, 4) * 60; // Читаем время сброса очередного таймера в виде количества секунд, прошедших от полуночи текущего дня (от 00:00:00)
if (timeTimerStart <= timeRTC && timeRTC < timeTimerStop) { // Если текущее время находится между запуском таймера и сбросом таймера, то ...
getChanel[funcReadTimer(i, 5) - 1] = funcReadTimer(i, 6); // Читаем из таймера уровень сигнала, который требуется установить на требуемом канале
valArray[funcReadTimer(i, 5) - 1] = 1; // Сохраняем тот факт, что установлен сигнал на требуемом канале
}
}
}
}
if (setChanel[0] != getChanel[0]) {
setChanel[0] = getChanel[0];
аналогWrite(pinChanel_1, карта(getChanel[0], 0, 100, 0, 255));
} // выводим ШИМ на 1 канал
if (setChanel[1] != getChanel[1]) {
setChanel[1] = getChanel[1];
аналогWrite(pinChanel_2, карта(getChanel[1], 0, 100, 0, 255));
} // выводим ШИМ на 2 канал
if (setChanel[2] != getChanel[2]) {
setChanel[2] = getChanel[2];
аналогWrite(pinChanel_3, карта(getChanel[2], 0, 100, 0, 255));
} // выводим ШИМ на 3 канал
if (setChanel[3] != getChanel[3]) {
setChanel[3] = getChanel[3];
AnalogWrite(pinChanel_4, map(getChanel[3], 0, 100, 0, 255));
} // выводим ШИМ на 4 канал
}
}
// ЗАПИСЬ ДО 7 СИМВОЛОВ В CGRAM ДИСПЛЕЯ
void funcSetChars(uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7) {
байт я[8];
если (i1 < 255) {
memcpy_P(i, rusMem[i1], 8);
lcd.createChar(1, я);
} // Записываем символ i (взятый из элемента № i1 массива rusMem, хранящегося в PROGMEM Arduino) в графах CGRAM под номером
если (i2 < 255) {
memcpy_P(i, rusMem[i2], 8);
lcd.createChar(2, я);
} // Записываем символ i (взятый из элемента № i2 массива rusMem, хранящегося в PROGMEM Arduino) в графах CGRAM под номером 2
если (i3 < 255) {
memcpy_P(i, rusMem[i3], 8);
lcd.createChar(3, я);
} // Записываем символ i (взятый из элемента № i3 массива rusMem, хранящегося в PROGMEM Arduino) в графах CGRAM под номером 3
если (i4 < 255) {
memcpy_P(i, rusMem[i4], 8);
lcd.createChar(4, я);
} // Записываем символ i (взятый из элемента № i4 массива rusMem, хранящегося в PROGMEM Arduino) в графах CGRAM под номером 4
если (i5 < 255) {
memcpy_P(i, rusMem[i5], 8);
lcd.createChar(5, я);
} // Записываем символ i (взятый из элемента № i5 массива rusMem, хранящегося в PROGMEM Arduino) в графах CGRAM под номером 5
если (i6 < 255) {
memcpy_P(i, rusMem[i6], 8);
lcd.createChar(6, я);
} // Записываем символ i (взятый из элемента № i6 массива rusMem, хранящегося в PROGMEM Arduino) в графах CGRAM под номером 6
если (i7 < 255) {
memcpy_P(i, rusMem[i7], 8);
lcd.createChar(7, я);
} // Записываем символ i (взятый из элемента № i7 массива rusMem, хранящегося в PROGMEM Arduino) в графах CGRAM под номером 7
}
// ЧТЕНИЕ ОДНОГО ИЗ ПАРАМЕТРОВ ТАЙМЕРА
uint8_t funcReadTimer(uint8_t i, uint8_t j) {
вернуть EEPROM[i * 8 + j];
}
// ПОИСК НОВОГО ТАЙМЕРА
uint8_t funcFindTimer (недействительный) {
uint8_t я = 0;
в то время как (funcReadTimer (я)) {
я++;
if (i >= maxTimers) {
перерыв;
}
}
вернуть я;
}
// СОХРАНЕНИЕ ОДНОГО ИЗ ПАРАМЕТРОВ ТАЙМЕА
void funcSaveTimer(uint8_t i, uint8_t j, uint8_t k) {
ЭСППЗУ[я * 8 + j] = к;
}
// ПРОВЕРКА ДАННЫХ ТАЙМЕРОВ В EEPROM
bool funcTestTimer (недействительный) {
for (uint8_t я = 0; я <maxTimers; я++) {
если (funcReadTimer(i, 0) > 1) {
вернуть ложь;
}
если (funcReadTimer(i, 1) > 23) {
вернуть ложь;
}
если (funcReadTimer(i, 2) > 59) {
вернуть ложь;
}
если (funcReadTimer(i, 3) > 23) {
вернуть ложь;
}
если (funcReadTimer(i, 4) > 59) {
вернуть ложь;
}
}
вернуть истину;
}
Неактивний
этот код я скачал с какого-то сайта. правда он не компилировался. человек мне помог и сделал чтобы он работал.
Неактивний
он не компилировался. человек мне помог и сделал чтобы он работал.
Ну так выложите код который компилируется. Иначе за переделку кода в таком виде ИМХО цена будет с тремя 0.
я уже его выложил
Неактивний
Ну, тогда 10000
Є код, не спаплюжений автоперекладачем?
В цьому "коді", як можна зрозуміти, налаштування кожного таймера зберігається в EEPROM у такому форматі:
#байта значення
0 активний/неактивний
1 година увімкнення
2 хвилина увімкнення
3 година вимкнення
4 хвилина вимкнення
5 номер канала
6 рівень сигнала
7 бітова маска днів тижня
Тобто час задається дискретно по хвилинах.
Щоб зробити по секундах, можна доповнити структуру ще двома полями: секунда увімкнення і секунда вимкнення. Тоді в обчисленні часу замість
timeTimerStart = (uint32_t)funcReadTimer(i, 1) * 3600 + funcReadTimer(i, 2) * 60;
timeTimerStop = (uint32_t)funcReadTimer(i, 3) * 3600 + funcReadTimer(i, 4) * 60;
буде щось типу
timeTimerStart = (uint32_t)funcReadTimer(i, 1) * 3600 + funcReadTimer(i, 2) * 60 + funcReadTimer(i, 8);
timeTimerStop = (uint32_t)funcReadTimer(i, 3) * 3600 + funcReadTimer(i, 4) * 60 + funcReadTimer(i, 9);
Тоді структура займатиме 10 байт замість 8-ми, тому потрібно змінити індексування EEPROM:
uint8_t funcReadTimer(uint8_t i, uint8_t j) {
return EEPROM[i * 10 + j];
}
...
void funcSaveTimer(uint8_t i, uint8_t j, uint8_t k) {
EEPROM[i * 10 + j] = k;
}
і решту коду, де очікується 8-байтова структура. Відповідно зміниться і кількість доступних таймерів з "кількість байт EEPROM/8" на "кількість байт EEPROM/10".
Також знадобиться додати установку секунд в UI.
Якщо буде достатньо дискретності в 2 секунди (тобто тільки 0, 2, 4, .. 58 секунд), то можна упакувати поле часу в ті ж два байта і обійтись без зміни розміру структури: 5 біт на години, 6 біт на хвилини і 5 біт на секунди. Або зберігати час просто як кількість 2-секундних інтервалів від початку доби.
UPD: ще, щоб не змінювати розмір структури, але отримати дискретність в 1 секунду, можна використати біти з нульового байта структури і упакувати додаткові біти секунд у нього.
Остання редакція dimich (2023-12-11 23:11:09)
Неактивний
Дуже Вам дякую за відповідь! Але я не розумію програмування. Я технарь, механік. Я розумію зовсім інші речі. Можливо я звернувся до ардуіно тому що думав що це для мене не складно.Можливо я так думав тому що всяких реле часу та інших таймеров дуже багато в нашому житті. Я вже розумію що для мене це гемор і потрібно шукати інше рішення( при всій повазі до Ваших знань та праці).
Неактивний
потрібно шукати інше рішення
Вполне возможно. В сети можно найти кучу различных таймеров. Все зависит от ваших потребностей. Или вам нужен именно суточный многоканальный?
Тему закрываю. решение найдено. Всем спасибо за дискуссию и советы!
Неактивний
Сторінки 1