Контроллер для пивоварни (моя версия)
- Войдите на сайт для отправки комментариев
Пт, 06/03/2015 - 15:27
Знакомый решил заняться пивоварением и попросил написать для него контроллер для нагревательного бака.
Далее фото и код.





#include <Wire.h>
#include <PID_v1.h>
#include <TimeHelpers.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <DS1307.h>
#include <RTClib.h>
#include <EEPROM.h>
#define ONE_WIRE_BUS 10 // Шина датчика температуры
#define P_Temp 0 // Поле масива с данными температуры
#define P_Time 1 // Поле масива с данными времени
#define P_Alar 2 // Поле масива с данными сигнализации
#define TEN1 13 // Порт шины нагревательного элемента 1
#define TEN2 6 // Порт шины нагревательного элемента 2
#define BUTON_MENU 4 // Порт входа кнопки меню (притянут к +)
#define BUZZ 8 // Порт выхода на пьезоизлучатель
#define noTrem 150 // Задержка антидребезга
RTC_DS1307 rtc; // Инициализация Часов точного времени
OneWire ds(10); // Инициализация шины датчика измерения температуры
LiquidCrystal_I2C lcd(0x27, 20, 4); // Инициализация дисплея
double Setpoint = EEPROM.read(110); // Создание переменной устанавливаемой температуры (и передача данных из памяти)
double Input; // Создание переменной входящих данных в ПИД регулятор
double Output; // Создание переменной исходящих данных из ПИД регулятора
double consKp = 5, consKi = 50, consKd = 0.5; // Создание переменных констант ПИД регулятора (Обычный режим)(быстрый режим)
//double tochKp = 5, tochKi = 2, tochKd = 0.05; // Создание переменных констант ПИД регулятора (точный режим)(медленный режим)
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT); // Инициализация ПИД регулятора
DateTime now; // Создания объекта Часов точного времени
byte type_s; // Создание переменной типа датчика измерения температуры
byte data[12]; // Создание переменной данных датчика температуры
byte addr[8]; // Создание переменной адреса датчика температуры
float celsius; // Создание переменной значения измерений датчика температуры
int Moschnost; // Создание переменной мощности нагревательного элемента
int U_D = 5; // Создание переменной джойстика (движение вверх, вниз)
int L_R = 0; // Создание переменной джойстика (движение в лево, в право)
boolean Vhod_v_menu = 0; // Создание переменной флага входа в меню
int T_Upr = EEPROM.read(111); // Создание переменной указывающий тип управления (и передача данных из памяти)
int _HR = 0; // Создание переменной хранения значения часов
int _MI = 0; // Создание переменной хранения значения минут
int _SE = 0; // Создание переменной хранения значения секунд
int A_H = 0; // Создание переменной хранения значения часов при изменении времени
int A_M = 0; // Создание переменной хранения значения минут при изменении времени
boolean chg_Time = 0; // Создание переменной флага изменения значения времени
#define PunkMenu 20 // Указатель на количество пунктов меню
boolean Dreft0 = 0; // Создание переменной флага отрисовки 0 поля меню
boolean Dreft1 = 0; // Создание переменной флага отрисовки 1 поля меню
boolean Dreft2 = 0; // Создание переменной флага отрисовки 2 поля меню
boolean Dreft3 = 0; // Создание переменной флага отрисовки 3 поля меню
boolean Dreft4 = 0; // Создание переменной флага отрисовки 4 поля меню
boolean Dreft5 = 0; // Создание переменной флага отрисовки 5 поля меню
boolean Dreft_MAS_0 = 0; // Создание переменной флага отрисовки 6 поля меню
boolean Dreft_MAS_1 = 0; // Создание переменной флага отрисовки 7 поля меню
boolean Dreft_MAS_2 = 0; // Создание переменной флага отрисовки 8 поля меню
boolean Dreft_MAS_3 = 0; // Создание переменной флага отрисовки 9 поля меню
boolean Dreft_MAS_4 = 0; // Создание переменной флага отрисовки 10 поля меню
// Temperatura,Vremya,Alarm
int Pat[5][3] = {{26,1,0}, // Создание масива данных програмируемых периодов
{28,0,0}, // Создание масива данных програмируемых периодов
{30,0,0}, // Создание масива данных програмируемых периодов
{40,0,0}, // Создание масива данных програмируемых периодов
{50,0,0}}; // Создание масива данных програмируемых периодов
int P_Numb = 0; // Создание переменной определения пункта масива програмируемых периодов (общего назначения)
int R_Numb = 0; // Создание переменной определения пункта масива програмируемых периодов (отрисовка меню)
long NeoTime = 0; // Создание переменной хранения значения unix времени конца выполнения программы
boolean rasTempBol = 0; // Создание переменной флага необходимости расчета времени
long unixt; // Создание переменной хранения текущего unix времени
long Sec; // Создание переменной временивыполнения программы
int cur = 1; // Создание переменной указателя элемента моссива (отрисовка меню)
boolean StartTime = 0; // Создание переменной начала работы по заданному переоду (Р1 - Р5)
boolean Rabota = 1; // Создание переменной дополнительная переменная управления переключением периодов (Р1 - Р5)
boolean Alarm = 0; // Создание переменной значения сигнализации
boolean chgTemp = 0; // Создание переменной флага изменения значения температуры
boolean flag = 0; // Создание переменной флага управления пьезо излучателем
void setup()
{
rtc.begin();
lcd.init();
lcd.backlight();
pinMode(TEN1, OUTPUT);
pinMode(TEN2, OUTPUT);
pinMode(BUZZ, OUTPUT);
pinMode(BUTON_MENU, INPUT_PULLUP);
// DO_EVERY(250,{ });
if ( !ds.search(addr)) {
ds.reset_search();
delay(250);
return;
}
if (Setpoint > 90){Setpoint = 20;} // на случай если значение в памяти будет отсутствовать или быть неккоректным
if (T_Upr > 3 || T_Upr < 0){T_Upr = 0;} // на случай если значение в памяти будет отсутствовать или быть неккоректным
myPID.SetMode(AUTOMATIC);
lcd.clear();
tone(BUZZ, 3000, 500); // сигнал готовности устройства
}
void loop()
{
getTemp();
Input = celsius; // глупо... но пусть будет.
now = rtc.now();
Pause();
podderzhTemp();
Menu();
/*
double gap = abs(Setpoint-Input);
if (gap <= 5){myPID.SetTunings(consKp, consKi, consKd);}
else {myPID.SetTunings(tochKp, tochKi, tochKd);}
*/
myPID.Compute();
if (T_Upr == 0){analogWrite(TEN1, 0);analogWrite(TEN2, 0);}
if (T_Upr == 1){analogWrite(TEN1, 255);analogWrite(TEN2, 255);}
if (T_Upr == 2){analogWrite(TEN1, Output);analogWrite(TEN2, Output);}
if (T_Upr == 3){
Setpoint = Pat[P_Numb][P_Temp];
Alarm = Pat[P_Numb][P_Alar];
int tempIN = abs(Input);
int SetpIN = abs(Setpoint);
if (SetpIN == tempIN) {StartTime = 1;}
analogWrite(TEN1, Output);analogWrite(TEN2, Output);
}
_HR = now.hour();
_MI = now.minute();
_SE = now.second();
Moschnost = map(Output, 0, 255, 0, 100);
if (Vhod_v_menu == 0) {
lcd.setCursor(0, 0);lcd.print("T.ustC ");
lcd.print(Setpoint);
if (T_Upr == 3) {lcd.print(" PREF");}
if (T_Upr == 2) {lcd.print(" AUTO");}
if (T_Upr < 2) {lcd.print(" MANUAL");}
lcd.setCursor(0, 1);
lcd.print("T.zidC ");
lcd.print(Input);
if (T_Upr == 3) {
lcd.setCursor(15, 1);
lcd.print("PAT ");
lcd.print(P_Numb + 1);
}else{lcd.setCursor(13, 1);lcd.print("PAT OFF");}
lcd.setCursor(0, 2);lcd.print("P.ten% ");
if (Moschnost <= 100) {lcd.setCursor(7, 2);lcd.print(Moschnost); lcd.print(" ");}
if (Moschnost < 10) {lcd.setCursor(7, 2);lcd.print(Moschnost); lcd.print(" ");}
if (Output <= 255) {lcd.setCursor(14, 2);lcd.print(Output); lcd.print("");}
if (Output < 100) {lcd.setCursor(14, 2);lcd.print(Output); lcd.print(" ");}
if (Output < 10) {lcd.setCursor(14, 2);lcd.print(Output); lcd.print(" ");}
lcd.setCursor(0, 3);
if (T_Upr != 3) {lcd.print("Time: ");}
if (_HR < 10) {lcd.print("0");lcd.print(_HR);}else{lcd.print(_HR);}lcd.print(":");
if (_MI < 10) {lcd.print("0");lcd.print(_MI);}else{lcd.print(_MI);}lcd.print(":");
if (_SE < 10) {lcd.print("0");lcd.print(_SE);}else{lcd.print(_SE);}
if (T_Upr == 3) {
lcd.setCursor(10, 3);lcd.print("Count:");
if (StartTime != 0) {
if (Rabota == 1){
if (Sec < 10){ lcd.setCursor(16, 3); lcd.print(" ");lcd.print(Sec);}
if (Sec < 100 && Sec > 10){ lcd.setCursor(16, 3); lcd.print(" "); lcd.print(Sec);}
if (Sec < 1000 && Sec > 100){ lcd.setCursor(16, 3); lcd.print(" "); lcd.print(Sec);}
if (Sec < 10000 && Sec > 1000){lcd.setCursor(16, 3); lcd.print(Sec);}
}
}else{
if (Rabota == 1){
long Pr = Pat[P_Numb][P_Time] * 60;
if (Pr < 10){ lcd.setCursor(16, 3); lcd.print(" ");lcd.print(Pr);}
if (Pr < 100 && Pr > 10){ lcd.setCursor(16, 3); lcd.print(" "); lcd.print(Pr);}
if (Pr < 1000 && Pr > 100){ lcd.setCursor(16, 3); lcd.print(" "); lcd.print(Pr);}
if (Pr < 10000 && Pr > 1000){lcd.setCursor(16, 3); lcd.print(Pr);}
}
}
}else{lcd.setCursor(15, 3);lcd.print(" ");}
}
}
void Pause(){
getPressedButton();
if (analogRead(0) > 1000) {Rabota = 1;Alarm = 0;} // Reset Pause
if (Rabota == 0) {
DO_EVERY(1000,{
if (flag == 0) {lcd.setCursor(13, 1); lcd.print("*"); tone(BUZZ, 1000); flag = 1;}
else {lcd.setCursor(13, 1); lcd.print(" "); noTone(BUZZ); flag = 0;}
});
}else{if (T_Upr == 3){lcd.setCursor(13, 1); lcd.print(" "); noTone(BUZZ); flag = 0;}}
}
void podderzhTemp(){
if (StartTime == 1){
rasTemp();
unixt = now.unixtime();
Sec = NeoTime - unixt;
if (Rabota = 1){
if (Sec <= 0){
if (Alarm == 1) {
Rabota = 0;
}else{
if (P_Numb <= 4){
rasTempBol = 0;
StartTime = 0;
P_Numb++;
if (Pat[P_Numb][P_Time] == 0){StopRab();}
}else{StopRab();}
}
}
}
}
}
void StopRab(){
Setpoint = 10;
T_Upr = 0;
P_Numb = 0;
StartTime = 0;
Rabota = 1;
Alarm = 0;
U_D = 5;
L_R = 0;
lcd.setCursor(15, 1);lcd.print(" STOP ");
lcd.setCursor(13, 1);lcd.print("PAT OFF");
tone(BUZZ, 400, 100); // сигнал завершения работы всех программ
tone(BUZZ, 500, 200); // сигнал завершения работы всех программ
tone(BUZZ, 700, 300); // сигнал завершения работы всех программ
tone(BUZZ, 1000, 200); // сигнал завершения работы всех программ
tone(BUZZ, 6000, 100); // сигнал завершения работы всех программ
}
void rasTemp(){
if (rasTempBol == 0){NeoTime = (Pat[P_Numb][P_Time] * 60) + now.unixtime();rasTempBol = 1;}
}
void Menu() {
getPressedButton();
if (Vhod_v_menu == 0) { // выключатель освещения :)
if (analogRead(1) < 100) {lcd.backlight();}
if (analogRead(1) > 1000) {lcd.noBacklight();}
}
if (digitalRead(BUTON_MENU) == 0) {
U_D = 5;
L_R = 0;
lcd.backlight();
if (Vhod_v_menu == 0) {
Vhod_v_menu = 1;
ClearNol();
lcd.print("0. Setup");
lcd.setCursor(0, 1);lcd.print(" left or right");
Dreft0 = 1;
delay(100);
} else {
lcd.clear();
lcd.setCursor(8, 1);lcd.print("EXIT");
chg_Time = 0;
L_R = 0;
Vhod_v_menu = 0;
if (EEPROM.read(110) != Setpoint) { // Сохранение значения температуры
if (T_Upr != 3 && chgTemp == 1){
EEPROM.write(110, Setpoint);
lcd.setCursor(8, 1);
lcd.print("SAVE");
}
}
if (EEPROM.read(111) != T_Upr) { // Сохранение значения режима работы
if (T_Upr != 3){
EEPROM.write(111, T_Upr);
lcd.setCursor(8, 1);
lcd.print("SAVE");
}
}
delay(1000);
lcd.clear();
}
}
//----------------------------------------------------------------------------------
if (Vhod_v_menu == 1) {
if (L_R == 0) {
if (Dreft0 == 0) {
ClearNol();
lcd.print("0. Setup");
lcd.setCursor(0, 1);lcd.print(" left or right");
Dreft0 = 1;}} else {Dreft0 = 0;}
//-------------
if (L_R == 1) {
if (Dreft1 == 0) {
chgTemp = 0;
ClearNol();
lcd.print("1. Setup Temp");
lcd.setCursor(0, 2);lcd.print(Setpoint);
Dreft1 = 1;}} else {Dreft1 = 0;}
//-------------
if (L_R == 2) {
if (Dreft2 == 0) {
ClearNol();
lcd.print("2. Setup Rele ON-OFF");
lcd.setCursor(0, 2);
if (T_Upr == 0) {lcd.print("1-4 OFF ");}
if (T_Upr == 1) {lcd.print("2-4 ON ");}
if (T_Upr == 2) {lcd.print("3-4 AUTO ");}
if (T_Upr == 3) {lcd.print("4-4 PREF ");}
Dreft2 = 1;}} else {Dreft2 = 0;}
//-------------
if (L_R == 3) {
if (Dreft3 == 0) {
A_H = now.hour();
ClearNol();
lcd.print("3. Setup Time hour");
lcd.setCursor(0, 1);
now = rtc.now();
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute());
lcd.print(":");
lcd.print(now.second());
lcd.setCursor(0, 2);
lcd.print(A_H);
lcd.print(" hour");
Dreft3 = 1;}} else {Dreft3 = 0;}
//-------------
if (L_R == 4) {
if (Dreft4 == 0) {
A_M = now.minute();
ClearNol();
lcd.print("4. Setup Time minute");
lcd.setCursor(0, 1);
now = rtc.now();
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute());
lcd.print(":");
lcd.print(now.second());
lcd.setCursor(0, 2);
lcd.print(A_M);
lcd.print(" minute");
Dreft4 = 1;}} else {Dreft4 = 0;}
//-------------
if (L_R == 5) {
if (Dreft5 == 0) {
ClearNol();
lcd.print("5. Setup SET Time");
lcd.setCursor(0, 1);
now = rtc.now();
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute());
lcd.print(":");
lcd.print(now.second());
lcd.print(" - OLD");
lcd.setCursor(0, 2);
lcd.print(A_H);
lcd.print(":");
lcd.print(A_M);
lcd.print(":00");
lcd.print(" - NEW");
lcd.setCursor(0, 3);
if (chg_Time == 1){lcd.print("Press UP to SET");}else{lcd.print("Time not changed");}
Dreft5 = 1;}} else {Dreft5 = 0;}
//-------------
if (L_R == 6 || L_R == 11 || L_R == 16) {
if (Dreft_MAS_0 == 0) {
if (L_R == 6) {Print_Pat_Screan_Temp();}
if (L_R == 11) {Print_Pat_Screan_Time();}
if (L_R == 16) {Print_Pat_Screan_Alarm();}
lcd.setCursor(1, 3);lcd.print("^^");
Dreft_MAS_0 = 1;}} else {Dreft_MAS_0 = 0;}
if (L_R == 7 || L_R == 12 || L_R == 17) {
if (Dreft_MAS_1 == 0) {
if (L_R == 7) {Print_Pat_Screan_Temp();}
if (L_R == 12) {Print_Pat_Screan_Time();}
if (L_R == 17) {Print_Pat_Screan_Alarm();}
lcd.setCursor(5, 3);lcd.print("^^");
Dreft_MAS_1 = 1;}} else {Dreft_MAS_1 = 0;}
if (L_R == 8 || L_R == 13 || L_R == 18) {
if (Dreft_MAS_2 == 0) {
if (L_R == 8) {Print_Pat_Screan_Temp();}
if (L_R == 13) {Print_Pat_Screan_Time();}
if (L_R == 18) {Print_Pat_Screan_Alarm();}
lcd.setCursor(9, 3);lcd.print("^^");
Dreft_MAS_2 = 1;}} else {Dreft_MAS_2 = 0;}
if (L_R == 9 || L_R == 14 || L_R == 19) {
if (Dreft_MAS_3 == 0) {
if (L_R == 9) {Print_Pat_Screan_Temp();}
if (L_R == 14) {Print_Pat_Screan_Time();}
if (L_R == 19) {Print_Pat_Screan_Alarm();}
lcd.setCursor(13, 3);lcd.print("^^");
Dreft_MAS_3 = 1;}} else {Dreft_MAS_3 = 0;}
if (L_R == 10 || L_R == 15 || L_R == 20) {
if (Dreft_MAS_4 == 0) {
if (L_R == 10) {Print_Pat_Screan_Temp();}
if (L_R == 15) {Print_Pat_Screan_Time();}
if (L_R == 20) {Print_Pat_Screan_Alarm();}
lcd.setCursor(17, 3);lcd.print("^^");
Dreft_MAS_4 = 1;}} else {Dreft_MAS_4 = 0;}
//##################################################################
if (U_D > 5) {
//-------------
if (L_R == 1) {
Setpoint = Setpoint + 0.5;
chgTemp = 1;
lcd.setCursor(0, 2);
lcd.print(Setpoint);
U_D = 5;
}
//-------------
if (L_R == 2) {
if (T_Upr < 4) {T_Upr = T_Upr + 1;}
lcd.setCursor(0, 2);
if (T_Upr == 0) {lcd.print("1-4 OFF ");}
if (T_Upr == 1) {lcd.print("2-4 ON ");}
if (T_Upr == 2) {lcd.print("3-4 AUTO ");}
if (T_Upr == 3) {lcd.print("4-4 PREF ");}
U_D = 5;
}
//-------------
if (L_R == 3) {
A_H = A_H + 1;
chg_Time = 1;
if (A_H > 23) {A_H = 23;}
if (A_H < 0) {A_H = 0;}
lcd.setCursor(0, 2);
lcd.print(A_H);
lcd.print(" hour");
U_D = 5;
}
//-------------
if (L_R == 4) {
A_M = A_M + 1;
chg_Time = 1;
if (A_M > 59) {A_M = 59;}
if (A_M < 0) {A_M = 0;}
lcd.setCursor(0, 2);
lcd.print(A_M);
lcd.print(" minute");
U_D = 5;
}
//-------------
if (L_R == 5) {
if (chg_Time == 1){
rtc.adjust(DateTime(2015, 2, 27, A_H, A_M, 0));
chg_Time = 0;
lcd.setCursor(0, 0);
lcd.clear();
lcd.print("6. Setup SET Time");
lcd.setCursor(0, 1);
now = rtc.now();
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute());
lcd.print(":");
lcd.print(now.second());
lcd.setCursor(0, 2);
lcd.print(A_H);
lcd.print(":");
lcd.print(A_M);
lcd.print(":00");
lcd.setCursor(0, 3);
lcd.print("Save - ok");
}
U_D = 5;
}
//-------------
if (L_R == 6 || L_R == 11 || L_R == 16) {
if (L_R == 6) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 11) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 16) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(1, 3);lcd.print("^^");
U_D = 5;
}
if (L_R == 7 || L_R == 12 || L_R == 17) {
if (L_R == 7) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 12) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 17) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(5, 3);lcd.print("^^");
U_D = 5;
}
if (L_R == 8 || L_R == 13 || L_R == 18) {
if (L_R == 8) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 13) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 18) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(9, 3);lcd.print("^^");
U_D = 5;
}
if (L_R == 9 || L_R == 14 || L_R == 19) {
if (L_R == 9) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 14) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 19) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(13, 3);lcd.print("^^");
U_D = 5;
}
if (L_R == 10 || L_R == 15 || L_R == 20) {
if (L_R == 10) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 15) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 20) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(17, 3);lcd.print("^^");
U_D = 5;
}
//----------------------------------------------------------------------------------
} else if (U_D < 5) {
if (L_R == 1) {
Setpoint = Setpoint - 0.5;
chgTemp = 1;
lcd.setCursor(0, 2);
lcd.print(Setpoint);
U_D = 5;
}
//-------------
if (L_R == 2) {
if (T_Upr > 0) {T_Upr = T_Upr - 1;}
lcd.setCursor(0, 2);
if (T_Upr == 0) {lcd.print("1-4 OFF ");}
if (T_Upr == 1) {lcd.print("2-4 ON ");}
if (T_Upr == 2) {lcd.print("3-4 AUTO ");}
if (T_Upr == 3) {lcd.print("4-4 PREF ");}
U_D = 5;
}
//-------------
if (L_R == 3) {
A_H = A_H - 1;
chg_Time = 1;
if (A_H > 23) {A_H = 23;}
if (A_H < 0) {A_H = 0;}
lcd.setCursor(0, 2);
lcd.print(A_H);
lcd.print(" hour");
U_D = 5;
}
//-------------
if (L_R == 4) {
A_M = A_M - 1;
chg_Time = 1;
if (A_M > 59) {A_M = 59;}
if (A_M < 0) {A_M = 0;}
lcd.setCursor(0, 2);
lcd.print(A_M);
lcd.print(" minute");
U_D = 5;
}
//-------------
if (L_R == 5) {
if (chg_Time == 1){
A_H = now.hour();
A_M = now.minute();
chg_Time = 0;
lcd.setCursor(0, 0);
lcd.clear();
lcd.print("6. Setup SET Time");
lcd.setCursor(0, 1);
now = rtc.now();
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute());
lcd.print(":");
lcd.print(now.second());
lcd.setCursor(0, 2);
lcd.print(A_H);
lcd.print(":");
lcd.print(A_M);
lcd.print(":00");
lcd.setCursor(0, 3);
lcd.print("Changed - Cancel");
}
U_D = 5;
}
//-------------
if (L_R == 6 || L_R == 11 || L_R == 16) {
if (L_R == 6) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 11) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 16) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(1, 3);lcd.print("^^");
U_D = 5;
}
if (L_R == 7 || L_R == 12 || L_R == 17) {
if (L_R == 7) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 12) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 17) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(5, 3);lcd.print("^^");
U_D = 5;
}
if (L_R == 8 || L_R == 13 || L_R == 18) {
if (L_R == 8) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 13) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 18) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(9, 3);lcd.print("^^");
U_D = 5;
}
if (L_R == 9 || L_R == 14 || L_R == 19) {
if (L_R == 9) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 14) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 19) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(13, 3);lcd.print("^^");
U_D = 5;
}
if (L_R == 10 || L_R == 15 || L_R == 20) {
if (L_R == 10) {
CHG_P_Temp();
Print_Pat_Screan_Temp();
}
if (L_R == 15) {
CHG_P_Time();
Print_Pat_Screan_Time();
}
if (L_R == 20) {
CHG_P_Alar();
Print_Pat_Screan_Alarm();
}
lcd.setCursor(17, 3);lcd.print("^^");
U_D = 5;
}
//-------------
}
}
}
void CHG_P_Temp(){
if (U_D > 5) {
if (Dreft_MAS_0 == 1) {if (Pat[0][P_Temp] < 100) {Pat[0][P_Temp] += 1;}}
if (Dreft_MAS_1 == 1) {if (Pat[1][P_Temp] < 100) {Pat[1][P_Temp] += 1;}}
if (Dreft_MAS_2 == 1) {if (Pat[2][P_Temp] < 100) {Pat[2][P_Temp] += 1;}}
if (Dreft_MAS_3 == 1) {if (Pat[3][P_Temp] < 100) {Pat[3][P_Temp] += 1;}}
if (Dreft_MAS_4 == 1) {if (Pat[4][P_Temp] < 100) {Pat[4][P_Temp] += 1;}}}
else{
if (Dreft_MAS_0 == 1) {if (Pat[0][P_Temp] > 0) {Pat[0][P_Temp] -= 1;}}
if (Dreft_MAS_1 == 1) {if (Pat[1][P_Temp] > 0) {Pat[1][P_Temp] -= 1;}}
if (Dreft_MAS_2 == 1) {if (Pat[2][P_Temp] > 0) {Pat[2][P_Temp] -= 1;}}
if (Dreft_MAS_3 == 1) {if (Pat[3][P_Temp] > 0) {Pat[3][P_Temp] -= 1;}}
if (Dreft_MAS_4 == 1) {if (Pat[4][P_Temp] > 0) {Pat[4][P_Temp] -= 1;}}}
}
void CHG_P_Time(){
if (U_D > 5) {
if (Dreft_MAS_0 == 1) {if (Pat[0][P_Time] < 32000) {Pat[0][P_Time] += 1;}}
if (Dreft_MAS_1 == 1) {if (Pat[1][P_Time] < 32000) {Pat[1][P_Time] += 1;}}
if (Dreft_MAS_2 == 1) {if (Pat[2][P_Time] < 32000) {Pat[2][P_Time] += 1;}}
if (Dreft_MAS_3 == 1) {if (Pat[3][P_Time] < 32000) {Pat[3][P_Time] += 1;}}
if (Dreft_MAS_4 == 1) {if (Pat[4][P_Time] < 32000) {Pat[4][P_Time] += 1;}}}
else{
if (Dreft_MAS_0 == 1) {if (Pat[0][P_Time] > 0) {Pat[0][P_Time] -= 1;}}
if (Dreft_MAS_1 == 1) {if (Pat[1][P_Time] > 0) {Pat[1][P_Time] -= 1;}}
if (Dreft_MAS_2 == 1) {if (Pat[2][P_Time] > 0) {Pat[2][P_Time] -= 1;}}
if (Dreft_MAS_3 == 1) {if (Pat[3][P_Time] > 0) {Pat[3][P_Time] -= 1;}}
if (Dreft_MAS_4 == 1) {if (Pat[4][P_Time] > 0) {Pat[4][P_Time] -= 1;}}}
}
void CHG_P_Alar(){
if (U_D > 5) {
if (Dreft_MAS_0 == 1) {Pat[0][P_Alar] = 1;}
if (Dreft_MAS_1 == 1) {Pat[1][P_Alar] = 1;}
if (Dreft_MAS_2 == 1) {Pat[2][P_Alar] = 1;}
if (Dreft_MAS_3 == 1) {Pat[3][P_Alar] = 1;}
if (Dreft_MAS_4 == 1) {Pat[4][P_Alar] = 1;}}
else{
if (Dreft_MAS_0 == 1) {Pat[0][P_Alar] = 0;}
if (Dreft_MAS_1 == 1) {Pat[1][P_Alar] = 0;}
if (Dreft_MAS_2 == 1) {Pat[2][P_Alar] = 0;}
if (Dreft_MAS_3 == 1) {Pat[3][P_Alar] = 0;}
if (Dreft_MAS_4 == 1) {Pat[4][P_Alar] = 0;}}
}
void Print_Pat_Screan_Temp(){
ClearNol();
cur = 1;
lcd.print("6. Setup PAT Temp");
for (int i = 1; i <= 5; i++) {
if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}
cur += 4;
}
cur = 1;
for (int i = 0; i < 5; i++) {
R_Numb = i;
if (cur == 1) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);}
cur += 4;
lcd.print(Pat[R_Numb][P_Temp]);
}
}
void Print_Pat_Screan_Time(){
ClearNol();
cur = 1;
lcd.print("7. Setup PAT Time");
for (int i = 1; i <= 5; i++) {
if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}
cur += 4;
}
cur = 1;
for (int i = 0; i < 5; i++) {
R_Numb = i;
if (cur == 1) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);}
cur += 4;
if (Pat[R_Numb][P_Time] < 10){lcd.print(Pat[R_Numb][P_Time]);lcd.print(" ");}else{lcd.print(Pat[R_Numb][P_Time]);}
}
}
void Print_Pat_Screan_Alarm(){
ClearNol();
cur = 1;
lcd.print("8. Setup PAT Alarm");
for (int i = 1; i <= 5; i++) {
if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}
cur += 4;
}
cur = 1;
for (int i = 0; i < 5; i++) {
R_Numb = i;
if (cur == 1) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);}
cur += 4;
if (Pat[R_Numb][P_Alar] == 0){lcd.print("OF");}else{lcd.print("ON");}
}
}
void ClearNol(){
lcd.clear();
lcd.setCursor(0, 0);
}
void getPressedButton() {
DO_EVERY(noTrem,{if (analogRead(0) < 100) {L_R--;}});
DO_EVERY(noTrem,{if (analogRead(0) > 1000){L_R++;}});
DO_EVERY(noTrem,{if (analogRead(1) < 100) {U_D++;}});
DO_EVERY(noTrem,{if (analogRead(1) > 1000){U_D--;}});
if (L_R < 0){L_R = PunkMenu;}
if (L_R > PunkMenu){L_R = 0;}
}
void getTemp() {
ds.reset();
ds.select(addr);
ds.write(0x44, 1);
ds.reset();
ds.select(addr);
ds.write(0xBE);
for ( int i = 0; i < 9; i++) {
data[i] = ds.read();
}
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3;
if (data[7] == 0x10) {
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw & ~7;
else if (cfg == 0x20) raw = raw & ~3;
else if (cfg == 0x40) raw = raw & ~1;
}
celsius = (float)raw / 16.0;
return;
}
Следующяя более оптимизированная версия прошивки
переработанно меню, добавленно управление рециркуляционным насосом, добавленны дополнительные 5 программ (P1 - P9), добавленна возможность изменять интегральный коэфициент ПИД регулятора.
Система протестированна на чайнике, по результатам тестов был удален НЧ фильтр между SSR и UNL.
#include <Wire.h> #include <PID_v1.h> #include <TimeHelpers.h> #include <OneWire.h> #include <LiquidCrystal_I2C.h> #include <DS1307.h> #include <RTClib.h> #include <EEPROM.h> #define ONE_WIRE_BUS 10 // Шина датчика температуры #define P_Temp 0 // Поле масива с данными температуры #define P_Time 1 // Поле масива с данными времени #define P_Alar 2 // Поле масива с данными сигнализации #define TEN1 13 // Порт шины нагревательного элемента 1 #define TEN2 6 // Порт шины нагревательного элемента 2 #define NASOS 2 // Порт шины рециркуляционного насоса #define BUTON_MENU 4 // Порт входа кнопки меню (притянут к +) #define BUZZ 8 // Порт выхода на пьезоизлучатель #define noTrem 150 // Задержка антидребезга RTC_DS1307 rtc; // Инициализация Часов точного времени OneWire ds(10); // Инициализация шины датчика измерения температуры LiquidCrystal_I2C lcd(0x27, 20, 4); // Инициализация дисплея double Setpoint = EEPROM.read(110); // Создание переменной устанавливаемой температуры (и передача данных из памяти) double Input; // Создание переменной входящих данных в ПИД регулятор double Output; // Создание переменной исходящих данных из ПИД регулятора double consKp = 5; // Создание переменных констант ПИД регулятора (Обычный режим)(быстрый режим) double consKi = EEPROM.read(112); // Создание переменных констант ПИД регулятора (Обычный режим)(быстрый режим) double consKd = 1; // Создание переменных констант ПИД регулятора (Обычный режим)(быстрый режим) double KP = 0; // Создание переменных констант ПИД регулятора double KI = 0; // Создание переменных констант ПИД регулятора double KD = 0; // Создание переменных констант ПИД регулятора //double tochKp = 5, tochKi = 2, tochKd = 0.05; // Создание переменных констант ПИД регулятора (точный режим)(медленный режим) PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT); // Инициализация ПИД регулятора DateTime now; // Создания объекта Часов точного времени byte type_s; // Создание переменной типа датчика измерения температуры byte data[12]; // Создание переменной данных датчика температуры byte addr[8]; // Создание переменной адреса датчика температуры float celsius; // Создание переменной значения измерений датчика температуры int Moschnost; // Создание переменной мощности нагревательного элемента int U_D = 5; // Создание переменной джойстика (движение вверх, вниз) int L_R = 0; // Создание переменной джойстика (движение в лево, в право) boolean Vhod_v_menu = 0; // Создание переменной флага входа в меню int T_Upr = 0; // EEPROM.read(111); // Создание переменной указывающий тип управления (и передача данных из памяти) int _HR = 0; // Создание переменной хранения значения часов int _MI = 0; // Создание переменной хранения значения минут int _SE = 0; // Создание переменной хранения значения секунд int A_H = 0; // Создание переменной хранения значения часов при изменении времени int A_M = 0; // Создание переменной хранения значения минут при изменении времени boolean chg_Time = 0; // Создание переменной флага изменения значения времени #define PunkMenu 35 // Указатель на количество пунктов меню boolean Dreft0 = 0; // Создание переменной флага отрисовки 0 поля меню boolean Dreft1 = 0; // Создание переменной флага отрисовки 1 поля меню boolean Dreft2 = 0; // Создание переменной флага отрисовки 2 поля меню boolean Dreft3 = 0; // Создание переменной флага отрисовки 3 поля меню boolean Dreft4 = 0; // Создание переменной флага отрисовки 4 поля меню boolean Dreft5 = 0; // Создание переменной флага отрисовки 5 поля меню boolean Dreft_MAS_0 = 0; // Создание переменной флага отрисовки 6 поля меню boolean Dreft_MAS_1 = 0; // Создание переменной флага отрисовки 7 поля меню boolean Dreft_MAS_2 = 0; // Создание переменной флага отрисовки 8 поля меню boolean Dreft_MAS_3 = 0; // Создание переменной флага отрисовки 9 поля меню boolean Dreft_MAS_4 = 0; // Создание переменной флага отрисовки 10 поля меню boolean Dreft_MAS_5 = 0; // Создание переменной флага отрисовки 11 поля меню boolean Dreft_MAS_6 = 0; // Создание переменной флага отрисовки 12 поля меню boolean Dreft_MAS_7 = 0; // Создание переменной флага отрисовки 13 поля меню boolean Dreft_MAS_8 = 0; // Создание переменной флага отрисовки 14 поля меню boolean Dreft_MAS_9 = 0; // Создание переменной флага отрисовки 15 поля меню // Temperatura,Vremya,Alarm int Pat[10][3] = {{30,0,0}, // Создание масива данных програмируемых периодов 0 {40,0,0}, // Создание масива данных програмируемых периодов 1 {50,0,0}, // Создание масива данных програмируемых периодов 2 {60,0,0}, // Создание масива данных програмируемых периодов 3 {70,0,0}, // Создание масива данных програмируемых периодов 4 {95,0,0}, // Создание масива данных програмируемых периодов 5 {95,0,0}, // Создание масива данных програмируемых периодов 6 {95,0,0}, // Создание масива данных програмируемых периодов 7 {95,0,0}, // Создание масива данных програмируемых периодов 8 {95,0,0}}; // Создание масива данных програмируемых периодов 9 int P_Numb = 0; // Создание переменной определения пункта масива програмируемых периодов (общего назначения) int R_Numb = 0; // Создание переменной определения пункта масива програмируемых периодов (отрисовка меню) long NeoTime = 0; // Создание переменной хранения значения unix времени конца выполнения программы boolean rasTempBol = 0; // Создание переменной флага необходимости расчета времени long unixt; // Создание переменной хранения текущего unix времени long Sec; // Создание переменной временивыполнения программы int cur = 1; // Создание переменной указателя элемента моссива (отрисовка меню) boolean StartTime = 0; // Создание переменной начала работы по заданному переоду (Р1 - Р5) boolean Rabota = 1; // Создание переменной дополнительная переменная управления переключением периодов (Р1 - Р5) boolean Alarm = 0; // Создание переменной значения сигнализации boolean chgTemp = 0; // Создание переменной флага изменения значения температуры boolean flag = 0; // Создание переменной флага управления пьезо излучателем int Povtor_Promyvka = 5; // Колличество циклов int tekPovtor_Promyvka = 0; // Текущее количество циклов проверки int EndOFNasos = 0; // отключение насоса byte Gradus[8] = // Создание значка градуса { B01000, // Создание значка градуса B10100, // Создание значка градуса B01000, // Создание значка градуса B00000, // Создание значка градуса B00000, // Создание значка градуса B00000, // Создание значка градуса B00000, // Создание значка градуса B00000}; // Создание значка градуса void setup() { KP = myPID.GetKp(); KI = myPID.GetKi(); KD = myPID.GetKd(); lcd.createChar(0, Gradus); rtc.begin(); lcd.init(); lcd.backlight(); pinMode(TEN1, OUTPUT); pinMode(TEN2, OUTPUT); pinMode(BUZZ, OUTPUT); pinMode(NASOS, OUTPUT); pinMode(BUTON_MENU, INPUT_PULLUP); digitalWrite(NASOS, LOW); analogWrite(TEN1, 0); analogWrite(TEN2, 0); // DO_EVERY(250,{ }); if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; } if (Setpoint > 90){Setpoint = 20;} // на случай если значение в памяти будет отсутствовать или быть неккоректным if (consKi < 1 || consKi > 100){consKi = 50;} // на случай если значение в памяти будет отсутствовать или быть неккоректным if (T_Upr > 3 || T_Upr < 0){T_Upr = 0;} // на случай если значение в памяти будет отсутствовать или быть неккоректным myPID.SetMode(AUTOMATIC); lcd.clear(); tone(BUZZ, 3000, 500); // сигнал готовности устройства } void loop() { Prokachka(); getTemp(); Input = celsius; // глупо... но пусть будет. now = rtc.now(); Pause(); podderzhTemp(); Menu(); myPID.Compute(); if (T_Upr == 0){analogWrite(TEN1, 0);analogWrite(TEN2, 0);} if (T_Upr == 1){analogWrite(TEN1, 255);analogWrite(TEN2, 255);} if (T_Upr == 2){analogWrite(TEN1, Output);analogWrite(TEN2, Output);} if (T_Upr == 3){ Setpoint = Pat[P_Numb][P_Temp]; Alarm = Pat[P_Numb][P_Alar]; int tempIN = abs(Input); int SetpIN = abs(Setpoint); if (SetpIN == tempIN) {StartTime = 1;} analogWrite(TEN1, Output);analogWrite(TEN2, Output); } _HR = now.hour(); _MI = now.minute(); _SE = now.second(); Moschnost = map(Output, 0, 255, 0, 100); if (Vhod_v_menu == 0) { lcd.setCursor(0, 0);lcd.print("T.ust "); lcd.print(Setpoint); lcd.print('\0'); if (T_Upr == 3) {lcd.print(" PREF");} if (T_Upr == 2) {lcd.print(" AUTO");} if (T_Upr < 2) {lcd.print(" MANUAL");} lcd.setCursor(0, 1); lcd.print("T.zid "); lcd.print(Input); lcd.print('\0'); if (T_Upr == 3) { lcd.setCursor(15, 1); lcd.print("PAT "); lcd.print(P_Numb); }else{lcd.setCursor(13, 1);lcd.print("PAT OFF");} lcd.setCursor(0, 2);lcd.print("P.ten "); if (Moschnost <= 100) {lcd.setCursor(6, 2);lcd.print(Moschnost); lcd.print("% ");} if (Moschnost < 10) {lcd.setCursor(6, 2);lcd.print(Moschnost); lcd.print("% ");} if (Output <= 255) {lcd.setCursor(14, 2);lcd.print(Output); lcd.print("");} if (Output < 100) {lcd.setCursor(14, 2);lcd.print(Output); lcd.print(" ");} if (Output < 10) {lcd.setCursor(14, 2);lcd.print(Output); lcd.print(" ");} lcd.setCursor(0, 3); if (T_Upr != 3) {lcd.print("Time: ");} if (_HR < 10) {lcd.print("0");lcd.print(_HR);}else{lcd.print(_HR);}lcd.print(":"); if (_MI < 10) {lcd.print("0");lcd.print(_MI);}else{lcd.print(_MI);}lcd.print(":"); if (_SE < 10) {lcd.print("0");lcd.print(_SE);}else{lcd.print(_SE);} if (T_Upr == 3) { lcd.setCursor(10, 3);lcd.print("Count:"); if (StartTime != 0) { if (Rabota == 1){ if (Sec < 10){ lcd.setCursor(16, 3); lcd.print(" ");lcd.print(Sec);} if (Sec < 100 && Sec > 10){ lcd.setCursor(16, 3); lcd.print(" "); lcd.print(Sec);} if (Sec < 1000 && Sec > 100){ lcd.setCursor(16, 3); lcd.print(" "); lcd.print(Sec);} if (Sec < 10000 && Sec > 1000){lcd.setCursor(16, 3); lcd.print(Sec);} } }else{ if (Rabota == 1){ long Pr = Pat[P_Numb][P_Time] * 60; if (Pr < 10){ lcd.setCursor(16, 3); lcd.print(" ");lcd.print(Pr);} if (Pr < 100 && Pr > 10){ lcd.setCursor(16, 3); lcd.print(" "); lcd.print(Pr);} if (Pr < 1000 && Pr > 100){ lcd.setCursor(16, 3); lcd.print(" "); lcd.print(Pr);} if (Pr < 10000 && Pr > 1000){lcd.setCursor(16, 3); lcd.print(Pr);} } } }else{lcd.setCursor(15, 3);lcd.print(" ");} } } void Pause(){ getPressedButton(); if (analogRead(0) > 1000) {Rabota = 1;Alarm = 0;} // Reset Pause if (Rabota == 0) { DO_EVERY(1000,{ if (flag == 0) {lcd.setCursor(13, 1); lcd.print("*"); tone(BUZZ, 1500); flag = 1;} else {lcd.setCursor(13, 1); lcd.print(" "); noTone(BUZZ); flag = 0;} }); }else{if (T_Upr == 3){lcd.setCursor(13, 1); lcd.print(" "); noTone(BUZZ); flag = 0;}} } void podderzhTemp(){ if (StartTime == 1){ rasTemp(); unixt = now.unixtime(); Sec = NeoTime - unixt; if (Rabota = 1){ if (Sec <= 0){ if (Alarm == 1) { Rabota = 0; }else{ if (P_Numb <= 9){ rasTempBol = 0; StartTime = 0; P_Numb++; if (Pat[P_Numb][P_Time] == 0){StopRab();} }else{StopRab();} } } } } } void StopRab(){ Setpoint = 10; T_Upr = 0; P_Numb = 0; StartTime = 0; chg_Time = 0; Rabota = 1; Alarm = 0; U_D = 5; L_R = 0; tekPovtor_Promyvka = 0; lcd.setCursor(15, 1);lcd.print(" STOP "); lcd.setCursor(13, 1);lcd.print("PAT OFF"); tone(BUZZ, 400, 5000); // сигнал завершения работы всех программ digitalWrite(NASOS,HIGH); // Включение насоса на 5 минут после завершения программ EndOFNasos = 1; // Флаг включение насоса на 5 минут после завершения программ } void rasTemp(){ if (rasTempBol == 0){NeoTime = (Pat[P_Numb][P_Time] * 60) + now.unixtime();rasTempBol = 1;} } void Menu() { getPressedButton(); if (Vhod_v_menu == 0) { // выключатель освещения :) if (analogRead(1) < 100) {lcd.backlight();} if (analogRead(1) > 1000) {lcd.noBacklight();} } if (digitalRead(BUTON_MENU) == 0) { U_D = 5; L_R = 0; chg_Time = 0; EndOFNasos = 0; lcd.backlight(); if (Vhod_v_menu == 0) { Vhod_v_menu = 1; ClearNol(); lcd.print(" Setup"); lcd.setCursor(0, 1);lcd.print(" left or right"); Dreft0 = 1; delay(100); } else { lcd.clear(); lcd.setCursor(8, 1);lcd.print("EXIT"); chg_Time = 0; L_R = 0; Vhod_v_menu = 0; if (EEPROM.read(110) != Setpoint) { // Сохранение значения температуры if (T_Upr == 2 && chgTemp == 1){ EEPROM.write(110, Setpoint); lcd.setCursor(5, 1); lcd.print("SAVE Temp"); delay(600); } } if (EEPROM.read(111) != T_Upr) { // Сохранение значения режима работы if (T_Upr != 3){ EEPROM.write(111, T_Upr); lcd.setCursor(5, 1); lcd.print("SAVE Mode"); delay(600); } } if (EEPROM.read(112) != KI) { // Сохранение значения режима KI PID регулятора EEPROM.write(112, KI); lcd.setCursor(5, 1); lcd.print("SAVE PID "); myPID.SetTunings(consKp, KI, consKd); delay(600); } lcd.clear(); } } //---------------------------------------------------------------------------------- if (Vhod_v_menu == 1) { if (L_R == 0) { if (Dreft0 == 0) { ClearNol(); lcd.print(" Setup"); lcd.setCursor(0, 1);lcd.print(" left or right"); Dreft0 = 1;}} else {Dreft0 = 0;} //------------- if (L_R == 1) { if (Dreft1 == 0) { ReleMode(); lcd.setCursor(0, 3);lcd.print(" ^^^^ "); Dreft1 = 1;}} else {Dreft1 = 0;} //------------- if (L_R == 2) { if (Dreft2 == 0) { ReleMode(); lcd.setCursor(0, 3);lcd.print(" ^^^^^"); Dreft2 = 1;}} else {Dreft2 = 0;} //------------- if (L_R == 3) { if (Dreft3 == 0) { A_H = now.hour(); A_M = now.minute(); ClearNol(); PrintTime(); lcd.setCursor(0, 3);lcd.print("^^"); Dreft3 = 1;}} else {Dreft3 = 0; if (chg_Time == 1){rtc.adjust(DateTime(2015, 2, 27, A_H, A_M, 0));}} //------------- if (L_R == 4) { if (Dreft4 == 0) { A_H = now.hour(); A_M = now.minute(); ClearNol(); PrintTime(); lcd.setCursor(0, 3);lcd.print(" ^^"); Dreft4 = 1;}} else {Dreft4 = 0; if (chg_Time == 1){rtc.adjust(DateTime(2015, 2, 27, A_H, A_M, 0));}} //------------- if (L_R == 5) { if (Dreft5 == 0) { ClearNol(); KP = myPID.GetKp(); KI = myPID.GetKi(); KD = myPID.GetKd(); lcd.setCursor(0, 0);lcd.print("Setup PID controller"); lcd.setCursor(0, 1);lcd.print("Kp "); if (KP < 10) {lcd.print("0");lcd.print(KP);}else{lcd.print(KP);} lcd.setCursor(0, 2);lcd.print("Ki "); if (KI < 10) {lcd.print("0");lcd.print(KI);}else{lcd.print(KI);} lcd.print(" <=="); lcd.setCursor(0, 3);lcd.print("Kd "); if (KD < 10) {lcd.print("0");lcd.print(KD);}else{lcd.print(KD);} Dreft5 = 1;}} else {Dreft5 = 0;} //------------- if (L_R == 6 || L_R == 11 || L_R == 16) { if (Dreft_MAS_0 == 0) { if (L_R == 6) {Print_Pat_Screan_Temp();} if (L_R == 11) {Print_Pat_Screan_Time();} if (L_R == 16) {Print_Pat_Screan_Alarm();} lcd.setCursor(0, 3);lcd.print("^^^^"); Dreft_MAS_0 = 1;}} else {Dreft_MAS_0 = 0;} if (L_R == 7 || L_R == 12 || L_R == 17) { if (Dreft_MAS_1 == 0) { if (L_R == 7) {Print_Pat_Screan_Temp();} if (L_R == 12) {Print_Pat_Screan_Time();} if (L_R == 17) {Print_Pat_Screan_Alarm();} lcd.setCursor(4, 3);lcd.print("^^^^"); Dreft_MAS_1 = 1;}} else {Dreft_MAS_1 = 0;} if (L_R == 8 || L_R == 13 || L_R == 18) { if (Dreft_MAS_2 == 0) { if (L_R == 8) {Print_Pat_Screan_Temp();} if (L_R == 13) {Print_Pat_Screan_Time();} if (L_R == 18) {Print_Pat_Screan_Alarm();} lcd.setCursor(8, 3);lcd.print("^^^^"); Dreft_MAS_2 = 1;}} else {Dreft_MAS_2 = 0;} if (L_R == 9 || L_R == 14 || L_R == 19) { if (Dreft_MAS_3 == 0) { if (L_R == 9) {Print_Pat_Screan_Temp();} if (L_R == 14) {Print_Pat_Screan_Time();} if (L_R == 19) {Print_Pat_Screan_Alarm();} lcd.setCursor(12, 3);lcd.print("^^^^"); Dreft_MAS_3 = 1;}} else {Dreft_MAS_3 = 0;} if (L_R == 10 || L_R == 15 || L_R == 20) { if (Dreft_MAS_4 == 0) { if (L_R == 10) {Print_Pat_Screan_Temp();} if (L_R == 15) {Print_Pat_Screan_Time();} if (L_R == 20) {Print_Pat_Screan_Alarm();} lcd.setCursor(16, 3);lcd.print("^^^^"); Dreft_MAS_4 = 1;}} else {Dreft_MAS_4 = 0;} if (L_R == 21 || L_R == 26 || L_R == 31) { if (Dreft_MAS_5 == 0) { if (L_R == 21) {Print_Pat_Screan_Temp();} if (L_R == 26) {Print_Pat_Screan_Time();} if (L_R == 31) {Print_Pat_Screan_Alarm();} lcd.setCursor(0, 3);lcd.print("^^^^"); Dreft_MAS_5 = 1;}} else {Dreft_MAS_5 = 0;} if (L_R == 22 || L_R == 27 || L_R == 32) { if (Dreft_MAS_6 == 0) { if (L_R == 22) {Print_Pat_Screan_Temp();} if (L_R == 27) {Print_Pat_Screan_Time();} if (L_R == 32) {Print_Pat_Screan_Alarm();} lcd.setCursor(4, 3);lcd.print("^^^^"); Dreft_MAS_6 = 1;}} else {Dreft_MAS_6 = 0;} if (L_R == 23 || L_R == 28 || L_R == 33) { if (Dreft_MAS_7 == 0) { if (L_R == 23) {Print_Pat_Screan_Temp();} if (L_R == 28) {Print_Pat_Screan_Time();} if (L_R == 33) {Print_Pat_Screan_Alarm();} lcd.setCursor(8, 3);lcd.print("^^^^"); Dreft_MAS_7 = 1;}} else {Dreft_MAS_7 = 0;} if (L_R == 24 || L_R == 29 || L_R == 34) { if (Dreft_MAS_8 == 0) { if (L_R == 24) {Print_Pat_Screan_Temp();} if (L_R == 29) {Print_Pat_Screan_Time();} if (L_R == 34) {Print_Pat_Screan_Alarm();} lcd.setCursor(12, 3);lcd.print("^^^^"); Dreft_MAS_8 = 1;}} else {Dreft_MAS_8 = 0;} if (L_R == 25 || L_R == 30 || L_R == 35) { if (Dreft_MAS_9 == 0) { if (L_R == 25) {Print_Pat_Screan_Temp();} if (L_R == 30) {Print_Pat_Screan_Time();} if (L_R == 35) {Print_Pat_Screan_Alarm();} lcd.setCursor(16, 3);lcd.print("^^^^"); Dreft_MAS_9 = 1;}} else {Dreft_MAS_9 = 0;} //################################################################## if (U_D > 5) { //------------- if (L_R == 1) { if (T_Upr < 3) {T_Upr += 1;} lcd.setCursor(0, 1); lcd.print(" MODE TEMP"); lcd.setCursor(0, 2); if (T_Upr == 0) {lcd.print("1-4 OFF -----");} if (T_Upr == 1) {lcd.print("2-4 ON -----");} if (T_Upr == 2) {lcd.print("3-4 AUTO ");lcd.print(Setpoint);lcd.print('\0');} if (T_Upr == 3) {lcd.print("4-4 PREF -----");} lcd.setCursor(0, 3);lcd.print(" ^^^^ "); U_D = 5; } //------------- if (L_R == 2) { if (T_Upr == 2) { Setpoint += 1; chgTemp = 1; lcd.setCursor(0, 1); lcd.print(" MODE TEMP"); lcd.setCursor(0, 2); lcd.print("3-4 AUTO "); lcd.print(Setpoint);lcd.print('\0'); lcd.setCursor(0, 3);lcd.print(" ^^^^^"); } U_D = 5; } //------------- if (L_R == 3) { if (A_H < 23) {A_H += 1;} chg_Time = 1; PrintTime(); lcd.setCursor(0, 3);lcd.print("^^"); U_D = 5; } //------------- if (L_R == 4) { if (A_M > 0) {A_M += 1;} chg_Time = 1; PrintTime(); lcd.setCursor(0, 3);lcd.print(" ^^"); U_D = 5; } //------------- if (L_R == 5) { if (KI < 100) {KI += 1;}else{KI = 0;} lcd.setCursor(0, 2);lcd.print("Ki "); if (KI < 10) {lcd.print("0");lcd.print(KI);}else{lcd.print(KI);} lcd.print(" <=="); U_D = 5; } //------------- Upr_PAT(); //---------------------------------------------------------------------------------- } else if (U_D < 5) { if (L_R == 1) { if (T_Upr > 0) {T_Upr -= 1;} lcd.setCursor(0, 1); lcd.print(" MODE TEMP"); lcd.setCursor(0, 2); if (T_Upr == 0) {lcd.print("1-4 OFF -----");} if (T_Upr == 1) {lcd.print("2-4 ON -----");} if (T_Upr == 2) {lcd.print("3-4 AUTO ");lcd.print(Setpoint);lcd.print('\0');} if (T_Upr == 3) {lcd.print("4-4 PREF -----");} lcd.setCursor(0, 3);lcd.print(" ^^^^ "); U_D = 5; } //------------- if (L_R == 2) { if (T_Upr == 2) { Setpoint -= 1; chgTemp = 1; lcd.setCursor(0, 1); lcd.print(" MODE TEMP"); lcd.setCursor(0, 2); lcd.print("3-4 AUTO "); lcd.print(Setpoint);lcd.print('\0'); lcd.setCursor(0, 3);lcd.print(" ^^^^^"); } U_D = 5; } //------------- if (L_R == 3) { if (A_H > 0) {A_H -= 1;} chg_Time = 1; PrintTime(); lcd.setCursor(0, 3);lcd.print("^^"); U_D = 5; } //------------- if (L_R == 4) { if (A_M > 0) {A_M -= 1;} chg_Time = 1; PrintTime(); lcd.setCursor(0, 3);lcd.print(" ^^"); U_D = 5; } //------------- if (L_R == 5) { if (KI > 0) {KI -= 1;} else {KI = 100;} lcd.setCursor(0, 2);lcd.print("Ki "); if (KI < 10) {lcd.print("0");lcd.print(KI);}else{lcd.print(KI);} lcd.print(" <=="); U_D = 5; } //------------- Upr_PAT(); //------------- } } } void Prokachka(){ int TempINNasos = abs(Input); if (TempINNasos < 40) { NasosPromyvka(); // 3 запуска длительностью в 1 секунду } else if (TempINNasos > 40) { digitalWrite(NASOS, HIGH); // постоянная работа } else if (TempINNasos > 70) { digitalWrite(NASOS, LOW); // отключение } else if (TempINNasos > 90) { NasosKipyachenie(); // вклячатся на 1 минуту с интервалом 10 минут } if (EndOFNasos == 1) {DO_EVERY(_MIN_(5),{digitalWrite(NASOS,LOW);});EndOFNasos = 0;} // Включение насоса на 5 минут после завершения программ } void NasosPromyvka(){ if (tekPovtor_Promyvka < Povtor_Promyvka *2){ DO_EVERY(3000,{digitalWrite(NASOS,!digitalRead(NASOS)); tekPovtor_Promyvka += 1;}); } else {digitalWrite(NASOS,LOW);} /* DO_EVERY(_SEC_(20),{digitalWrite(NASOS,HIGH);}); DO_EVERY(_SEC_(5),{digitalWrite(NASOS,LOW);}); */ } void NasosKipyachenie(){ DO_EVERY(_MIN_(10),{digitalWrite(NASOS,HIGH);}); DO_EVERY(_MIN_(1),{digitalWrite(NASOS,LOW);}); } void PrintTime(){ lcd.setCursor(0, 0); lcd.print("Setup Time"); // lcd.setCursor(0, 1); lcd.print(now.hour()); lcd.print(":"); lcd.print(now.minute()); lcd.print(":"); lcd.print(now.second()); lcd.setCursor(0, 2); if (A_H < 10) {lcd.print("0");lcd.print(A_H);}else{lcd.print(A_H);} lcd.print(":"); if (A_M < 10) {lcd.print("0");lcd.print(A_M);}else{lcd.print(A_M);} lcd.print(":00 - New Time"); } void ReleMode(){ ClearNol(); lcd.print("Setup Rele MODE"); lcd.setCursor(0, 1); lcd.print(" MODE TEMP"); lcd.setCursor(0, 2); if (T_Upr == 0) {lcd.print("1-4 OFF -----");} if (T_Upr == 1) {lcd.print("2-4 ON -----");} if (T_Upr == 2) {lcd.print("3-4 AUTO "); Setpoint = EEPROM.read(110); lcd.print(Setpoint);lcd.print('\0');} if (T_Upr == 3) {lcd.print("4-4 PREF -----");} } void Upr_PAT(){ if (L_R == 6 || L_R == 11 || L_R == 16) { if (L_R == 6) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 11) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 16) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(0, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 7 || L_R == 12 || L_R == 17) { if (L_R == 7) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 12) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 17) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(4, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 8 || L_R == 13 || L_R == 18) { if (L_R == 8) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 13) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 18) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(8, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 9 || L_R == 14 || L_R == 19) { if (L_R == 9) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 14) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 19) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(12, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 10 || L_R == 15 || L_R == 20) { if (L_R == 10) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 15) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 20) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(16, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 21 || L_R == 26 || L_R == 31) { if (L_R == 21) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 26) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 31) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(0, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 22 || L_R == 27 || L_R == 32) { if (L_R == 22) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 27) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 32) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(4, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 23 || L_R == 28 || L_R == 33) { if (L_R == 23) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 28) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 33) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(8, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 24 || L_R == 29 || L_R == 34) { if (L_R == 24) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 29) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 34) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(12, 3);lcd.print("^^^^"); U_D = 5; } if (L_R == 25 || L_R == 30 || L_R == 35) { if (L_R == 25) { CHG_P_Temp(); Print_Pat_Screan_Temp(); } if (L_R == 30) { CHG_P_Time(); Print_Pat_Screan_Time(); } if (L_R == 35) { CHG_P_Alar(); Print_Pat_Screan_Alarm(); } lcd.setCursor(16, 3);lcd.print("^^^^"); U_D = 5; } } void CHG_P_Temp(){ if (U_D > 5) { if (Dreft_MAS_0 == 1) {if (Pat[0][P_Temp] < 100) {Pat[0][P_Temp] += 1;}} if (Dreft_MAS_1 == 1) {if (Pat[1][P_Temp] < 100) {Pat[1][P_Temp] += 1;}} if (Dreft_MAS_2 == 1) {if (Pat[2][P_Temp] < 100) {Pat[2][P_Temp] += 1;}} if (Dreft_MAS_3 == 1) {if (Pat[3][P_Temp] < 100) {Pat[3][P_Temp] += 1;}} if (Dreft_MAS_4 == 1) {if (Pat[4][P_Temp] < 100) {Pat[4][P_Temp] += 1;}} if (Dreft_MAS_5 == 1) {if (Pat[5][P_Temp] < 100) {Pat[5][P_Temp] += 1;}} if (Dreft_MAS_6 == 1) {if (Pat[6][P_Temp] < 100) {Pat[6][P_Temp] += 1;}} if (Dreft_MAS_7 == 1) {if (Pat[7][P_Temp] < 100) {Pat[7][P_Temp] += 1;}} if (Dreft_MAS_8 == 1) {if (Pat[8][P_Temp] < 100) {Pat[8][P_Temp] += 1;}} if (Dreft_MAS_9 == 1) {if (Pat[9][P_Temp] < 100) {Pat[9][P_Temp] += 1;}}} else{ if (Dreft_MAS_0 == 1) {if (Pat[0][P_Temp] > 0) {Pat[0][P_Temp] -= 1;}} if (Dreft_MAS_1 == 1) {if (Pat[1][P_Temp] > 0) {Pat[1][P_Temp] -= 1;}} if (Dreft_MAS_2 == 1) {if (Pat[2][P_Temp] > 0) {Pat[2][P_Temp] -= 1;}} if (Dreft_MAS_3 == 1) {if (Pat[3][P_Temp] > 0) {Pat[3][P_Temp] -= 1;}} if (Dreft_MAS_4 == 1) {if (Pat[4][P_Temp] > 0) {Pat[4][P_Temp] -= 1;}} if (Dreft_MAS_5 == 1) {if (Pat[5][P_Temp] > 0) {Pat[5][P_Temp] -= 1;}} if (Dreft_MAS_6 == 1) {if (Pat[6][P_Temp] > 0) {Pat[6][P_Temp] -= 1;}} if (Dreft_MAS_7 == 1) {if (Pat[7][P_Temp] > 0) {Pat[7][P_Temp] -= 1;}} if (Dreft_MAS_8 == 1) {if (Pat[8][P_Temp] > 0) {Pat[8][P_Temp] -= 1;}} if (Dreft_MAS_9 == 1) {if (Pat[9][P_Temp] > 0) {Pat[9][P_Temp] -= 1;}}} } void CHG_P_Time(){ if (U_D > 5) { if (Dreft_MAS_0 == 1) {if (Pat[0][P_Time] < 32000) {Pat[0][P_Time] += 1;}} if (Dreft_MAS_1 == 1) {if (Pat[1][P_Time] < 32000) {Pat[1][P_Time] += 1;}} if (Dreft_MAS_2 == 1) {if (Pat[2][P_Time] < 32000) {Pat[2][P_Time] += 1;}} if (Dreft_MAS_3 == 1) {if (Pat[3][P_Time] < 32000) {Pat[3][P_Time] += 1;}} if (Dreft_MAS_4 == 1) {if (Pat[4][P_Time] < 32000) {Pat[4][P_Time] += 1;}} if (Dreft_MAS_5 == 1) {if (Pat[5][P_Time] < 32000) {Pat[5][P_Time] += 1;}} if (Dreft_MAS_6 == 1) {if (Pat[6][P_Time] < 32000) {Pat[6][P_Time] += 1;}} if (Dreft_MAS_7 == 1) {if (Pat[7][P_Time] < 32000) {Pat[7][P_Time] += 1;}} if (Dreft_MAS_8 == 1) {if (Pat[8][P_Time] < 32000) {Pat[8][P_Time] += 1;}} if (Dreft_MAS_9 == 1) {if (Pat[9][P_Time] < 32000) {Pat[9][P_Time] += 1;}}} else{ if (Dreft_MAS_0 == 1) {if (Pat[0][P_Time] > 0) {Pat[0][P_Time] -= 1;}} if (Dreft_MAS_1 == 1) {if (Pat[1][P_Time] > 0) {Pat[1][P_Time] -= 1;}} if (Dreft_MAS_2 == 1) {if (Pat[2][P_Time] > 0) {Pat[2][P_Time] -= 1;}} if (Dreft_MAS_3 == 1) {if (Pat[3][P_Time] > 0) {Pat[3][P_Time] -= 1;}} if (Dreft_MAS_4 == 1) {if (Pat[4][P_Time] > 0) {Pat[4][P_Time] -= 1;}} if (Dreft_MAS_5 == 1) {if (Pat[5][P_Time] > 0) {Pat[5][P_Time] -= 1;}} if (Dreft_MAS_6 == 1) {if (Pat[6][P_Time] > 0) {Pat[6][P_Time] -= 1;}} if (Dreft_MAS_7 == 1) {if (Pat[7][P_Time] > 0) {Pat[7][P_Time] -= 1;}} if (Dreft_MAS_8 == 1) {if (Pat[8][P_Time] > 0) {Pat[8][P_Time] -= 1;}} if (Dreft_MAS_9 == 1) {if (Pat[9][P_Time] > 0) {Pat[9][P_Time] -= 1;}}} } void CHG_P_Alar(){ if (U_D > 5) { if (Dreft_MAS_0 == 1) {Pat[0][P_Alar] = 1;} if (Dreft_MAS_1 == 1) {Pat[1][P_Alar] = 1;} if (Dreft_MAS_2 == 1) {Pat[2][P_Alar] = 1;} if (Dreft_MAS_3 == 1) {Pat[3][P_Alar] = 1;} if (Dreft_MAS_4 == 1) {Pat[4][P_Alar] = 1;} if (Dreft_MAS_5 == 1) {Pat[5][P_Alar] = 1;} if (Dreft_MAS_6 == 1) {Pat[6][P_Alar] = 1;} if (Dreft_MAS_7 == 1) {Pat[7][P_Alar] = 1;} if (Dreft_MAS_8 == 1) {Pat[8][P_Alar] = 1;} if (Dreft_MAS_9 == 1) {Pat[9][P_Alar] = 1;}} else{ if (Dreft_MAS_0 == 1) {Pat[0][P_Alar] = 0;} if (Dreft_MAS_1 == 1) {Pat[1][P_Alar] = 0;} if (Dreft_MAS_2 == 1) {Pat[2][P_Alar] = 0;} if (Dreft_MAS_3 == 1) {Pat[3][P_Alar] = 0;} if (Dreft_MAS_4 == 1) {Pat[4][P_Alar] = 0;} if (Dreft_MAS_5 == 1) {Pat[5][P_Alar] = 0;} if (Dreft_MAS_6 == 1) {Pat[6][P_Alar] = 0;} if (Dreft_MAS_7 == 1) {Pat[7][P_Alar] = 0;} if (Dreft_MAS_8 == 1) {Pat[8][P_Alar] = 0;} if (Dreft_MAS_9 == 1) {Pat[9][P_Alar] = 0;}} } void Print_Pat_Screan_Temp(){ ClearNol(); cur = 1; if (L_R <= 20){ lcd.print("Setup PAT Temp"); for (int i = 0; i <= 4; i++) { if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);} cur += 4; } cur = 0; for (int i = 0; i < 5; i++) { R_Numb = i; if (cur == 1) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);} cur += 4; lcd.print(Pat[R_Numb][P_Temp]); } }else{ lcd.print("Setup PAT Temp"); cur = 1; for (int i = 5; i <= 9; i++) { if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);} cur += 4; } cur = 0; for (int i = 5; i < 10; i++) { R_Numb = i; if (cur == 1) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);} cur += 4; lcd.print(Pat[R_Numb][P_Temp]); } } } void Print_Pat_Screan_Time(){ ClearNol(); cur = 1; if (L_R <= 20){ lcd.print("Setup PAT Time"); for (int i = 0; i <= 4; i++) { if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);} cur += 4; } cur = 0; for (int i = 0; i < 5; i++) { R_Numb = i; if (cur == 0) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);} cur += 4; if (Pat[R_Numb][P_Time] < 10){lcd.print(Pat[R_Numb][P_Time]);lcd.print(" ");}else{lcd.print(Pat[R_Numb][P_Time]);} } }else{ cur = 1; lcd.print("Setup PAT Time"); for (int i = 5; i <= 9; i++) { if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);} cur += 4; } cur = 0; for (int i = 5; i < 10; i++) { R_Numb = i; if (cur == 0) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);} cur += 4; if (Pat[R_Numb][P_Time] < 10){lcd.print(Pat[R_Numb][P_Time]);lcd.print(" ");}else{lcd.print(Pat[R_Numb][P_Time]);} } } } void Print_Pat_Screan_Alarm(){ ClearNol(); cur = 1; if (L_R <= 20){ lcd.print("Setup PAT Alarm"); for (int i = 0; i <= 4; i++) { if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);} cur += 4; } cur = 0; for (int i = 0; i < 5; i++) { R_Numb = i; if (cur == 0) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);} cur += 4; if (Pat[R_Numb][P_Alar] == 0){lcd.print("OFF");}else{lcd.print("ON");} } }else{ cur = 1; lcd.print("Setup PAT Alarm"); for (int i = 5; i <= 9; i++) { if (cur == 1) {lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);}else{lcd.setCursor(cur, 1);lcd.print("P");lcd.print(i);} cur += 4; } cur = 0; for (int i = 5; i < 10; i++) { R_Numb = i; if (cur == 0) {lcd.setCursor(cur, 2);}else{lcd.setCursor(cur, 2);} cur += 4; if (Pat[R_Numb][P_Alar] == 0){lcd.print("OFF");}else{lcd.print("ON");} } } } void ClearNol(){ lcd.clear(); lcd.setCursor(0, 0); } void getPressedButton() { DO_EVERY(noTrem,{if (analogRead(0) < 100) {L_R--;}}); DO_EVERY(noTrem,{if (analogRead(0) > 1000){L_R++;}}); DO_EVERY(noTrem,{if (analogRead(1) < 100) {U_D++;}}); DO_EVERY(noTrem,{if (analogRead(1) > 1000){U_D--;}}); if (L_R < 0){L_R = PunkMenu;} if (L_R > PunkMenu){L_R = 0;} } void getTemp() { ds.reset(); ds.select(addr); ds.write(0x44, 1); ds.reset(); ds.select(addr); ds.write(0xBE); for ( int i = 0; i < 9; i++) { data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; if (data[7] == 0x10) { raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw & ~7; else if (cfg == 0x20) raw = raw & ~3; else if (cfg == 0x40) raw = raw & ~1; } celsius = (float)raw / 16.0; return; }Добрый день. Проконсультируйте будет ваша прошивка работать на Мега 2560 и экран
TFT 320QUT и что для этого надо.
Прошивка работать будет, но для использования указанной вами модели экрана необходимо использоваь другую библиотеку (я использую LiquidCrystal_I2C.h вам она не подайдет), и соответственно поменять больше половины кода отрисовывания менюшек. Одним словом вам будет проще написать с вой код.
Предварительный монтаж. В дальнейшем всё будет собранно на одной плате.
Также снгодня будут купленны разьемы на корпус для подключения тена, насоса, 220 вольт, и датчика температуры.
Датчик температуры будет запаян Оловянно-медным припоем в отверстие 6,5 высверленное в болте. Пустота между датчиком и болтом будет заполнена теплопроводящим клей-герметиком.
Купленны разьемы для подключения внешних устройств (тен, насос, датчик ds18b20) кнопка ресет, и клавишный общий выключатель.
Да, было бы не плохо научиться писать код.
Пока нравиться! Смущает только здоровый радиатор у пластика, но это все суеверия. Ждем фото общего готовго проджекта!
Почти готовый коньтроллер.
Почти готовый БАК.
Тестовый запуск всей конструкции.
Работа Бака
https://youtu.be/vtRUYCUEHXE
Работа контроллера
https://youtu.be/e4MfLSn30cs
Прект входит в заключительную стадию отладки и тестирования.
Испытание чиллира.
Итак первая партия домашнего пива прошла 50% отстаивания в бутылках (на следующие выходные буду пробовать)
Ссылки с рецептами.
http://rossibeer.ru/recepty-piva
http://www.castlemalting.com/CastleMaltingBeerRecipes.asp?Language=Russian
Котел 5091 http://www.klenmarket.ru/shop/inventory/kitchen-equipment/boilers/boiler-50-l-professional-luxstahl-101307/
Внутренний бак 6950 http://hbpro.ru/showcase/zheleznyj-kit-30l.7/
Насос 4750 http://вортекс-центр.рф/shop/n-gvs/bw152r12ot.html
ТЭН 2100 http://hbpro.ru/showcase/tehn-dlja-klona-20l.18/
Кран шаровой ½ дюйма, ножки для бака, фитинг для насоса (врезка в бак ½ дюйма, переходник американка вн-внеш резьба ½ дюйма, уголок внутр-внеш резьба ½ дюйма), прокладки ~ 1500-2000
Болт+гайки из нержи для датчика ~ 200 рублей
Чиллер 3500 http://hbpro.ru/showcase/chiller-dlja-klona-20l.24/
Из инструмента пришлось купить тиски, сверла кобальтовые (по нерже) разного диаметра, припой безсвинцовый, термоклей. На это еще где-то 3500 вышло.
Итого средняя стоимость проекта 31650 в среднем.
Пока нравиться! Смущает только здоровый радиатор у пластика, но это все суеверия. Ждем фото общего готовго проджекта!
Данный радиатор больше для перестраховки, в проццесе работы он немного тепленький. в следующей версии прошивки, я буду использовать немного другой алгоритм управления ТЕНом, поэтому от такого радиатора можно будет отказатся.
Процесс варки пивного сусла.
https://youtu.be/vjlG784vqak
Первая партия готова!
И как это на вкус?
И как это на вкус?
Ну мой комментарий вкуса будет предвзят априори, Но друзья которые пробовали говорят что не уступает магазинному разливному а то и превосходит его.
Вкус мягкий, насыщенный, в меру алкогольный (приблизительно 5,5 - 6 градусов).
Хороший вкус у пива -- это когда его хочется выпить много, за исключением случаев, когда хочется выпить все равно чего. :)
Круто! Реально круто! позже детальней рассмотрю, логика особенно интересна для пивоварения. А насчет сэма, пока меня трудно переубедить, хочу свою теорию реализовать в практику.
Переосмыслев всю логику и ошибки предыдущего контроллера начал разрабатывать новую версию с более одекватным меню, улучшенной производительностью и логикой, а также энкодером и SD кртой для загрузки файлов с рецептами.
готовый на 70% код (профильный режим в проццесе написания)
для простоты проект разбит на 8 файлов (но это не обязательно можно весь код сохранить в один файл)
// Last Relise - 05/08/2015 Alpha // // Last Relise - 21/08/2015 Betha // // Last Relise - 00/00/0000 Relise // ///////////////////////////////////// #include <SD.h> #include <SPI.h> #include <Wire.h> #include <EEPROM.h> #include <Encoder.h> #include <OneWire.h> #include <LiquidCrystal_I2C.h> #include <DS1307.h> #include <RTClib.h> #include <PID_v1.h> #include <IniFile.h> #include <TimeHelpers.h> #define DEBUG // #define ENCODER_DO_NOT_USE_INTERRUPTS #define ONE_WIRE_BUS 7 // Порт шина датчика температуры #define SD_SELECT 4 // Порт шина CS SD карты #define ButtonEnc 8 // Порт кнопка энкодора #define TEN1 13 // Порт шины нагревательного элемента 1 #define TEN2 6 // Порт шины нагревательного элемента 2 #define NASOS 9 // Порт шины рециркуляционного насоса #define BUZZ 5 // Порт выхода на пьезоизлучатель // #define P_Temp 0 // Поле масива с данными температуры #define P_Time 1 // Поле масива с данными времени #define P_Alar 2 // Поле масива с данными сигнализации #define BobleOff_tim 3000 // Время продувки насоса //`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````` byte type_s; // Создание переменной типа датчика измерения температуры byte data[12]; // Создание переменной данных датчика температуры byte addr[8]; // Создание переменной адреса датчика температуры // long Pos; // Создание переменной нового положения энкодера long position; // Создание переменной текущего положения энкодера long NeoTime = 0; // Создание переменной хранения значения unix времени конца выполнения программы // const size_t bufferLen = 30; // Создания константы размера буфера строк читаемых из ini файла // char buffer[bufferLen]; // Создания буфера строк читаемых из ini файла // double Setpoint; // Создание переменной устанавливаемой температуры (и передача данных из памяти) double Input; // Создание переменной входящих данных в ПИД регулятор double Output; // Создание переменной исходящих данных из ПИД регулятора double consKp = 5; // Создание переменных констант ПИД регулятора double consKi = 75; // Создание переменных констант ПИД регулятора double consKd = 1; // Создание переменных констант ПИД регулятора // String FileiniNAMEAn; String FileiniNAME; // 0 1 2 3 4 5 6 7 8 9 const String Prog[10] = {"PROG_1", "PROG_2", "PROG_3", "PROG_4", "PROG_5", "PROG_6", "PROG_7", "PROG_8", "PROG_9", "PROG_10"}; int Pat[10][3] = {{20,0,0}, {20,0,0}, {20,0,0}, {20,0,0}, {20,0,0}, {20,0,0}, {20,0,0}, {20,0,0}, {20,0,0}, {20,0,0} }; int prog = 0; int mem1 = 0; int mem2 = 0; int mem3 = 0; int Nasos_Start = 30; int Nasos_Stop = 80; int PID_SPEED = 3; int UPGRADE = 1000; // Частота обновления главного экрана в милисикундах int _HR = 0; // Создание переменной хранения значения часов int _MI = 0; // Создание переменной хранения значения минут int _SE = 0; // Создание переменной хранения значения секунд int A_H = 0; // Создание переменной хранения значения часов при изменении времени int A_M = 0; // Создание переменной хранения значения минут при изменении времени int maxMenu = 40; // Отсчет от 0 (количество пунктов -1). int curMenu = 0; // Значение текущего пункта меню. int Moschnost; // Создание переменной мощности нагревательного элемента int T_Upr = 0; // Режим работы. int P_Numb = 0; // Создание переменной определения пункта масива програмируемых периодов (общего назначения) int BobleOff_tec1 = 0; // Создание переменной хранения времени прошедшего с начала промывки насоса int BobleOff_tec2 = 0; // Создание переменной хранения времени прошедшего с начала промывки насоса int vinti = 0; // Создание переменной винтика :) int cardti = 0; // Создание переменной карточки :) // long unixt; // Создание переменной хранения текущего unix времени long Sec; // Создание переменной временивыполнения программы // float Mic1 = 0; // Переменные измерения производительности float Mic2 = 0; // Переменные измерения производительности float celsius; // Создание переменной значения измерений датчика температуры // boolean StartTime = false; // Создание переменной начала работы по заданному переоду (Р1 - Р9) boolean Rabota = true; // Создание переменной дополнительная переменная управления переключением периодов (Р1 - Р9) boolean Alarm = false; // Создание переменной значения сигнализации boolean Pause = false; // Создание переменной паузы в варке boolean BobleOff = true; // Создание переменной продувки насоса boolean BobleOffst = true; // Создание переменной продувки насоса boolean rasTempBol = false; // Создание переменной флага необходимости расчета времени boolean tr_menu = false; // Признак входа в меню настройки. boolean dir = false; // Признак переключения между вводом данных и листанием меню. boolean keyPres = false; // Признак исплнния клика по кнопке. boolean STATUS = false; // Состояние предохранителя (программа включена/выключенна) boolean Udate = true; // Обновление основного экрана boolean SD_stat = false; // Определяет наличие или отсутствие SD карты. //`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````` uint8_t vint1[8] = {B00000, B00111, B00101, B11111, B00100, B00100, B00000, B00000,}; uint8_t vint2[8] = {B00000, B00100, B00100, B11111, B00101, B00111, B00000, B00000,}; uint8_t vint3[8] = {B00000, B00100, B00100, B11111, B10100, B11100, B00000, B00000,}; uint8_t vint4[8] = {B00000, B11100, B10100, B11111, B00100, B00100, B00000, B00000,}; uint8_t gradus[8] = {B01000, B10100, B10100, B01000, B00000, B00000, B00000, B00000,}; uint8_t card[8] = {B00000, B00000, B01111, B10101, B10001, B11111, B11111, B11111,}; uint8_t curs[8] = {B11000, B11100, B11110, B11111, B11110, B11100, B11000, B00000,}; RTC_DS1307 rtc; // Инициализация Часов точного времени OneWire ds(ONE_WIRE_BUS); // Инициализация шины датчика измерения температуры LiquidCrystal_I2C lcd(0x27, 20, 4); // Инициализация дисплея DateTime now; // Создания объекта Часов точного времени PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT); // Инициализация ПИД регулятора Encoder myEnc(2, 3); // инициализация энкодера File root; File entry; class BUTTON { public: //================================================================ static const byte bounce_ = 50; // длительность отслеживания дребезга. static const byte doubleclick_ = 200; // длительность отслеживания двойного клика. static const unsigned int retention_ = 2000; // длительность отслеживания нажатия и удержания. static const unsigned long timer_ = 60000; // длительность отслеживания неактивности. //================================================================ boolean click_down; boolean click_up; boolean doubleclick; boolean timer; boolean retention; //================================= unsigned long m; boolean p; boolean b; boolean dc; byte c; boolean t; boolean r; //================================= byte _pb; //================================= BUTTON(byte pb) { _pb = pb; pinMode(_pb, INPUT); digitalWrite(_pb, 1); //==== click_down = 0; click_up = 0; doubleclick = 0; timer = 0; retention = 0; //==== m = millis(); p = digitalRead(_pb); b = 0; dc = 0; c = 0; t = 0; r = 0; //==== } void read() { //======================================================= unsigned long nm = millis(); boolean np = digitalRead(_pb); //================= boolean nb = 0; boolean ndc = 0; boolean nt = 0; boolean nr = 0; //================ click_down = 0; click_up = 0; doubleclick = 0; timer = 0; retention = 0; //================= if (np != p) {p = np; m = nm; } //======================================================= if (nm - m > bounce_) {nb = 1;} if (nm - m > doubleclick_) {ndc = 1;} if (ndc != dc) {dc = ndc; if (dc == 1) {c = 0;}} if (nb != b) {b = nb; if (p == 0 && b == 0) {click_down = 1; ++c; if (c == 2) {c = 0; doubleclick = 1;} } if (p == 1 && b == 1) {click_up = 1;} } //======================================================= if (nm - m > timer_) {nt = 1;} if (nt != t) {t = nt; if (p == 1 && t == 1) {timer = 1;}} //======================================================= if (nm - m > retention_) {nr = 1;} if (nr != r) {r = nr; if (p == 0 && r == 1) {retention = 1;}} //======================================================= }}; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BUTTON BUTTON_01(ButtonEnc); /////////////////////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ void clearLine(int line){if (line <= 3 && line >= 0){lcd.setCursor(0, line); lcd.print(" "); lcd.setCursor(0, line);} else {lcd.clear();}} void Enc_Zero(int ps = 0){ if (ps == 0) {myEnc.write(0);} else {ps = ps*4; myEnc.write(ps);} position = Pos;} void EnterCHG(){if (tr_menu == true) {if (dir == true) {Enc_Zero(curMenu); menu(curMenu);} else {lcd.setCursor(13, 0); lcd.print("Chenge"); Enc_Zero(0); ChgData();} dir = !dir;}} void Heat(boolean het = false){if (het){analogWrite(TEN1, Output); analogWrite(TEN2, Output);} else {analogWrite(TEN1, 0); analogWrite(TEN2, 0);}} /////////////////////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ void setup() { #ifdef DEBUG Serial.begin(115200); #endif // SavePAT(); LoadPAT(); rtc.begin(); lcd.init(); lcd.backlight(); lcd.createChar(1, vint1); lcd.createChar(2, vint2); lcd.createChar(3, vint3); lcd.createChar(4, vint4); lcd.createChar(5, gradus); lcd.createChar(6, card); lcd.createChar(7, curs); pinMode(TEN1, OUTPUT); pinMode(TEN2, OUTPUT); pinMode(BUZZ, OUTPUT); pinMode(NASOS, OUTPUT); pinMode(ButtonEnc, INPUT); digitalWrite(ButtonEnc, HIGH); myPID.SetMode(AUTOMATIC); lcd.setCursor(0, 0); lcd.print(__DATE__); lcd.setCursor(0, 1); lcd.print(__TIME__); delay(2000); lcd.clear(); if (!SD.begin(SD_SELECT)) {lcd.setCursor(0, 0); lcd.print("SD init - failed!");} // Тестирование SD карты (карта отсутствует) else {lcd.setCursor(0, 0); lcd.print("SD init - ok"); root = SD.open("/"); root.rewindDirectory(); SD_stat = true;} // Тестирование SD карты (карта на месте, исправна) delay(500); lcd.setCursor(0, 1); lcd.print("CPU init - ok"); // Приятный красивый мультик (несёт только эстетический хорактер) delay(500); lcd.setCursor(0, 2); lcd.print("SYS init - ok"); // Приятный красивый мультик (несёт только эстетический хорактер) delay(500); lcd.setCursor(0, 3); lcd.print("PID init - ok"); // Приятный красивый мультик (несёт только эстетический хорактер) delay(100); lcd.clear(); if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; } } void loop(){ Mic1 = millis(); now = rtc.now(); _HR = now.hour(); _MI = now.minute(); _SE = now.second(); getTemp(); Input = celsius; // Конвертация типов переменных на вход ПИД регулятора. DO_EVERY(PID_SPEED,{ myPID.Compute(); }); Pos = myEnc.read() / 4; Moschnost = map(Output, 0, 255, 0, 100); if (STATUS) { Prokachka(); if (!Pause){ UPGRADE = 500; if (T_Upr == 0) {analogWrite(TEN1, 255); analogWrite(TEN2, 255); Moschnost = 100;} if (T_Upr == 1) { if (Input < Setpoint) {Heat(true);} else {Heat(false); Moschnost = 0;}} if (T_Upr == 2) {Heater(); if (Input < Setpoint) {Heat(true);} else {Heat(false); Moschnost = 0;}} } else {Heat(false); UPGRADE = 1000;} } else {Heat(false); digitalWrite(NASOS, LOW); Moschnost = 0; UPGRADE = 1000;} //-------------------------------------------------------- BUTTON_01.read(); if (BUTTON_01.timer) {lcd.noBacklight(); tr_menu = false; lcd.noBlink(); lcd.clear(); Enc_Zero(0); keyPres = false;} if (BUTTON_01.click_down) {keyPres = true; lcd.backlight();} if (BUTTON_01.retention) {lcd.backlight(); tr_menu = !tr_menu; if (tr_menu == true) {Enc_Zero(0); menu(0); lcd.blink();} else {lcd.noBlink(); lcd.clear(); Enc_Zero(0); SavePAT();} keyPres = false;} if (BUTTON_01.doubleclick) {if (!tr_menu && position == 1 && !STATUS){STATUS = true; vinti = 0; BobleOff = true; Enc_Zero(0);} else if (!tr_menu && position == 0 && STATUS) {STATUS = false;} else if (tr_menu == false && position == 2 && STATUS) {Pause = !Pause;} Udate = true;} if (BUTTON_01.click_up) {if (keyPres == true) {EnterCHG();} keyPres = false;} //-------------------------------------------------------- if (tr_menu == false){ DO_EVERY(UPGRADE,{Udate = true;}); menu(99); } if (Pos != position) {position = Pos; lcd.backlight(); if (tr_menu == false) {if (position > 2) {Enc_Zero(0);} else if (position < 0) {Enc_Zero(2); } Print_ctrl_main();} if (tr_menu == true && dir == false) {if (position > maxMenu) {Enc_Zero(0);} else if (position < 0) {Enc_Zero(maxMenu);} menu(position);} if (tr_menu == true && dir == true) {ChgData();} } //`````````````````````````````````````````` #ifdef DEBUG Mic2 = 1000 / (millis() - Mic1); // Вычисление количества операций(циклов) в секунду // Переменные и флаги Serial.print(" Status-"); Serial.print(STATUS); Serial.print(" Pause-"); Serial.print(Pause); // Значения и параметры Serial.print(" Output-"); Serial.print(Output); Serial.print(" Input-"); Serial.print(Input); Serial.print(" celsius-"); Serial.print(celsius); Serial.print(" Setpoint-"); Serial.print(Setpoint); Serial.print(" Nasos_Start-"); Serial.print(Nasos_Start); Serial.print(" Nasos_Stop-"); Serial.print(Nasos_Stop); // Производительность Serial.print(" CPU-"); Serial.print(Mic2); Serial.print("Lps"); // Конец тестовой информации Serial.println(" |"); #endif //`````````````````````````````````````````` } // end Loopvoid ChgData(){ if (curMenu == 0) {if (position >= 0 && position <= 2) {T_Upr = position; lcd.setCursor(12, 1); switch (T_Upr){case 0:lcd.print("MAN "); break; case 1:lcd.print("AUTO"); break; case 2:lcd.print("PAT "); break;}} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 1) {if (position >= 25 && position <= 90) {Nasos_Start = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(25);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 2) {if (position >= 25 && position <= 90) {Nasos_Stop = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(25);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 3) {lcd.setCursor(6, 1); lcd.print(" "); CHGFile(); lcd.setCursor(6, 1); lcd.print(FileiniNAME); lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 4) {ReadINI(); lcd.setCursor(8, 3); if (!SD_stat) {lcd.print("fail");}else{lcd.print("ok");} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 5) {if (position >= 1 && position <= 100) {PID_SPEED = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 6) {if (position >= 0 && position <= 100) {consKi = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 7) {if (position >= 0 && position <= 100) {Setpoint = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 8) {if (position >= 0 && position <= 24) {A_H = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 9) {if (position >= 0 && position <= 59) {A_M = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 10){rtc.adjust(DateTime(2015, 8, 20, A_H, A_M, 0)); lcd.setCursor(12, 3); lcd.print("ok"); lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 11) {if (position >= 0 && position <= 100) {Pat[0][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 12) {if (position >= 0 && position <= 32000) {Pat[0][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 13) {if (position >= 0 && position <= 1) {Pat[0][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 14) {if (position >= 0 && position <= 100) {Pat[1][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 15) {if (position >= 0 && position <= 32000) {Pat[1][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 16) {if (position >= 0 && position <= 1) {Pat[1][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 17) {if (position >= 0 && position <= 100) {Pat[2][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 18) {if (position >= 0 && position <= 32000) {Pat[2][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 19) {if (position >= 0 && position <= 1) {Pat[2][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 20) {if (position >= 0 && position <= 100) {Pat[3][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 21) {if (position >= 0 && position <= 32000) {Pat[3][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 22) {if (position >= 0 && position <= 1) {Pat[3][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 23) {if (position >= 0 && position <= 100) {Pat[4][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 24) {if (position >= 0 && position <= 32000) {Pat[4][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 25) {if (position >= 0 && position <= 1) {Pat[4][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 26) {if (position >= 0 && position <= 100) {Pat[5][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 27) {if (position >= 0 && position <= 32000) {Pat[5][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 28) {if (position >= 0 && position <= 1) {Pat[5][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 29) {if (position >= 0 && position <= 100) {Pat[6][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 30) {if (position >= 0 && position <= 32000) {Pat[6][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 31) {if (position >= 0 && position <= 1) {Pat[6][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 32) {if (position >= 0 && position <= 100) {Pat[7][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 33) {if (position >= 0 && position <= 32000) {Pat[7][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 34) {if (position >= 0 && position <= 1) {Pat[7][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 35) {if (position >= 0 && position <= 100) {Pat[8][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 36) {if (position >= 0 && position <= 32000) {Pat[8][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 37) {if (position >= 0 && position <= 1) {Pat[8][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} if (curMenu == 38) {if (position >= 0 && position <= 100) {Pat[9][0] = position; lcd.setCursor(12, 1); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 1); lcd.blink();} if (curMenu == 39) {if (position >= 0 && position <= 32000) {Pat[9][1] = position; lcd.setCursor(12, 2); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 2); lcd.blink();} if (curMenu == 40) {if (position >= 0 && position <= 1) {Pat[9][2] = position; lcd.setCursor(12, 3); lcd.print(position); lcd.print(" ");} else {Enc_Zero(0);} lcd.setCursor(0, 3); lcd.blink();} }void Heater(){ }void Prokachka(){ if (BobleOff){ if (Input <= Nasos_Stop){ BobleOff_tec1 = millis(); if (BobleOffst){BobleOff_tec2 = BobleOff_tec1 + BobleOff_tim; BobleOffst = false;} if (BobleOff_tec1 <= BobleOff_tec2) {digitalWrite(NASOS, HIGH); Pause = true; } else {digitalWrite(NASOS, LOW); Pause = false; BobleOff = false; BobleOffst = true; BobleOff_tec1 = 0;} } else {BobleOff = false;} } if (!Pause){if (Input >= Nasos_Start && Input <= Nasos_Stop) {digitalWrite(NASOS, HIGH);} else {digitalWrite(NASOS, LOW);}} else {if (!BobleOff) {digitalWrite(NASOS, LOW);}} }void CHGFile(){ entry = root.openNextFile(); if (!entry) { root.rewindDirectory(); } FileiniNAMEAn = entry.name(); if (FileiniNAMEAn == "" or FileiniNAMEAn == "SYSTEM~1") {entry = root.openNextFile();} else {FileiniNAME = entry.name();}} void ReadINI(){ if (SD_stat){ char Str2[FileiniNAME.length()+1]; FileiniNAME.toCharArray(Str2, FileiniNAME.length()+1); IniFile ini(Str2); if (!ini.open()) {clearLine(0); lcd.print("Ini file does not exist"); while (1);} if (!ini.validate(buffer, bufferLen)) {clearLine(0); lcd.print("ini file "); lcd.print(ini.getFilename()); lcd.print(" not valid"); while (1);} //-------------------------------------------------------------------- if (ini.open()) { /* clearLine(0); lcd.print("Load: "); lcd.print(ini.getFilename()); */ } if (ini.getValue("NAME", "NAME", buffer, bufferLen)) {if (curMenu == 4) {clearLine(2); lcd.setCursor(1, 2); lcd.print(buffer);}} //else {clearLine(0); lcd.print("Default Error file");} if (ini.getValue("PID", "consKp", buffer, bufferLen)) {consKp = String(buffer).toInt();} if (ini.getValue("PID", "consKi", buffer, bufferLen)) {consKi = String(buffer).toInt();} if (ini.getValue("PID", "consKd", buffer, bufferLen)) {consKd = String(buffer).toInt();} if (ini.getValue("PID", "PID_SPEED", buffer, bufferLen)) {PID_SPEED = String(buffer).toInt();} if (ini.getValue("NASOS", "start", buffer, bufferLen)) {Nasos_Start = String(buffer).toInt();} if (ini.getValue("NASOS", "stop", buffer, bufferLen)) {Nasos_Stop = String(buffer).toInt();} for (int mesMas=0; mesMas <= 9; mesMas++){ char Str1[Prog[mesMas].length()+1]; Prog[mesMas].toCharArray(Str1, Prog[mesMas].length()+1); if (ini.getValue(Str1, "P_Temp", buffer, bufferLen)) {Pat[mesMas][0] = String(buffer).toInt();} if (ini.getValue(Str1, "P_Time", buffer, bufferLen)) {Pat[mesMas][1] = String(buffer).toInt();} if (ini.getValue(Str1, "P_Alar", buffer, bufferLen)) {Pat[mesMas][2] = String(buffer).toInt();} } ini.close(); entry.close(); //-------------------------------------------------------------------- }}void LoadPAT(){ INI_pat_mem(); for (int pr=50; pr <= 59; pr++){ prog = pr - 50; mem1 = pr; mem2 = pr + 10; mem3 = pr + 20; Pat[prog][0] = EEPROM.read(mem1); Pat[prog][1] = EEPROM.read(mem2); Pat[prog][2] = EEPROM.read(mem3); } T_Upr = EEPROM.read(111); consKi = EEPROM.read(112); PID_SPEED = EEPROM.read(113); Nasos_Start = EEPROM.read(114); Nasos_Stop = EEPROM.read(115); Setpoint = EEPROM.read(116); myPID.SetTunings(consKp, consKi, consKd); } void SavePAT(){ INI_pat_mem(); for (int pr=50; pr <= 59; pr++){ prog = pr - 50; mem1 = pr; mem2 = pr + 10; mem3 = pr + 20; if (EEPROM.read(mem1) != Pat[prog][0]) {EEPROM.write(mem1, Pat[prog][0]);} if (EEPROM.read(mem2) != Pat[prog][1]) {EEPROM.write(mem2, Pat[prog][1]);} if (EEPROM.read(mem3) != Pat[prog][2]) {EEPROM.write(mem3, Pat[prog][2]);} } if (EEPROM.read(111) != T_Upr) {EEPROM.write(111, T_Upr); } // Сохранение значения режима работы if (EEPROM.read(112) != consKi) {EEPROM.write(112, consKi); myPID.SetTunings(consKp, consKi, consKd); } // Сохранение значения режима consKi PID регулятора if (EEPROM.read(113) != PID_SPEED) {EEPROM.write(113, PID_SPEED); } // Сохранение значения режима SPEED PID регулятора if (EEPROM.read(114) != Nasos_Start) {EEPROM.write(114, Nasos_Start); } // Сохранение значения режима запуска насоса if (EEPROM.read(115) != Nasos_Stop) {EEPROM.write(115, Nasos_Stop); } // Сохранение значения режима отключения насоса if (EEPROM.read(116) != Setpoint) {EEPROM.write(116, Setpoint); } // Сохранение значения установленной температуры } void INI_pat_mem(){ prog = 0; mem1 = 0; mem2 = 0; mem3 = 0; }void getTemp() { ds.reset(); ds.select(addr); ds.write(0x44, 1); ds.reset(); ds.select(addr); ds.write(0xBE); for ( int i = 0; i < 9; i++) {data[i] = ds.read();} int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; if (data[7] == 0x10) {raw = (raw & 0xFFF0) + 12 - data[6];} } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw & ~7; else if (cfg == 0x20) raw = raw & ~3; else if (cfg == 0x40) raw = raw & ~1; } celsius = (float)raw / 16.0; return; }void menu(int lvl){ if (lvl == 0 || lvl == 1 || lvl == 2){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 0"); lcd.setCursor(0, 1); lcd.print(" Mode:"); lcd.setCursor(12, 1); switch (T_Upr){case 0:lcd.print("MAN "); break; case 1:lcd.print("AUTO"); break; case 2:lcd.print("PAT "); break;} lcd.setCursor(0, 2); lcd.print(" Nasos run:"); lcd.setCursor(12, 2); lcd.print(Nasos_Start); lcd.setCursor(0, 3); lcd.print(" Nasos stop:"); lcd.setCursor(12, 3); lcd.print(Nasos_Stop); switch (lvl){case 0:lcd.setCursor(0, 1); lcd.blink(); break; case 1:lcd.setCursor(0, 2); lcd.blink(); break; case 2:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 3 || lvl == 4){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 1"); lcd.setCursor(0, 1); lcd.print(" File:"); lcd.print(FileiniNAME); if (!SD_stat) {lcd.setCursor(0, 2); lcd.print(" SD init - failed!");} lcd.setCursor(0, 3); lcd.print(" Load"); switch (lvl){case 3:lcd.setCursor(0, 1); lcd.blink(); break; case 4:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 5 || lvl == 6 || lvl == 7 ){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 2"); lcd.setCursor(0, 1); lcd.print(" PID_SPEED"); lcd.setCursor(12, 1); lcd.print(PID_SPEED); lcd.setCursor(0, 2); lcd.print(" consKi"); lcd.setCursor(12, 2); lcd.print(consKi); lcd.setCursor(0, 3); lcd.print(" Setpoint"); lcd.setCursor(12, 3); lcd.print(Setpoint); switch (lvl){case 5:lcd.setCursor(0, 1); lcd.blink(); break; case 6:lcd.setCursor(0, 2); lcd.blink(); break; case 7:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 8 || lvl == 9 || lvl == 10 ){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 3"); lcd.setCursor(0, 1); lcd.print(" hour"); lcd.setCursor(12, 1); lcd.print(A_H); lcd.setCursor(0, 2); lcd.print(" minute"); lcd.setCursor(12, 2); lcd.print(A_M); lcd.setCursor(0, 3); lcd.print(" set clock"); switch (lvl){case 8: lcd.setCursor(0, 1); lcd.blink(); break; case 9: lcd.setCursor(0, 2); lcd.blink(); break; case 10:lcd.setCursor(0, 3); lcd.blink(); break;} } //``````````````````````````````````````````````````````````````````````````````````````````` if (lvl == 11 || lvl == 12 || lvl == 13){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.0"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[0][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[0][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[0][2]); switch (lvl){case 11:lcd.setCursor(0, 1); lcd.blink(); break; case 12:lcd.setCursor(0, 2); lcd.blink(); break; case 13:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 14 || lvl == 15 || lvl == 16){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.1"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[1][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[1][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[1][2]); switch (lvl){case 14:lcd.setCursor(0, 1); lcd.blink(); break; case 15:lcd.setCursor(0, 2); lcd.blink(); break; case 16:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 17 || lvl == 18 || lvl == 19){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.2"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[2][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[2][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[2][2]); switch (lvl){case 17:lcd.setCursor(0, 1); lcd.blink(); break; case 18:lcd.setCursor(0, 2); lcd.blink(); break; case 19:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 20 || lvl == 21 || lvl == 22){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.3"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[3][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[3][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[3][2]); switch (lvl){case 20:lcd.setCursor(0, 1); lcd.blink(); break; case 21:lcd.setCursor(0, 2); lcd.blink(); break; case 22:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 23 || lvl == 24 || lvl == 25){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.4"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[4][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[4][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[4][2]); switch (lvl){case 23:lcd.setCursor(0, 1); lcd.blink(); break; case 24:lcd.setCursor(0, 2); lcd.blink(); break; case 25:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 26 || lvl == 27 || lvl == 28){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.5"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[5][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[5][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[5][2]); switch (lvl){case 26:lcd.setCursor(0, 1); lcd.blink(); break; case 27:lcd.setCursor(0, 2); lcd.blink(); break; case 28:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 29 || lvl == 30 || lvl == 31){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.6"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[6][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[6][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[6][2]); switch (lvl){case 29:lcd.setCursor(0, 1); lcd.blink(); break; case 30:lcd.setCursor(0, 2); lcd.blink(); break; case 31:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 32 || lvl == 33 || lvl == 34){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.7"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[7][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[7][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[7][2]); switch (lvl){case 32:lcd.setCursor(0, 1); lcd.blink(); break; case 33:lcd.setCursor(0, 2); lcd.blink(); break; case 34:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 35 || lvl == 36 || lvl == 37){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.8"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[8][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[8][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[8][2]); switch (lvl){case 35:lcd.setCursor(0, 1); lcd.blink(); break; case 36:lcd.setCursor(0, 2); lcd.blink(); break; case 37:lcd.setCursor(0, 3); lcd.blink(); break;} } if (lvl == 38 || lvl == 39 || lvl == 40){ lcd.clear(); curMenu = lvl; clearLine(0); lcd.setCursor(0, 0); lcd.print(" MENU - 4.9"); lcd.setCursor(0, 1); lcd.print(" P_Temp "); lcd.setCursor(12, 1); lcd.print(Pat[9][0]); lcd.setCursor(0, 2); lcd.print(" P_Time "); lcd.setCursor(12, 2); lcd.print(Pat[9][1]); lcd.setCursor(0, 3); lcd.print(" P_Alar "); lcd.setCursor(12, 3); lcd.print(Pat[9][2]); switch (lvl){case 38:lcd.setCursor(0, 1); lcd.blink(); break; case 39:lcd.setCursor(0, 2); lcd.blink(); break; case 40:lcd.setCursor(0, 3); lcd.blink(); break;} } //``````````````````````````````````````````````````````````````````````````````````````````` if (lvl == 99){ if (Udate){ Udate = false; lcd.setCursor(0, 0); lcd.print("T.ust "); lcd.print(Setpoint); lcd.print("\5"); Card(); if (STATUS) {Vintik(); lcd.setCursor(17, 0); lcd.print("RUN");} else {lcd.setCursor(15, 0); lcd.print("+ OFF");} lcd.setCursor(0, 1); lcd.print("T.zid "); lcd.print(Input); lcd.print("\5"); lcd.setCursor(13, 1); switch (T_Upr){case 0:lcd.print("M"); break; case 1:lcd.print("A"); break; case 2:lcd.print("P"); break;} lcd.setCursor(0, 2); lcd.print("P.ten "); lcd.setCursor(13, 2); if (T_Upr == 2) {lcd.print(P_Numb);} else {lcd.print("-");} if (Moschnost <= 100) {lcd.setCursor(6, 2);lcd.print(Moschnost); lcd.print("% ");} if (Moschnost < 10) {lcd.setCursor(6, 2);lcd.print(Moschnost); lcd.print("% ");} Print_ctrl_main(); lcd.setCursor(0, 3); if (_HR < 10) {lcd.print("0"); lcd.print(_HR);} else {lcd.print(_HR);} lcd.print(":"); if (_MI < 10) {lcd.print("0"); lcd.print(_MI);} else {lcd.print(_MI);} lcd.print(":"); if (_SE < 10) {lcd.print("0"); lcd.print(_SE);} else {lcd.print(_SE);} lcd.setCursor(13, 3); if (digitalRead(NASOS)) {if (BobleOff) {lcd.print("B");} else {lcd.print("N");}} else {lcd.print("-");} } } } void Print_ctrl_main(){ if (tr_menu == false && position == 0) {lcd.setCursor(15, 1); lcd.print("\7STOP"); lcd.setCursor(15, 2); lcd.print(" WORK"); lcd.setCursor(15, 3); if (Pause) {lcd.print(" NEXT");} else {lcd.print(" PAUS");}} if (tr_menu == false && position == 1) {lcd.setCursor(15, 1); lcd.print(" STOP"); lcd.setCursor(15, 2); lcd.print("\7WORK"); lcd.setCursor(15, 3); if (Pause) {lcd.print(" NEXT");} else {lcd.print(" PAUS");}} if (tr_menu == false && position == 2) {lcd.setCursor(15, 1); lcd.print(" STOP"); lcd.setCursor(15, 2); lcd.print(" WORK"); lcd.setCursor(15, 3); if (Pause) {lcd.print("\7NEXT");} else {lcd.print("\7PAUS");}} } void Vintik(){ lcd.setCursor(15, 0); if (!Pause){ vinti = vinti + 1; switch (vinti){case 1:lcd.print("\1"); break; case 2:lcd.print("\2"); break; case 3:lcd.print("\3"); break; case 4:lcd.print("\4"); vinti = 0; break;} } } void Card(){ lcd.setCursor(13, 0); if (!SD_stat){ cardti = cardti + 1; switch (cardti){case 1:lcd.print("\6"); break; case 2:lcd.print(" "); cardti = 0; break;} }else{lcd.print("\6");} }Работа с меню осуществляется с помощью энкодера и его кнопки. Находясь на домашнем экране поворот энкодера переключает отдин из 3х пунктов меню (см. скриншот выше). При двойном клике (два key_up до 200ms) активируется соответствующий выбранный пунк. Длительное (2000ms) нажатие переводит в меню настроек (скриншоты в проццесе), далее вращение энкодера переключает по пунктам меню. короткий клик на выбраном пункте меню вводит в состояние настройки параметра, второй короткий клик в меню применяет заданные параметры. Длительный клик находясь в меню запускает процедуру сохранения !только измененых параметров! и выводит на домашний экран.
Отдельное спасибо Клапауций 999 за класс для кнопки, и leshak за <TimeHelpers.h>
Формат ini файла с рецептом
Отдельное спасибо Клапауций 999 за класс для кнопки
ок - рад, что не мне одному показалось это нужным.
Максим! как успехи с новой версией проекта? добил его
Переосмыслев всю логику и ошибки предыдущего контроллера начал разрабатывать новую версию с более одекватным меню, улучшенной производительностью и логикой, а также энкодером и SD кртой для загрузки файлов с рецептами.
Аналогично. Пересмотрев существующие решения и желания пивоваров, начали разработку новой автоматики с touch LCD и WiFi.
Небольшой демо-ролик
За подробностями можно следить тут http://hbpro.ru/threads/wi-fi-kontroller-na-esp8266.233/
Здравствуйте! maxi_10, продолжение будет?)) очень ждем) или, если может где-нибудь на другом ресурсе описывали, можно ссылочку?
Здраствуйте уважаемый maxi_10! Заинтересовал ваш проект. Какова судьба и как с продолжением?
Здравствуйте, я собрал автоматику на LCD 3.2 на Mega кому интерестно https://youtu.be/BvQUjaGohdY
День добрый! не могу найти библиотеку <TimeHelpers.h>.
Привет всем!!! а я с компа варю) https://youtu.be/Ua9WxJoCwpc