#include <EncButton.h> // подключаем библиотеки
#include <GyverOLED.h>
#include <EEManager.h>
#include <Arduino.h>
#include <GTimer.h>
GTimer<millis> tmrMotor1; // Таймер насоса 1
GTimer<millis> tmrDelay1; // Таймер задержки насоса 1
GTimer<millis> tmrMotor2; // Таймер насоса 2
GTimer<millis> tmrDelay2; // Таймер задержки насоса 2
GTimer<millis> tmrMotor3; // Таймер насоса 3
GTimer<millis> tmrDelay3; // Таймер задержки насоса 3
GTimer<millis> tmrMotor4; // Таймер насоса 4
GTimer<millis> tmrDelay4; // Таймер задержки насоса 4
GTimer<millis> tmrDisplay; // Таймер дисплея
Button btnM(12); // кнопка M
Button btnUP(11); // кнопка UP
Button btnDOWN(10); // кнопка DOWN
Button btnRIGHT(8); // кнопка RIGHT
Button btnLEFT(9); // кнопка LEFT
GyverOLED<SSD1306_128x64, OLED_BUFFER> oled; // дисплей
struct Data { // СТРУКТУРА (сохраняемые в памяти параметры)
uint16_t workTime1 = 3700; // время, на которое включается реле 1 (мс)
uint32_t frequency1 = 3600000; // период (частота) включения реле 1 (мс)
uint8_t mode1 = 0; // флаг режима работы реле 1 (0 -авто, 1 - ручной, 2 - выкл)
uint32_t delay1 = 0; // задержка первого включения реле 1 (мс)
uint16_t workTime2 = 22160; // время, на которое включается реле 2 (мс)
uint32_t frequency2 = 3600000; // период (частота) включения реле 2 (мс)
uint8_t mode2 = 0; // флаг режима работы реле 1 (0 -авто, 1 - ручной, 2 - выкл)
uint32_t delay2 = 1800000; // задержка первого включения реле 2 (мс) 1800000
uint16_t workTime3 = 4000; // время, на которое включается реле 3 (мс)
uint32_t frequency3 = 3600000; // период (частота) включения реле 3 (мс)
uint8_t mode3 = 2; // флаг режима работы реле 1 (0 -авто, 1 - ручной, 2 - выкл)
uint32_t delay3 = 0; // задержка первого включения реле 3 (мс)
uint16_t workTime4 = 4000; // время, на которое включается реле 4 (мс)
uint32_t frequency4 = 3600000; // период (частота) включения реле 4 (мс)
uint8_t mode4 = 2; // флаг режима работы реле 1 (0 -авто, 1 - ручной, 2 - выкл)
uint32_t delay4 = 0; // задержка первого включения реле 4 (мс)
};
Data data; // переменная структуры, с которой мы работаем в программе
EEManager memory(data, 2000); // Переменная объекта EEManager. Вторым аргументом можно задать таймаут обновления (2000). Если не указывать, то по умолч. 5 сек (5000мс)
#define RELAY1_PIN 2 // пин реле 1
#define RELAY2_PIN 3 // пин реле 2
#define RELAY3_PIN 4 // пин реле 3
#define RELAY4_PIN 5 // пин реле 4
bool flagRelay1 = 0; // флаг статуса реле 1 (0 - выкл, 1 -вкл)
bool flagRelay2 = 0; // флаг статуса реле 2 (0 - выкл, 1 -вкл)
bool flagRelay3 = 0; // флаг статуса реле 3 (0 - выкл, 1 -вкл)
bool flagRelay4 = 0; // флаг статуса реле 4 (0 - выкл, 1 -вкл)
bool calibration1 = 0; // флаг режима калибровки реле 1 (0 - выкл, 1 -вкл)
bool calibration2 = 0; // флаг режима калибровки реле 2 (0 - выкл, 1 -вкл)
bool calibration3 = 0; // флаг режима калибровки реле 3 (0 - выкл, 1 -вкл)
bool calibration4 = 0; // флаг режима калибровки реле 4 (0 - выкл, 1 -вкл)
bool checkDelay1 = 1; // флаг проверки задержки первого включения реле 1 (0 - выкл, 1 -вкл)
bool checkDelay2 = 1; // флаг проверки задержки первого включения реле 2 (0 - выкл, 1 -вкл)
bool checkDelay3 = 1; // флаг проверки задержки первого включения реле 3 (0 - выкл, 1 -вкл)
bool checkDelay4 = 1; // флаг проверки задержки первого включения реле 4 (0 - выкл, 1 -вкл)
bool stopRelay1 = 0; // флаг режима "СТОП" реле 1
bool stopRelay2 = 0; // флаг режима "СТОП" реле 2
bool stopRelay3 = 0; // флаг режима "СТОП" реле 3
bool stopRelay4 = 0; // флаг режима "СТОП" реле 4
uint8_t pompNum = 0; // номер выбранного насоса (0 - основной экран, 1-4 - насосы)
uint8_t pompInfoMode = 0; // тип отображаемой информации для насоса (0 - инфо, 1 - настройка, 2 - калибровка)
bool emergency = 0; // флаг аварийной остановки всех насосов
bool blink = false; // флаг миганием буквой "З" если активна задержка
bool dispBright = true; // флаг яркости дисплея (0 - мин, 1 - макс)
const uint8_t ok[] PROGMEM = { // ok
0x7f, 0x63, 0x5d, 0x5d, 0x63, 0x7f, 0x41, 0x77, 0x6b, 0x5d, 0x7f
};
const uint8_t grid[] PROGMEM = { // сетка на главном экране
0xff, 0x01, 0x7d, 0x09, 0x11, 0x21, 0x7d, 0x01, 0xff, 0x01, 0x7d, 0x15, 0x15, 0x15, 0x09, 0x01, 0xff, 0x01, 0x7d, 0x15, 0x15, 0x09, 0x01, 0x79,
0x15, 0x15, 0x79, 0x01, 0x7d, 0x55, 0x55, 0x25, 0x01, 0x39, 0x45, 0x45, 0x39, 0x01, 0x05, 0x7d, 0x05, 0x01, 0x79, 0x15, 0x15, 0x79, 0x01, 0x01,
0xff, 0x01, 0x7d, 0x05, 0x05, 0x7d, 0x01, 0x7d, 0x55, 0x45, 0x01, 0x7d, 0x15, 0x15, 0x09, 0x01, 0x7d, 0x31, 0x19, 0x7d, 0x01, 0x39, 0x45, 0x45,
0x39, 0x01, 0x61, 0x3d, 0x25, 0x3d, 0x61, 0x01, 0xff, 0x01, 0x39, 0x45, 0x45, 0x39, 0x01, 0x39, 0x45, 0x45, 0x01, 0x05, 0x7d, 0x05, 0x01, 0x79,
0x15, 0x79, 0x01, 0x05, 0x7d, 0x05, 0x01, 0x39, 0x45, 0x45, 0x39, 0x01, 0x7d, 0x11, 0x6d, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1d, 0x21,
0x41, 0x21, 0x1d, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xff,
0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0xff, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xff, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0xff, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xff, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xff, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0xff, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t set[] PROGMEM = { // настройка 39*9
0xff, 0x01, 0x55, 0x01, 0x7d, 0x09, 0x11, 0x09, 0x7d, 0x01, 0x55, 0x01, 0xff, 0xff, 0x83, 0xef, 0xef, 0x83, 0xff, 0x87, 0xeb, 0xeb, 0x87, 0xff,
0xc7, 0xbb, 0xbb, 0xff, 0xfb, 0x83, 0xfb, 0xff, 0x83, 0xeb, 0xeb, 0xf7, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t stopSet[] PROGMEM = { // закончить настройку 39*9
0xff, 0x01, 0x55, 0x01, 0x7d, 0x09, 0x11, 0x09, 0x7d, 0x01, 0x55, 0x01, 0xff, 0xff, 0xbb, 0xab, 0xd7, 0xff, 0x87, 0xeb, 0x87, 0xff, 0x83, 0xef,
0xd7, 0xbb, 0xff, 0xc7, 0xbb, 0xc7, 0xff, 0x83, 0xef, 0x83, 0xff, 0xf3, 0xef, 0x83, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t save[] PROGMEM = { // сохранить 40*9
0xff, 0x01, 0x55, 0x01, 0x61, 0x19, 0x05, 0x19, 0x61, 0x01, 0x55, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xbb, 0xbb, 0xff, 0xc7, 0xbb, 0xbb, 0xc7,
0xff, 0xbb, 0xd7, 0xef, 0xd7, 0xbb, 0xff, 0x83, 0xeb, 0xeb, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t stop[] PROGMEM = { // стоп 39*9
0xff, 0x01, 0x55, 0x01, 0x7d, 0x09, 0x11, 0x09, 0x7d, 0x01, 0x55, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xbb, 0xbb, 0xff, 0xfb, 0xfb, 0x83, 0xfb,
0xfb, 0xff, 0xc7, 0xbb, 0xbb, 0xc7, 0xff, 0x83, 0xfb, 0xfb, 0x83, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t start[] PROGMEM = { // старт 39*9
0xff, 0x01, 0x55, 0x01, 0x7d, 0x09, 0x11, 0x09, 0x7d, 0x01, 0x55, 0x01, 0xff, 0xff, 0xff, 0xc7, 0xbb, 0xbb, 0xff, 0xfb, 0x83, 0xfb, 0xff, 0x87,
0xeb, 0xeb, 0x87, 0xff, 0x83, 0xeb, 0xeb, 0xf7, 0xff, 0xfb, 0x83, 0xfb, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t on[] PROGMEM = { // включить 39*9
0xff, 0x01, 0x01, 0x7d, 0x09, 0x11, 0x09, 0x7d, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xab, 0xab, 0xd7, 0xff, 0x83, 0xef,
0xd7, 0xbb, 0xff, 0x87, 0xfb, 0xfb, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t off[] PROGMEM = { // выключить 39*9
0xff, 0x01, 0x01, 0x7d, 0x09, 0x11, 0x09, 0x7d, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x83, 0xab, 0xab, 0xd7, 0xff, 0x83, 0xaf, 0xdf, 0xff, 0x83,
0xff, 0x83, 0xef, 0xd7, 0xbb, 0xff, 0x87, 0xfb, 0xfb, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t on_mini[] PROGMEM = { // включить мини 29*9
0xff, 0x01, 0x7d, 0x09, 0x11, 0x09, 0x7d, 0x01, 0xff, 0xff, 0xff, 0x83, 0xab, 0xab, 0xd7, 0xff, 0x83, 0xef, 0xd7, 0xbb, 0xff, 0x87, 0xfb, 0xfb,
0x87, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t off_mini[] PROGMEM = { // выключить мини 29*9
0xff, 0x01, 0x7d, 0x09, 0x11, 0x09, 0x7d, 0x01, 0xff, 0x83, 0xab, 0xd7, 0xff, 0x83, 0xaf, 0x8f, 0xff, 0x83, 0xff, 0x83, 0xef, 0xd7, 0xbb, 0xff,
0x87, 0xfb, 0xfb, 0x87, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t information[] PROGMEM = { // инфо 40*9
0xff, 0x01, 0x61, 0x19, 0x05, 0x19, 0x61, 0x01, 0x0d, 0x31, 0x41, 0x31, 0x0d, 0x01, 0xff, 0xff, 0xff, 0x83, 0xcf, 0xe7, 0x83, 0xff, 0x83, 0xef,
0xef, 0x83, 0xff, 0xe7, 0xdb, 0x83, 0xdb, 0xe7, 0xff, 0xc7, 0xbb, 0xbb, 0xc7, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t arrows[] PROGMEM = { // стрелки 40*9
0xff, 0x01, 0x61, 0x19, 0x05, 0x19, 0x61, 0x01, 0x0d, 0x31, 0x41, 0x31, 0x0d, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xe7, 0x83, 0xe7,
0xef, 0xff, 0xff, 0xff, 0xff, 0xef, 0xcf, 0x83, 0xcf, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t arrows_mini[] PROGMEM = { // стрелки мини 28*9
0xff, 0x01, 0x61, 0x19, 0x05, 0x19, 0x61, 0x01, 0x0d, 0x31, 0x41, 0x31, 0x0d, 0x01, 0xff, 0xef, 0xe7, 0x83, 0xe7, 0xef, 0xff, 0xff, 0xef, 0xcf,
0x83, 0xcf, 0xef, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t back[] PROGMEM = { // назад 40*9
0xff, 0x01, 0x01, 0x11, 0x29, 0x45, 0x01, 0x01, 0xff, 0xff, 0xff, 0x83, 0xef, 0xef, 0x83, 0xff, 0x87, 0xeb, 0xeb, 0x87, 0xff, 0xbb, 0xab, 0xab,
0xd7, 0xff, 0x87, 0xeb, 0xeb, 0x87, 0xff, 0x9f, 0xc7, 0xdb, 0xdb, 0xc3, 0x9f, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t back_mini[] PROGMEM = { // назад мини 15*9
0xff, 0x01, 0x11, 0x29, 0x45, 0x01, 0xff, 0xef, 0xc7, 0x83, 0xef, 0xef, 0xef, 0xef, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t calibration[] PROGMEM = { // калибровка 40*9
0xff, 0x01, 0x01, 0x45, 0x29, 0x11, 0x01, 0x01, 0xff, 0x83, 0xef, 0xd7, 0xbb, 0xff, 0x87, 0xeb, 0xeb, 0x87, 0xff, 0x87, 0xfb, 0xfb, 0x87, 0xff,
0x83, 0xcf, 0xe7, 0x83, 0xff, 0x83, 0xab, 0xab, 0xdb, 0xff, 0x83, 0xeb, 0xeb, 0xf7, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
const uint8_t val[] PROGMEM = { // +/- 25*9
0xff, 0x01, 0x11, 0x29, 0x45, 0x01, 0x01, 0x45, 0x29, 0x11, 0x01, 0xff, 0xef, 0xef, 0xef, 0xef, 0xef, 0xff, 0xff, 0xef, 0xef, 0x83, 0xef, 0xef,
0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01
};
void setup() { // задаем начальные настройки
oled.init();
oled.setContrast(250);
pinMode(RELAY1_PIN, OUTPUT);
digitalWrite(RELAY1_PIN, LOW);
pinMode(RELAY2_PIN, OUTPUT);
digitalWrite(RELAY2_PIN, LOW);
pinMode(RELAY3_PIN, OUTPUT);
digitalWrite(RELAY3_PIN, LOW);
pinMode(RELAY4_PIN, OUTPUT);
digitalWrite(RELAY4_PIN, LOW);
memory.begin(0, 'x'); // Сменить здесь букву в кавычках на любую другую латинскую букву и прошить Arduino, если не получается сбросить настройки через устройство *
tmrMotor1.setMode(GTMode::Interval); // Настройка таймера 1 (насос 1)
tmrMotor1.keepPhase(true);
tmrMotor1.setTime(data.frequency1);
tmrDelay1.setMode(GTMode::Timeout); // Настройка задержки таймера 1 (насос 1)
tmrDelay1.setTime(data.delay1);
if (data.delay1 == 0) tmrMotor1.start();
else tmrDelay1.start();
tmrMotor2.setMode(GTMode::Interval); // Настройка таймера 2 (насос 2)
tmrMotor2.keepPhase(true);
tmrMotor2.setTime(data.frequency2);
tmrDelay2.setMode(GTMode::Timeout); // Настройка задержки таймера 2 (насос 2)
tmrDelay2.setTime(data.delay2);
if (data.delay2 == 0) tmrMotor2.start();
else tmrDelay2.start();
tmrMotor3.setMode(GTMode::Interval); // Настройка таймера 3 (насос 3)
tmrMotor3.keepPhase(true);
tmrMotor3.setTime(data.frequency3);
tmrDelay3.setMode(GTMode::Timeout); // Настройка задержки таймера 3 (насос 3)
tmrDelay3.setTime(data.delay3);
if (data.delay3 == 0) tmrMotor3.start();
else tmrDelay3.start();
tmrMotor4.setMode(GTMode::Interval); // Настройка таймера 4 (насос 4)
tmrMotor4.keepPhase(true);
tmrMotor4.setTime(data.frequency4);
tmrDelay4.setMode(GTMode::Timeout); // Настройка задержки таймера 4 (насос 4)
tmrDelay4.setTime(data.delay4);
if (data.delay4 == 0) tmrMotor4.start();
else tmrDelay4.start();
tmrDisplay.setMode(GTMode::Timeout); // Настройка таймера 5 (выключение дисплея)
tmrDisplay.setTime(120000);
tmrDisplay.start();
if (data.delay1 == 0) checkDelay1 = false; // если задержка == 0, тогда сразу опускаем флаг проверки задержки первого включения
if (data.delay2 == 0) checkDelay2 = false;
if (data.delay3 == 0) checkDelay3 = false;
if (data.delay4 == 0) checkDelay4 = false;
if (data.delay1 == 0 and data.mode1 == 2) {tmrMotor1.stop(); stopRelay1 = 1;} // ПРИ ВКЛЮЧЕНИИ ОСТАНАВЛИВАЕМ ТАЙМЕР НУЖНОГО НАСОСА, ЕСЛИ НАСТРОЕН РЕЖИМ "СТОП"
if (data.delay2 == 0 and data.mode2 == 2) {tmrMotor2.stop(); stopRelay2 = 1;}
if (data.delay3 == 0 and data.mode3 == 2) {tmrMotor3.stop(); stopRelay3 = 1;}
if (data.delay4 == 0 and data.mode4 == 2) {tmrMotor4.stop(); stopRelay4 = 1;}
}
void loop() {
getCheckDelay();
//static bool display = true; // флаг вкл/выкл дисплея
btnM.tick(); // тикеры кнопок
btnUP.tick();
btnDOWN.tick();
btnLEFT.tick();
btnRIGHT.tick();
memory.tick(); // тикер EEPROM
if (btnDOWN.click() and pompInfoMode == 0) { // кнопка DOWN - переключать экраны с насосами вниз
if (pompNum == 4) pompNum = 0;
else pompNum++;
}
if (btnUP.click() and pompInfoMode == 0) { // кнопка UP - переключать экраны с насосами вверх
if (pompNum == 0) pompNum = 4;
else pompNum--;
}
switch (pompNum) { // отображение экрана выбранного насоса
case 0: info(); break;
case 1:
case 2:
case 3:
case 4:
if (pompInfoMode == 2) getCalibration(pompNum);
else getPompInfo(pompNum);
break;
}
if (flagRelay1) digitalWrite(RELAY1_PIN, HIGH); // вкл/откл реле 1
else digitalWrite(RELAY1_PIN, LOW);
if (flagRelay2) digitalWrite(RELAY2_PIN, HIGH); // вкл/откл реле 2
else digitalWrite(RELAY2_PIN, LOW);
if (flagRelay3) digitalWrite(RELAY3_PIN, HIGH); // вкл/откл реле 3
else digitalWrite(RELAY3_PIN, LOW);
if (flagRelay4) digitalWrite(RELAY4_PIN, HIGH); // вкл/откл реле 4
else digitalWrite(RELAY4_PIN, LOW);
if (tmrDisplay.getLeft() == 0) { // приглушить дисплей по таймеру
//display = false;
dispBright = false;
pompNum = 0;
pompInfoMode = 0;
} else dispBright = true;
//if (display) oled.setPower(1);
//else oled.setPower(0);
if (dispBright) oled.setContrast(250);
else oled.setContrast(1);
// перезапустить таймер приглушения дисплея при нажатии какой-либо кнопки
if (btnM.click() or btnUP.click() or btnDOWN.click() or btnLEFT.click() or btnRIGHT.click() or btnM.hold() or btnUP.hold() or btnDOWN.hold() or btnLEFT.hold() or btnRIGHT.hold()) tmrDisplay.start();
/*if (dispBright) { // перезапустить таймер приглушения дисплея при нажатии какой-либо кнопки
if (btnM.click() or btnUP.click() or btnDOWN.click() or btnLEFT.click() or btnRIGHT.click() or btnM.hold() or btnUP.hold() or btnDOWN.hold() or btnLEFT.hold() or btnRIGHT.hold()) tmrDisplay.start();
} else {
if (btnM.click()) {
tmr5.start();
display = true;
}
}*/
}
void info() { // ОСНОВНОЙ ЭКРАН
getTimer(); // получаем таймеры всех насосов
static bool saveSettings = false; // флаг сохранения настроек
static uint32_t timerSave;
if (btnM.hold() and pompInfoMode == 0) { // удержание кнопки М - аварийная приостановка/запуск всех реле
static uint8_t mode1; // временные переменные для хранения состояния режима реле
static uint8_t mode2;
static uint8_t mode3;
static uint8_t mode4;
emergency = !emergency;
if (emergency) {
mode1 = data.mode1;
mode2 = data.mode2;
mode3 = data.mode3;
mode4 = data.mode4;
if (data.mode1 == 0) {data.mode1 = 1; flagRelay1 = false;}
if (data.mode2 == 0) {data.mode2 = 1; flagRelay2 = false;}
if (data.mode3 == 0) {data.mode3 = 1; flagRelay3 = false;}
if (data.mode4 == 0) {data.mode4 = 1; flagRelay4 = false;}
} else {
data.mode1 = mode1;
data.mode2 = mode2;
data.mode3 = mode3;
data.mode4 = mode4;
}
//if (!data.mode1 or !data.mode2 or !data.mode3 or !data.mode4) {data.mode1 = true; data.mode2 = true; data.mode3 = true; data.mode4 = true;}
//else if (data.mode1 and data.mode2 and data.mode3 and data.mode4) {data.mode1 = false; data.mode2 = false; data.mode3 = false; data.mode4 = false;}
//checkMode();
}
oled.clear(); // очистить дисплей
if (data.mode1 != 0 and data.mode2 != 0 and data.mode3 != 0 and data.mode4 != 0) oled.drawBitmap(44, 55, start, 39, 9); // подсказки для кнопок
else oled.drawBitmap(44, 55, stop, 39, 9);
oled.drawBitmap(0, 55, arrows, 40, 9);
if (!saveSettings) oled.drawBitmap(88, 55, save, 40, 9);
if (btnUP.holdFor(3000)) { // удержание кнопки UP в теч. 3 сек - записать в память
timerSave = millis();
memory.update();
saveSettings = true;
}
if (saveSettings) { // иконка сохранения настроек
oled.rect(88, 51, 127, 63, OLED_FILL);
oled.textMode(1);
oled.setCursorXY(103, 54);
oled.print(F("OK"));
oled.textMode(0);
}
if (millis() - timerSave > 2000) saveSettings = false;
if (digitalRead(RELAY1_PIN) == HIGH) { // инфо по насосу 1
oled.rect(1, 9, 7, 17, OLED_FILL);
oled.textMode(1);
}
oled.setCursorXY(2, 10);
oled.print(F("1"));
oled.textMode(0);
oled.setCursorXY(10, 10);
if (data.mode1 == 1) oled.print(F("Р"));
else if (data.mode1 == 2) oled.print(F("С"));
else oled.print(F("А"));
oled.setCursorXY(18, 10);
oled.print(data.workTime1);
oled.setCursorXY(50, 10);
oled.print(data.frequency1 / 1000);
oled.setCursorXY(82, 10);
if (data.mode1 == 0) oled.print(ceil(tmrMotor1.getLeft() / 1000.0), 0);
else if (data.mode1 == 1) oled.print(F("РУЧН."));
else oled.print(F("СТОП"));
if (checkDelay1) {
blinkDelayOn();
if (blink) {
oled.setCursorXY(114, 10);
oled.print(F("З"));
}
}
if (digitalRead(RELAY2_PIN) == HIGH) { // инфо по насосу 2
oled.rect(1, 19, 7, 27, OLED_FILL);
oled.textMode(1);
}
oled.setCursorXY(2, 20);
oled.print(F("2"));
oled.textMode(0);
oled.setCursorXY(10, 20);
if (data.mode2 == 1) oled.print(F("Р"));
else if (data.mode2 == 2) oled.print(F("С"));
else oled.print(F("А"));
oled.setCursorXY(18, 20);
oled.print(data.workTime2);
oled.setCursorXY(50, 20);
oled.print(data.frequency2 / 1000);
oled.setCursorXY(82, 20);
if (data.mode2 == 0) oled.print(ceil(tmrMotor2.getLeft() / 1000.0), 0);
else if (data.mode2 == 1) oled.print(F("РУЧН."));
else oled.print(F("СТОП"));
if (checkDelay2) {
blinkDelayOn();
if (blink) {
oled.setCursorXY(114, 20);
oled.print(F("З"));
}
}
if (digitalRead(RELAY3_PIN) == HIGH) { // инфо по насосу 3
oled.rect(1, 29, 7, 37, OLED_FILL);
oled.textMode(1);
}
oled.setCursorXY(2, 30);
oled.print(F("3"));
oled.textMode(0);
oled.setCursorXY(10, 30);
if (data.mode3 == 1) oled.print(F("Р"));
else if (data.mode3 == 2) oled.print(F("С"));
else oled.print(F("А"));
oled.setCursorXY(18, 30);
oled.print(data.workTime3);
oled.setCursorXY(50, 30);
oled.print(data.frequency3 / 1000);
oled.setCursorXY(82, 30);
if (data.mode3 == 0) oled.print(ceil(tmrMotor3.getLeft() / 1000.0), 0);
else if (data.mode3 == 1) oled.print(F("РУЧН."));
else oled.print(F("СТОП"));
if (checkDelay3) {
blinkDelayOn();
if (blink) {
oled.setCursorXY(114, 30);
oled.print(F("З"));
}
}
if (digitalRead(RELAY4_PIN) == HIGH) { // инфо по насосу 4
oled.rect(1, 39, 7, 47, OLED_FILL);
oled.textMode(1);
}
oled.setCursorXY(2, 40);
oled.print(F("4"));
oled.textMode(0);
oled.setCursorXY(10, 40);
if (data.mode4 == 1) oled.print(F("Р"));
else if (data.mode4 == 2) oled.print(F("С"));
else oled.print(F("А"));
oled.setCursorXY(18, 40);
oled.print(data.workTime4);
oled.setCursorXY(50, 40);
oled.print(data.frequency4 / 1000);
oled.setCursorXY(82, 40);
if (data.mode4 == 0) oled.print(ceil(tmrMotor4.getLeft() / 1000.0), 0);
else if (data.mode4 == 1) oled.print(F("РУЧН."));
else oled.print(F("СТОП"));
if (checkDelay4) {
blinkDelayOn();
if (blink) {
oled.setCursorXY(114, 40);
oled.print(F("З"));
}
}
oled.drawBitmap(0, 0, grid, 128, 49);
oled.update(); // обновить дисплей
}
void getPompInfo(uint8_t num) { // ДЕТАЛЬНАЯ ИНФОРМАЦИЯ ПО КАЖДОМУ НАСОСУ
getTimer(); // получаем таймеры всех насосов
static uint8_t items = 1; // счетчик выбранного параметра для настройки
oled.clear(); // очистить дисплей
if (pompInfoMode == 1) oled.drawBitmap(30, 55, stopSet, 39, 9); // подсказки для кнопок
else oled.drawBitmap(30, 55, set, 39, 9);
oled.drawBitmap(0, 55, arrows_mini, 28, 9);
if (pompInfoMode == 0) oled.drawBitmap(71, 55, back_mini, 15, 9);
if (pompInfoMode == 1) oled.drawBitmap(71, 55, val, 25, 9);
if (getMode(num) == 1 and pompInfoMode == 1) {
if (getRelayStatus2(num)) oled.drawBitmap(98, 55, off_mini, 29, 9);
else oled.drawBitmap(98, 55, on_mini, 29, 9);
} else if (getMode(num) == 1 and pompInfoMode == 0) {
if (getRelayStatus2(num)) oled.drawBitmap(99, 44, off_mini, 29, 9);
else oled.drawBitmap(99, 44, on_mini, 29, 9);
}
if (pompInfoMode == 0) oled.drawBitmap(88, 55, calibration, 40, 9);
if (pompInfoMode == 0 and btnLEFT.click()) pompNum = 0; // кнопка LEFT - вернуться на главный экран
if (btnM.hold()) { // удержание кнопки M - режим просмотра/настройки
if (pompInfoMode == 0) pompInfoMode = 1;
else {
pompInfoMode = 0;
items = 1;
}
if (getMode(num) == 2) {timerStop(num); stopRelay(num);}
if (stopRelayFlag(num) and getMode(num) != 2) {timerStart(num); startRelay(num);}
}
if (btnM.click() and getMode(num) == 1) { // вкл/выкл насосов кнопкой M (в ручном режиме)
switch (num) {
case 1: flagRelay1 = !flagRelay1; break;
case 2: flagRelay2 = !flagRelay2; break;
case 3: flagRelay3 = !flagRelay3; break;
case 4: flagRelay4 = !flagRelay4; break;
}
}
if (pompInfoMode == 0 and btnRIGHT.click()) { // кнопка RIGHT - перейти в режим калибровки
pompInfoMode = 2;
onCalibration(num);
offRelay(num);
}
if (pompInfoMode == 1 and btnDOWN.click()) { // кнопка DOWN - в режиме настройки перемещаемся по параметрам вниз
if (items == 4) items = 1;
else items++;
}
if (pompInfoMode == 1 and btnUP.click()) { // кнопка UP - в режиме настройки перемещаемся по параметрам вВЕРХ
if (items == 1) items = 4;
else items--;
}
if (pompInfoMode == 1) { // в режиме настройки изменяем параметры кнопками UP/DOWN
uint8_t position = 4;
if (items >= 4) position = 5;
oled.setCursorXY(123, items * 8 + position);
oled.print(F("<"));
switch (items) {
case 1:
if (btnLEFT.click() or btnLEFT.holding()) {
setMode(num, 0);
if (getMode(num) != 0) offRelay(num);
}
if (btnRIGHT.click() or btnRIGHT.holding()) {
setMode(num, 1);
if (getMode(num) != 0) offRelay(num);
}
break;
case 2:
if (btnLEFT.click() or btnLEFT.holding()) setWorkTime(num, 0);
if (btnRIGHT.click() or btnRIGHT.holding()) setWorkTime(num, 1);
break;
case 3:
if (btnLEFT.click() or btnLEFT.holding()) setFrequency(num, 0);
if (btnRIGHT.click() or btnRIGHT.holding()) setFrequency(num, 1);
break;
case 4:
if (btnLEFT.click() or btnLEFT.holding()) setDelay(num, 0);
if (btnRIGHT.click() or btnRIGHT.holding()) setDelay(num, 1);
break;
}
}
if (!getRelayStatus2(num)) oled.circle(123, 4, 4, OLED_STROKE);
else oled.circle(123, 4, 4, OLED_FILL);
oled.rect(0, 0, 112, 8, OLED_FILL); // подробная инфо на дисплее
oled.setCursorXY(40, 1);
oled.textMode(1);
oled.print(F("НАСОС"));
oled.setCursorXY(75, 1);
oled.print(num);
oled.textMode(0);
oled.setCursorXY(0, 12);
oled.print(F("РЕЖИМ"));
oled.setCursorXY(50, 12);
if (getMode(num) == 1) oled.print(F("РУЧНОЙ"));
else if (getMode(num) == 2) oled.print(F("СТОП"));
else oled.print(F("АВТО"));
oled.setCursorXY(0, 20);
oled.print(F("РАБОТА"));
oled.setCursorXY(50, 20);
oled.print(getWorkTime(num));
oled.setCursorXY(0, 28);
oled.print(F("ПЕРИОД"));
oled.setCursorXY(50, 28);
oled.print(getFrequency(num) / 1000);
oled.setCursorXY(0, 37);
oled.print(F("ЗАДЕРЖ."));
oled.setCursorXY(50, 37);
oled.print(getDelay(num) / 1000);
oled.setCursorXY(0, 45);
oled.print(F("ОСТАТОК"));
oled.setCursorXY(50, 45);
if (getMode(num) == 0 or getMode(num) == 1) oled.print(ceil(timerGetLeft(num) / 1000.0), 0);
else oled.print(F("СТОП"));
if (checkDelay(num)) {
blinkDelayOn();
if (blink) {
oled.setCursorXY(123, 45);
oled.print(F("З"));
}
}
oled.update(); // обновить дисплей
}
void getCalibration(uint8_t num) { // ЭКРАН КАЛИБРОВКИ
getTimer(); // получаем таймеры всех насосов
static bool measure = false; // флаг включения реле в режиме калибровки
static uint32_t start = 0; // старт калибровки
static uint32_t stop = 0; // окончание калибровки
if (btnLEFT.click()) { // кнопка LEFT - вернуться в режим настройки
pompInfoMode = 0;
start = 0;
stop = 0;
measure = false;
offRelay(num);
offCalibration(num);
}
oled.clear(); // очистить дисплей
if (measure) oled.drawBitmap(43, 55, off, 39, 9); // подсказки для кнопок
else oled.drawBitmap(43, 55, on, 39, 9);
oled.drawBitmap(0, 55, back, 40, 9);
if (getRelayStatus2(num)) oled.circle(124, 3, 3, OLED_FILL);
if (btnM.click()) { // при нажатии кнопки M...
measure = !measure; // вкл/выкл калибровку (старт/стоп)
if (measure) {
start = millis();
onRelay(num);
} else {
stop = millis();
offRelay(num);
}
}
oled.setCursorXY(0, 0); // инфо на дисплее
oled.print(F("КАЛИБРОВКА НАСОСА"));
oled.setCursorXY(108, 0);
oled.print(num);
/*oled.setCursorXY(3, 17);
oled.print(getVoltage(num));
oled.setCursorXY(3, 28);
oled.print(F("ВОЛЬТ"));*/
oled.setScale(2);
oled.setCursorXY(10, 19);
if (measure) oled.print(millis() - start); // отображать замеренное время калибровки
else oled.print(stop - start);
oled.setScale(1);
oled.rect(0, 10, 127, 42, OLED_STROKE);
//oled.line(34, 11, 34, 41);
oled.update();
}
bool getRelayStatus2(uint8_t num) { // УЗНАЕМ СТАТУС НАСОСА
switch (num) {
case 1: return flagRelay1; break;
case 2: return flagRelay2; break;
case 3: return flagRelay3; break;
case 4: return flagRelay4; break;
}
}
void onRelay(uint8_t num) { // ВКЛЮЧИТЬ НУЖНЫЙ НАСОС
switch (num) {
case 1: flagRelay1 = true; break;
case 2: flagRelay2 = true; break;
case 3: flagRelay3 = true; break;
case 4: flagRelay4 = true; break;
}
}
void offRelay(uint8_t num) { // ВЫКЛЮЧИТЬ НУЖНЫЙ НАСОС
switch (num) {
case 1: flagRelay1 = false; break;
case 2: flagRelay2 = false; break;
case 3: flagRelay3 = false; break;
case 4: flagRelay4 = false; break;
}
}
bool stopRelayFlag(uint8_t num) { // СТАТУС ФЛАГА ОСТАНОВКИ НАСОСА
switch (num) {
case 1: return stopRelay1; break;
case 2: return stopRelay2; break;
case 3: return stopRelay3; break;
case 4: return stopRelay4; break;
}
}
bool checkDelay(uint8_t num) { // СТАТУС НАЛИЧИЯ АКТИВНОЙ ЗАДЕРЖКИ НАСОСА
switch (num) {
case 1: return checkDelay1; break;
case 2: return checkDelay2; break;
case 3: return checkDelay3; break;
case 4: return checkDelay4; break;
}
}
void stopRelay(uint8_t num) { // ОСТАНОВИТЬ ТАЙМЕР НУЖНОГО НАСОСА
switch (num) {
case 1: stopRelay1 = true; break;
case 2: stopRelay2 = true; break;
case 3: stopRelay3 = true; break;
case 4: stopRelay4 = true; break;
}
}
void startRelay(uint8_t num) { // ПЕРЕЗАПУСТИТЬ ТАЙМЕР НУЖНОГО НАСОСА
switch (num) {
case 1: stopRelay1 = false; break;
case 2: stopRelay2 = false; break;
case 3: stopRelay3 = false; break;
case 4: stopRelay4 = false; break;
}
}
void onCalibration(uint8_t num) { // ВКЛЮЧИТЬ РЕЖИМ КАЛИБРОВКИ НУЖНОГО НАСОСА
switch (num) {
case 1: calibration1 = true; break;
case 2: calibration2 = true; break;
case 3: calibration3 = true; break;
case 4: calibration4 = true; break;
}
}
void offCalibration(uint8_t num) { // ВЫКЛЮЧИТЬ РЕЖИМ КАЛИБРОВКИ НУЖНОГО НАСОСА
switch (num) {
case 1: calibration1 = false; break;
case 2: calibration2 = false; break;
case 3: calibration3 = false; break;
case 4: calibration4 = false; break;
}
}
void timerPause(uint8_t num) { // ПОСТАВИТЬ НУЖНЫЙ ТАЙМЕР НА ПАУЗУ
switch (num) {
case 1: tmrMotor1.pause(); break;
case 2: tmrMotor2.pause(); break;
case 3: tmrMotor3.pause(); break;
case 4: tmrMotor4.pause(); break;
}
}
void timerStop(uint8_t num) { // ОСТАНОВИТЬ НУЖНЫЙ ТАЙМЕР
switch (num) {
case 1: tmrMotor1.stop(); break;
case 2: tmrMotor2.stop(); break;
case 3: tmrMotor3.stop(); break;
case 4: tmrMotor4.stop(); break;
}
}
void timerStart(uint8_t num) { // ПЕРЕЗАПУСТИТЬ НУЖНЫЙ ТАЙМЕР
switch (num) {
case 1: tmrMotor1.start(); break;
case 2: tmrMotor2.start(); break;
case 3: tmrMotor3.start(); break;
case 4: tmrMotor4.start(); break;
}
}
void timerResume(uint8_t num) { // СНЯТЬ НУЖНЫЙ ТАЙМЕР С ПАУЗЫ
switch (num) {
case 1: tmrMotor1.resume(); break;
case 2: tmrMotor2.resume(); break;
case 3: tmrMotor3.resume(); break;
case 4: tmrMotor4.resume(); break;
}
}
uint32_t timerGetLeft(uint8_t num) { // УЗНАТЬ ОСТАТОК ВРЕМЕНИ ТАЙМЕРА НУЖНОГО НАСОСА
switch (num) {
case 1: return tmrMotor1.getLeft(); break;
case 2: return tmrMotor2.getLeft(); break;
case 3: return tmrMotor3.getLeft(); break;
case 4: return tmrMotor4.getLeft(); break;
}
}
uint8_t getMode(uint8_t num) { // УЗНАЕМ РЕЖИМ РАБОТЫ НАСОСА
switch (num) {
case 1: return data.mode1; break;
case 2: return data.mode2; break;
case 3: return data.mode3; break;
case 4: return data.mode4; break;
}
}
uint16_t getWorkTime(uint8_t num) { // УЗНАЕМ ВРЕМЯ РАБОТЫ НАСОСА
switch (num) {
case 1: return data.workTime1; break;
case 2: return data.workTime2; break;
case 3: return data.workTime3; break;
case 4: return data.workTime4; break;
}
}
uint32_t getFrequency(uint8_t num) { // УЗНАЕМ ПЕРИОД СРАБАТЫВАНИЯ НАСОСА
switch (num) {
case 1: return data.frequency1; break;
case 2: return data.frequency2; break;
case 3: return data.frequency3; break;
case 4: return data.frequency4; break;
}
}
/*float getVoltage(uint8_t num) { // УЗНАЕМ ВОЛЬТАЖ МОТОРА НАСОСА
switch (num) {
case 1: return data.voltage1; break;
case 2: return data.voltage2; break;
case 3: return data.voltage3; break;
case 4: return data.voltage4; break;
}
}*/
uint32_t getDelay(uint8_t num) { // УЗНАЕМ ЗАДЕРЖКУ ВКЛЮЧЕНИЯ МОТОРА НАСОСА
switch (num) {
case 1: return data.delay1; break;
case 2: return data.delay2; break;
case 3: return data.delay3; break;
case 4: return data.delay4; break;
}
}
void setWorkTime(uint16_t num, bool operation) { // УСТАОВИТЬ ВРЕМЯ РАБОТЫ НАСОСА
if (operation == 1) {
switch (num) {
case 1: data.workTime1 += 20; break;
case 2: data.workTime2 += 20; break;
case 3: data.workTime3 += 20; break;
case 4: data.workTime4 += 20; break;
}
} else {
switch (num) {
case 1: data.workTime1 -= 20; break;
case 2: data.workTime2 -= 20; break;
case 3: data.workTime3 -= 20; break;
case 4: data.workTime4 -= 20; break;
}
}
}
void setFrequency(uint16_t num, bool operation) { // УСТАОВИТЬ ПЕРИОД РАБОТЫ НАСОСА
if (operation == 1) {
switch (num) {
case 1: data.frequency1 += 1000; break;
case 2: data.frequency2 += 1000; break;
case 3: data.frequency3 += 1000; break;
case 4: data.frequency4 += 1000; break;
}
} else {
switch (num) {
case 1: data.frequency1 -= 1000; break;
case 2: data.frequency2 -= 1000; break;
case 3: data.frequency3 -= 1000; break;
case 4: data.frequency4 -= 1000; break;
}
}
}
void setMode(uint16_t num, bool operation) { // УСТАОВИТЬ РЕЖИМ РАБОТЫ НАСОСА
if (operation == 1) {
switch (num) {
case 1:
if (data.mode1 == 2) data.mode1 = 0;
else data.mode1 += 1;
break;
case 2:
if (data.mode2 == 2) data.mode2 = 0;
else data.mode2 += 1;
break;
case 3:
if (data.mode3 == 2) data.mode3 = 0;
else data.mode3 += 1;
break;
case 4:
if (data.mode4 == 2) data.mode4 = 0;
else data.mode4 += 1;
break;
}
} else {
switch (num) {
case 1:
if (data.mode1 == 0) data.mode1 = 2;
else data.mode1 -= 1;
break;
case 2:
if (data.mode2 == 0) data.mode2 = 2;
else data.mode2 -= 1;
break;
case 3:
if (data.mode3 == 0) data.mode3 = 2;
else data.mode3 -= 1;
break;
case 4:
if (data.mode4 == 0) data.mode4 = 2;
else data.mode4 -= 1;
break;
}
}
}
void setDelay(uint16_t num, bool operation) { // УСТАОВИТЬ ЗАДЕРЖКУ ВКЛЮЧЕНИЯ МОТОРА НАСОСА
if (operation == 1) {
switch (num) {
case 1: data.delay1 += 1000; break;
case 2: data.delay2 += 1000; break;
case 3: data.delay3 += 1000; break;
case 4: data.delay4 += 1000; break;
}
} else {
switch (num) {
case 1: data.delay1 -= 1000; break;
case 2: data.delay2 -= 1000; break;
case 3: data.delay3 -= 1000; break;
case 4: data.delay4 -= 1000; break;
}
}
}
void getTimer() { // ТАЙМЕРЫ РЕЛЕ
if (data.mode1 == 0 and !calibration1 and tmrMotor1) flagRelay1 = true;
if (data.mode1 == 0 and !calibration1 and tmrMotor1.getCurrent() >= data.workTime1) flagRelay1 = false;
if (data.mode2 == 0 and !calibration2 and tmrMotor2) flagRelay2 = true;
if (data.mode2 == 0 and !calibration2 and tmrMotor2.getCurrent() >= data.workTime2) flagRelay2 = false;
if (data.mode3 == 0 and !calibration3 and tmrMotor3) flagRelay3 = true;
if (data.mode3 == 0 and !calibration3 and tmrMotor3.getCurrent() >= data.workTime3) flagRelay3 = false;
if (data.mode4 == 0 and !calibration4 and tmrMotor4) flagRelay4 = true;
if (data.mode4 == 0 and !calibration4 and tmrMotor4.getCurrent() >= data.workTime4) flagRelay4 = false;
}
void getCheckDelay() { // ПРОВЕРКА НАЛИЧИЯ ЗАДЕРЖКИ ВКЛЮЧЕНИЯ НАСОСОВ
if (checkDelay1) {
if (tmrDelay1) {tmrMotor1.start(); checkDelay1 = false;}
}
if (checkDelay2) {
if (tmrDelay2) {tmrMotor2.start(); checkDelay2 = false;}
}
if (checkDelay3) {
if (tmrDelay3) {tmrMotor3.start(); checkDelay3 = false;}
}
if (checkDelay4) {
if (tmrDelay4) {tmrMotor4.start(); checkDelay4 = false;}
}
}
void blinkDelayOn() { // Мигать буквой "З" если активна задержка
static uint32_t delayBlink;
if (millis() - delayBlink >= 1000) {
delayBlink = millis();
blink = !blink;
}
}