Привет всем !
В общем мой проект: есть светодиода , дисплей(1602) , и энкодер с кнопкой. поворачивая енкодер мы выствляем время сколько будет гореть светодиод (1) я после завершения времени должен отключиться и включиться светодиод (2) на заданное время, а затем отключяиться и по идее ве ничего сложного. Но тут я подумал и мне нужно еще выставлять количество циклов (включинеия 1и 2 светодида ). По ковырял код (ALEXGYVER теплица) есть непонятные строчки. Я пытался как то обойти PERIOD коде но!, обходя его ничего не работает. И еще почему при запуске ардуинки она ждем время указанное время Периода а потом начинаеться цикл?? И почум при выборе времени работы более чем минута все стопориться и ничего не работает? Помощь создания кода с нуля..
вот кусок метода : ( просто чтоб понять)
void periodTick() {
for (byte i = 0; i < PUPM_AMOUNT; i++) { // пробегаем по всем помпам
if ( (millis() - pump_timers > ( (long)period_time * period_coef) ) непонятное условие (
переменная millis(), которая возвращает время с момента включения ардуины вычитается время pump_timer(1) больше чем ( вермя периода period_time[1] умноженое на period_coef Если выполняется равенсво если (pump_state[1] не равенSWITCH_LEVEL)
и !(now_pumping *!PARALLEL)
&& (pump_state != SWITCH_LEVEL)
&& !(now_pumping * !PARALLEL)) {
pump_state = SWITCH_LEVEL;
digitalWrite(pump_pins, SWITCH_LEVEL);
pump_timers = millis();
now_pumping = true;
}
}
}
В общем мой проект: есть светодиода , дисплей(1602) , и энкодер с кнопкой. поворачивая енкодер мы выствляем время сколько будет гореть светодиод (1) я после завершения времени должен отключиться и включиться светодиод (2) на заданное время, а затем отключяиться и по идее ве ничего сложного. Но тут я подумал и мне нужно еще выставлять количество циклов (включинеия 1и 2 светодида ). По ковырял код (ALEXGYVER теплица) есть непонятные строчки. Я пытался как то обойти PERIOD коде но!, обходя его ничего не работает. И еще почему при запуске ардуинки она ждем время указанное время Периода а потом начинаеться цикл?? И почум при выборе времени работы более чем минута все стопориться и ничего не работает? Помощь создания кода с нуля..
вот кусок метода : ( просто чтоб понять)
void periodTick() {
for (byte i = 0; i < PUPM_AMOUNT; i++) { // пробегаем по всем помпам
if ( (millis() - pump_timers > ( (long)period_time * period_coef) ) непонятное условие (
переменная millis(), которая возвращает время с момента включения ардуины вычитается время pump_timer(1) больше чем ( вермя периода period_time[1] умноженое на period_coef Если выполняется равенсво если (pump_state[1] не равенSWITCH_LEVEL)
и !(now_pumping *!PARALLEL)
&& (pump_state != SWITCH_LEVEL)
&& !(now_pumping * !PARALLEL)) {
pump_state = SWITCH_LEVEL;
digitalWrite(pump_pins, SWITCH_LEVEL);
pump_timers = millis();
now_pumping = true;
}
}
}
C++:
#define ENCODER_TYPE 0
#define DRIVER_VERSION 0 // 0 - маркировка драйвера дисплея кончается на 4АТ, 1 - на 4Т
#define PUPM_AMOUNT 2 // количество помп, подключенных через реле/мосфет
#define START_PIN 5 // подключены начиная с пина
#define SWITCH_LEVEL 1 // реле: 1 - высокого уровня (или мосфет), 0 - низкого
#define PARALLEL 0 // 1 - параллельный полив, 0 - полив в порядке очереди
#define TIMER_START 0 // 1 - отсчёт периода с момента ВЫКЛЮЧЕНИЯ помпы, 0 - с момента ВКЛЮЧЕНИЯ помпы
//#define PERIOD 0 // 1 - период в часах, 0 - в минутах
#define PUMPING 1 // 1 - время работы помпы в секундах, 0 - в минутах
#define DROP_ICON 1 // 1 - отображать капельку, 0 - будет буква "t" (time)
// названия каналов управления. БУКВУ L НЕ ТРОГАТЬ БЛЕТ!!!!!!
static const wchar_t *relayNames[] = {
L"Pumped ",
L"Vaccuumed",
// L"Pump 3",
};
#define CLK 2
#define DT 3
#define SW 0
#include "GyverEncoder.h"
Encoder enc1(CLK, DT, SW);
#include <EEPROMex.h>
#include <EEPROMVar.h>
#include "LCD_1602_RUS.h"
// -------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ-------------
// Если кончается на 4Т - это 0х27. Если на 4АТ - 0х3f
#if (DRIVER_VERSION)
LCD_1602_RUS lcd(0x27, 16, 2);
#else
LCD_1602_RUS lcd(0x3f, 16, 2);
#endif
// -------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ-------------
unsigned long pump_timers[PUPM_AMOUNT];
unsigned int pumping_time[PUPM_AMOUNT];
unsigned int period_time[PUPM_AMOUNT];
unsigned int time_left[PUPM_AMOUNT];
boolean pump_state[PUPM_AMOUNT];
byte pump_pins[PUPM_AMOUNT];
byte current_set = 2;
byte current_pump;
boolean reDraw_flag, arrow_update;
boolean now_pumping;
unsigned long period_coef, pumping_coef;
void setup() {
// --------------------- КОНФИГУРИРУЕМ ПИНЫ ---------------------
for (byte i = 0; i < PUPM_AMOUNT; i++) { // пробегаем по всем помпам
pump_pins[i] = START_PIN + i; // настраиваем массив пинов
pinMode(START_PIN + i, OUTPUT); // настраиваем пины
digitalWrite(START_PIN + i, !SWITCH_LEVEL); // выключаем от греха
}
// --------------------- ИНИЦИАЛИЗИРУЕМ ЖЕЛЕЗО ---------------------
lcd.init();
lcd.backlight();
lcd.clear();
enc1.setStepNorm(1);
attachInterrupt(0, encISR, CHANGE);
// --------------------- СБРОС НАСТРОЕК ---------------------
if (!digitalRead(SW)) { // если нажат энкодер, сбросить настройки до 1
lcd.setCursor(0, 0);
lcd.print("Reset settings");
for (byte i = 0; i < 100; i++) {
EEPROM.updateByte(i, 1);
}
}
while (!digitalRead(SW)); // ждём отпускания кнопки
lcd.clear(); // очищаем дисплей, продолжаем работу
// --------------------------- НАСТРОЙКИ ---------------------------
// if (PERIOD) period_coef = (long)1000; // перевод в часы
period_coef = (long)60000 ; // перевод в минуты
pumping_coef = 1000 ; // перевод в секунды
//pumping_coef = (long)1000 * 60; // перевод в минуты
// в ячейке 100 должен быть записан флажок 1, если его нет - делаем (ПЕРВЫЙ ЗАПУСК)
if (EEPROM.read(100) != 1) {
EEPROM.writeByte(100, 1);
// для порядку сделаем 1 ячейки с 0 по 99
for (byte i = 0; i < 100; i++) {
EEPROM.writeByte(i, 1);
}
}
for (byte i = 0; i < PUPM_AMOUNT; i++) { // пробегаем по всем помпам
period_time[i] = EEPROM.readByte(2 * i); // читаем данные из памяти. На чётных - период (ч)
pumping_time[i] = EEPROM.readByte(2 * i + 1); // на нечётных - полив (с)
}
// ---------------------- ВЫВОД НА ДИСПЛЕЙ ------------------------
// вывести буквенные подписи
lcd.setCursor(1, 0);
//lcd.print("Pump #");
lcd.print(relayNames[0]);
lcd.setCursor(1, 1);
lcd.print("Prd: ");
lcd.setCursor(10, 1);
lcd.print("t:");
//lcd.print(": ");
arrow_update = true; // флаг на обновление стрелочки
reDraw(); // вывести на дисплей
reDraw(); // вывести на дисплей (флаг стрелок сбросился, выведем числа...)
}
void loop() {
encoderTick();
flowTick();
}
void flowTick() {
for (byte i = 0; i < PUPM_AMOUNT; i++) { // пробегаем по всем помпам
if ( pump_timers[i] > pumping_coef )
now_pumping = true;
else now_pumping = false;
}
}
void encISR() {
enc1.tick(); // отработка энкодера
}
void encoderTick() {
enc1.tick(); // отработка энкодера
if (enc1.isRelease()) { // если был нажат
arrow_update = true; // флаг на обновление стрелочки
reDraw(); // обновить дисплей
}
if (enc1.isTurn()) { // если был совершён поворот
switch (current_set) { // смотрим, какая опция сейчас меняется
case 0: // если номер помпы
current_pump = enc1.normCount; // получить значение с энкодера
break;
case 1: // если период работы помпы
period_time[current_pump] = enc1.normCount; // получить значение с энкодера
break;
case 2: // если время работы помпы
pumping_time[current_pump] = enc1.normCount; // получить значение с энкодера
break;
}
reDraw(); // обновить дисплей
}
}
void reDraw() {
if (arrow_update) { // если изменился режим выбора
if (++current_set > 2) // менять current_set в пределах 0.. 2
current_set = 0;
if (current_set == 0) update_EEPROM(); // если переключилиссь на выбор помпы, обновить данные
switch (current_set) { // смотрим, какая опция сейчас выбрана
case 0: // если номер помпы
enc1.setCounterNorm(current_pump); // говорим энкодеру работать с номером помпы
enc1.setLimitsNorm(0, PUPM_AMOUNT - 1); // ограничиваем
// стереть предыдущую стрелочку и нарисовать новую
lcd.setCursor(0, 0); lcd.write(126); lcd.setCursor(9, 1); lcd.print(" ");
break;
case 1:
enc1.setCounterNorm(period_time[current_pump]);
enc1.setLimitsNorm(1, 99);
lcd.setCursor(0, 1); lcd.write(126); lcd.setCursor(0, 0); lcd.print(" ");
break;
case 2:
enc1.setCounterNorm(pumping_time[current_pump]);
enc1.setLimitsNorm(1, 99);
lcd.setCursor(9, 1); lcd.write(126); lcd.setCursor(0, 1); lcd.print(" ");
break;
}
arrow_update = false;
} else {
// вывести все цифровые значения на их места
//lcd.setCursor(7, 0);
//lcd.print(current_pump);
if (current_set == 0) {
lcd.setCursor(1, 0);
lcd.print(" ");
lcd.setCursor(1, 0);
lcd.print(relayNames[current_pump]);
}
lcd.setCursor(5, 1);
lcd.print(period_time[current_pump]);
lcd.print("ss ");
lcd.setCursor(12, 1);
lcd.print(pumping_time[current_pump]);
lcd.print("s ");
/*
Serial.print("Pump #"); Serial.print(current_pump);
if (PERIOD) Serial.print(" hrs, period: ");
else Serial.print(" min, period: ");
Serial.print(period_time[current_pump]);
if (PUMPING) Serial.print(" sec, flow: ");
else Serial.print(" min, flow: ");
Serial.println(pumping_time[current_pump]);
}
*/
}
}
// обновляем данные в памяти
void update_EEPROM() {
EEPROM.updateByte(2 * current_pump, period_time[current_pump]);
EEPROM.updateByte(2 * current_pump + 1, pumping_time[current_pump]);
}
Изменено: