//https://arduino-tex.ru/news/172/tipy-dannyh-v-arduino-ide-i-ih-ves-razmer-v-baitah.html
//uxTaskGetStackHighWaterMark показывает, сколько стека никогда не использовалось, а не значение использованного стека. Он должен сообщать как можно ближе к 0 (с некоторым запасом).
#include <logger.h>
#include <button.h>
#include <run.h>
#include <temp.h>
#include <pressure.h>
#include <tn.h>
//Остальное
#include <neotimer.h>
//Управление eev
#include <AccelStepper.h>
//Гистерезис управляемой температуры
#include <GyverRelay.h>
//Пид регулирование eev
#include <QuickPID.h>
#include <freon.h>
//------------------Новое мое-------------------
#define TN_PAUSE 0; // 0 пауза // 1 ТН включен //По умолчанию в момент включения включена пауза работы компрессора ТН
#define BOOT_REBOOT 1; //Статус запуска или ребута контроллера
#define BOOT_REBOOT_TIME 60; //Ждем время при первом старте ТН
#define MOTOR_START_TIME 2; //Пауза между включение насоса скважины и насоса теплого пола
#define MOTOR_COLDSIDE_TIME 5; //Таймаут ожидания проверки протока скважины
#define MOTOR_HOTSIDE_TIME 5; //Таймаут ожидания проверки протока теплого пола
//------------------Новое разобрать---------
#define FREON_TYPE 1 // Тип фреона //0 = 22 //1 = 410 //6 R290 пропан .....
#define DEFROST 0 // 1 нужна разморозка
// Защиты по входному напряжению. Используется счетчик SDM*
#define SDM_MIN_VOLTAGE 170.0 // Минимальное напряжение работы ТН при падении - предупреждение
#define SDM_MAX_VOLTAGE 250.0 // Максимальное напряжение работы ТН при падении - выключение ТН
#define SDM_MAX_POWER 2500.0 // Максимальная мощность потребления (ватт) - выключение ТН
// Временные задержки/времена начала дефайна в конфиге начинается DELAY в константах начинается с TIME
#define DEF_DELAY_ON_PUMP 60; // Задержка включения компрессора после включения насосов (сек).
#define DEF_DELAY_OFF_PUMP 60; // Задержка выключения насосов после выключения компрессора (сек).
#define DEF_DELAY_START_RES (5*60) // Задержка включения ТН после внезапного сброса контроллера (сек.)
#define DEF_DELAY_REPEAD_START (10*60) // Задержка перед повторным включениме ТН при ошибке (попытки пуска) секунды
#define DEF_DELAY_DEFROST_ON 120 // ДЛЯ ВОЗДУШНОГО ТН Задержка после срабатывания датчика перед включением разморозки (секунды)
#define DEF_DELAY_DEFROST_OFF 120 // ДЛЯ ВОЗДУШНОГО ТН Задержка перед выключением разморозки (секунды)
#define DEF_DELAY_R4WAY 120 // Задержка между переключением 4-х ходового клапана и включением компрессора, для выравнивания давлений (сек). Если включены эти опции (переключение тепло-холод)
#define DEF_DELAY_BOILER_SW 60 // Пауза (сек) после переключение ГВС - выравниваем температуру в контуре отопления/ГВС что бы сразу защиты не сработали
#define DEF_DELAY_BOILER_OFF 120 // Время (сек) на сколько блокируются защиты при переходе с ГВС на отопление и охлаждение слишком горяче после ГВС
#define DELAY_AFTER_SWITCH_RELAY 500 // Задержка после переключения реле, для сглаживания потребления и уменьшения помех(мс)
#define DELAY_BEFORE_STOP_IN_PUMP 10 // Задержка перед выключением насоса геоконтура, насос отопления отключается позже (сек)
//--------------ПИНЫ------------------------
#define PIN_TEMP1 6 //Пин с температурными датчиками группы 1
#define PIN_TEMP2 7 //Пин с температурными датчиками группы 2
#define PIN_LOW_PRESSURE 11 // Датчик низкого давления
#define PIN_HIGH_PRESSURE 12 // Датчик высокого давления
#define PIN_SENSOR_COLDSIDE 35 // - ПИН Датчик протока по кондесатору
#define PIN_SENSOR_HOTSIDE 36 // - ПИН Датчик протока по испарителю
#define RELAY_PIN_1 6 // Пин мотора теплового насоса //Пин компрессора
#define RELAY_PIN_2 42 // Пин насоса скважины
#define RELAY_PIN_3 41 // Пин насоса теплого пола
//#define RELAY_PIN_4 43 // Пин клапана высокого давления //защита от обмораживания
// EEV куда подключено общий СИНИЙ
#define PIN_EEV1 15 // ++ первая нога ЭРВ D24 ОРАНЖЕВЫЙ +А
#define PIN_EEV2 16 // ++ вторая нога ЭРВ D25 КРАСНЫЙ +B
#define PIN_EEV3 17 // ++ третья нога ЭРВ D26 ЖЕЛТЫЙ -A
#define PIN_EEV4 18 // ++ четвертая нога ЭРВ D27 ЧЕРНЫЙ -B
//------Режим работы ТН---------------------
#define WORK_MODE 0; // 0 - ручное, 1 - по температуре воздуха, 2 - по температуре подачи, 3 - по температуре обратки
#define PIN_MANUAL_CONTROL 100; //Включение по кнопке для ручного управления
//-------Целевая температура и гистезис------
#define TEMP_TARGET_SET 24.0; // Целевая температуры (начальная температура)
#define TEMP_TARGET_HYSTER 2; // ширина гистерезиса градусы
#define TEMP_TARGET_FEEDBACK 0.5; //коэффициент обратной связи (подбирается по факту)
//#define MIN_SET_TEMP 20.0; //Минимальная целевая температура
//#define MAX_SET_TEMP 25.0; //Максимальная целевая температура
//-------------------Константы--------------
#define MAX_COMPRESSOR_HEATING_CABLE 16.0; //Порог выключения греющего кабеля
#define MAX_COMPRESSOR_TEMP 110.0; //Максимальная температура компрессора
#define MIN_COMPRESSOR_TEMP 6.0; //Минимальная температура компрессора
#define MIN_RETURN_WATER_TEMP 2.0; //Минимальная температура обратки после испарителя (вода-вода)
#define MIN_WORK_TIME 30; //Минимальное время работы ТН (или компрессора) сек
#define MIN_L_PRESSURE 2.0; //Минимальное давление фреона (низкий контур)
#define MAX_H_PRESSURE 25.0; //Максимальное давление фреона (высокий контур)
/*
// Температура хранится в сотых градуса
#define TOUT 0 // Температура улицы
#define TIN 1 // Температура в доме
#define TEVAIN 2 // Температура на входе испарителя (по фреону)
#define TEVAOUT 3 // Температура на выходе испарителя (по фреону)
#define TCONIN 4 // Температура на входе конденсатора (по фреону)установлен 02.06.19
#define TCONOUT 5 // Температура на выходе конденсатора (по фреону) установлен 02.06.19
#define TBOILER 6 // Температура в бойлере ГВС
#define TACCUM 7 // Температура на выходе теплоаккмулятора
#define TCOMPIN 8 // Температура на входе компрессора
#define TCOMP 9 // Температура нагнетания компрессора
#define TEVAING 10 // Температура на входе испарителя (по гликолю)
#define TEVAOUTG 11 // Температура на выходе испарителя (по гликолю)
#define TCONING 12 // Температура на входе конденсатора (по гликолю)
#define TCONOUTG 13 // Температура на выходе конденсатора (по гликолю)
*/
//#define RBOILER 3 //Пин включение ТЭНа бойлера
//#define R3WAY 5 //Пин 3-ходовой клапан
//#define R4WAY 4 //Пин 4-ходовой клапан (охлаждение)
//#define RHEAT 6 //Пин Включение ТЭНа СО (электрокотел), может использоваться как догрев, резерв и т.д.
//#define RPUMPB 7 //Пин Реле насоса циркуляции бойлера (ГВС)
//#define RFAN1 5 // Реле включения вентилятора испарителя №1
//#define RFAN2 6 // Реле включения вентилятора испарителя №2
#define EEV 1 // Наличие ЭРВ в конфигурации
#define EEV_start 0 // 0 еще не стартанул, ждем нуля и закрытия
#define EEV_TYPE 1 //Режим определения перегрева // 1 - два датчика температуры, 2 - датчик давления и температуры, 3 - два датчика давления
#define EEV_SPEED 40 // Скорость шагового двигателя ЭРВ (импульсы в сек.)
#define EEV_MIN_STEPS 66 // Число шагов EEV
#define EEV_MAX_STEPS 480 // Число шагов EEV
#define EEV_CLOSE_STEP 2 // Позиция ЭРВ - Закрыто
#define EEV_ACCELERATION 50 //Ускорение EEV //Было 100
#define EEV_TIME 50 // Постоянная интегрирования времени в секундах ЭРВ СЕКУНДЫ
/* тут не мое */
//#define EEV_Kp 2500 // ПИД Коэф пропорц. В ТЫСЯЧНЫХ
//#define EEV_Ki 800 // ПИД Коэф интегр. В ТЫСЯЧНЫХ
//#define EEV_Kd 900 // ПИД Коэф дифф. В ТЫСЯЧНЫХ
//V1
#define EEV_Kp 3 // ПИД Коэф пропорц.
#define EEV_Ki 40 // ПИД Коэф интегр.
#define EEV_Kd 1 // ПИД Коэф дифф.
//V2
//#define EEV_Kp 15 // ПИД Коэф пропорц.
//#define EEV_Ki 150 // ПИД Коэф интегр.
//#define EEV_Kd 5 // ПИД Коэф дифф.
#define EEV_POSITION 0 // текущая позиция eev
#define EEV_START_POS 200 // ПУСКОВАЯ позиция ЭРВ (ТО что при старте компрессора ПРИ РАСКРУТКЕ)
#define EEV_HOLD_MOTOR 0 // Режим "удержания" шагового двигателя ЭРВ
#define DEFAULT_DELAY_ON_PID 120 // Задержка включения EEV после включения компрессора (сек). Точнее после выхода на рабочую позицию
#define DEFAULT_DELAY_ON 5 // Задержка между открытием (для старта) ЭРВ и включением компрессора, для выравнивания давлений (сек). Если ЭРВ закрывлось при остановке
#define DEFAULT_DELAY_START_POS 30 // Время после старта компрессора когда EEV выходит на стартовую позицию - облегчение пуска вначале ЭРВ
#define DEFAULT_DELAY_OFF 10 // Задержка закрытия EEV после выключения насосов (сек). Время от команды стоп компрессора до закрытия ЭРВ = delayOffPump+delayOff
//---- Управление перегревом ----
#define OVERHEAT 6 // Заданное значение перегрева
#define CURRENT_OVERHEAT 0 // Текущее значение перегрева
//-----------------Переменные---------------
uint8_t freon_type = FREON_TYPE; // Тип фреона //0 = 22 //1 = 410 //6 R290 пропан .....
uint8_t work_mode = WORK_MODE; //Режим работы ТН )(0 - ручное, 1 - по температуре воздуха, 2 - по температуре подачи, 3 - по температуре обратки)
uint8_t tn_pause = TN_PAUSE; //Пауза в работе ТН
bool debug_mode = false;
bool start = false; //По умолчанию ТН остановлен (общий)
//bool tn_start = false; //При запуске ТН остановлен
float temp_target_set = TEMP_TARGET_SET;
float temp_target_hysteresis = TEMP_TARGET_HYSTER;
float temp_target_feedback = TEMP_TARGET_FEEDBACK;
//int timeout_start_compressor = TIMEOUT_START;
bool cont_flow_cold = false; //контакт// По умолчанию нет протока = false
bool cont_flow_hot = false; //контакт// По умолчанию нет протока = 1
bool boot_reboot = BOOT_REBOOT; //Статус запуска или ребута контроллера
int boot_reboot_time = BOOT_REBOOT_TIME; //Ждем время при первом старте ТН
int motor_start_time = MOTOR_START_TIME; //Пауза между включением насоса скважины и насоса теплого пола
int motor_coldside_time = MOTOR_COLDSIDE_TIME; //Таймаут ожидания проверки протока скважины
int motor_hotside_time = MOTOR_HOTSIDE_TIME; //Таймаут ожидания проверки протока теплого пола
//-----------------Статусы------------------
bool start_status = 0; // 0 - ТН остановлен 1 - ТН запущен
//bool heatpump_state = 0; //flag_start //не используем
bool temp_state = false;
bool coldside_circle_state = false; //По умолчанию насос скважины остановлен
bool hotside_circle_state = false; //По умолчанию насос теплого пола остановлен
//bool tmp_coldside_circle_state = false;
//bool tmp_hotside_circle_state = false;
bool sensor_coldside = false; //Датчик протока скважины
bool sensor_hotside = false; //Датчик протока теплого пола
/* не использую
start_status
0: первый запуск конроллера
1: по температуре
2:
stop_status
0: первый запуск конроллера
1: по ошибке
*/
//--------------Оборудование-----------------
//#define RELAY_HEATPUMP 25
//#define RELAY_COLDSIDE_CIRCLE 26
//#define RELAY_HOTSIDE_CIRCLE 27
//#define CONT_FLOW_COLD 15 //Контакт датчика протока холодая часть
//#define CONT_FLOW_HOT 14 //Контакт датчика протока горячаяя часть
//#define RELAY_CIRCUL A3
//#define RELAY_PUMP_STANTION A4
//------Переменные TEMPERATURE SENSORS------
float current_temp = 0;
float isp_water_temp_in = 0;
float isp_water_temp_out = 0;
float isp_freon_temp_in = 0;
float isp_freon_temp_out = 0;
float cond_water_temp_in = 0;
float cond_water_temp_out = 0;
float cond_freon_temp_in = 0;
float cond_freon_temp_out = 0;
//old temperature's
float old_current_temp = 0;
float old_isp_water_temp_in = 0;
float old_isp_water_temp_out = 0;
float old_isp_freon_temp_in = 0;
float old_isp_freon_temp_out = 0;
float old_cond_water_temp_in = 0;
float old_cond_water_temp_out = 0;
float old_cond_freon_temp_in = 0;
float old_cond_freon_temp_out = 0;
//-------Переменные температура по давлению фреона
float isp_freon_temp_pressure_in = 0;
float isp_freon_temp_pressure_out = 0;
float cond_freon_temp_pressure_in = 0;
float cond_freon_temp_pressure_out = 0;
float old_isp_freon_temp_pressure_in = 0;
float old_isp_freon_temp_pressure_out = 0;
float old_cond_freon_temp_pressure_in = 0;
float old_cond_freon_temp_pressure_out = 0;
//------Переменные давления фреона---------
float min_l_pressure = MIN_L_PRESSURE; //Минимальное давление фреона (низкий контур)
float max_h_pressure = MAX_H_PRESSURE; //Максимальное давление фреона (высокий контур)
float low_pressure_value_in = 0; //Давление фреона получено с датчика (низкое) вход в испаритель
float low_pressure_value_out = 0; //Давление фреона получено с датчика (низкое) выход из испарителя
float high_pressure_value_in = 0; //Давление фреона получено с датчика (высокое) вход в конденсатор
float high_pressure_value_out = 0; //Давление фреона получено с датчика (высокое) выход из конденсатора
float old_low_pressure_value_in = 0; //Давление фреона получено с датчика (низкое) вход в испаритель
float old_low_pressure_value_out = 0; //Давление фреона получено с датчика (низкое) выход из испарителя
float old_high_pressure_value_in = 0; //Давление фреона получено с датчика (высокое) вход в конденсатор
float old_high_pressure_value_out = 0; //Давление фреона получено с датчика (высокое) выход из конденсатора
//-----Переменные температуры
float max_compressor_temp = MAX_COMPRESSOR_TEMP;
float min_return_water_temp = MIN_RETURN_WATER_TEMP;
//-----------------------EEV CONF---------------------
uint8_t eev_type = EEV_TYPE;
uint8_t eev_start = EEV_start;
float eev_kp = EEV_Kp;
float eev_ki = EEV_Ki;
float eev_kd = EEV_Kd;
//Определите переменные, к которым мы будем подключаться
float eev_position = EEV_POSITION;
/* перегрев */
float overheat = OVERHEAT; // Заданное значение перегрева
float current_overheat = CURRENT_OVERHEAT; // Текущее значение перегрева
float old_current_overheat = 0;
/* это вроде старый конфиг
unsigned long Kover = 2; // Уменьшение постоянной времени в Kover раз при ощибке более 1.5 градусов в минус и 5 в плюс.
unsigned long Tint = 120; // ПОСТОЯННАЯ ВРЕМЕНИ ИНТЕГРИРОВАНИЯ, С
unsigned long Tintegr; // Постоянная интегрирования в цикле с учетом Kover, с.
unsigned long previousMillis = 0; // Служебная переменная коррекция интегрирующей цепью
unsigned long previousMillis1 = 0; // Служебная переменная1 опрос датчиков каждую 1 с
unsigned long previousMillis2 = 0; // Служебная переменная1 расчёт нового положения эрв без интегрирующей цепи каждые 15 с
int minst = 66; // минимальное число шагов открытия ЭРВ.
int st = minst; //установка ЭРВ в минимально открытое состояние.
int pre_st = minst; //установка ЭРВ в минимально открытое состояние.
int nulst = 200; // среднестатистическое положение ЭРВ, относительно которого производится ввод поправки в плюс/минус
float C = 0; // Служебная переменная интегрирования (накопительная)
int Kp = 20; // Коэф пропорц.
int Ki = 1; // Коэф интегр. для настройки Ki=0
int Kd = 27; // Коэф дифф. //10 = MAX SH 13.5 (485) //15 = MAX SH 12 (480) //27 = MAX SH 10 (482)
int Tpd = 5; // ВРЕМЯ В СЕК, РАСЧЁТА ПРОП И ДИФФ СОСТАВЛЯЮЩЕЙ с установкой эрв в новое положение. Желательно должна быть кратной Tint/4
float err = 0 ; // Константы и переменные для вычисления ошибки и необходимого положения ЭРВ (st)
float need_SH = 4; // Заданное значение перегрева
float SH = 0; //Перегрев
//int pd = 2.5; ///процентное отклонение 5% //2.5%
int pd = 1; ///процентное отклонение 1%
int pd_steps = 0;
*/
//-------------------Переменные для разработки тестовые данные------------------
//float current_temp = 20.5; //20.5 //22.5
//float return_water_temp = 4.0; //1.0 //4.0
///////////////////ИНИЦИАЛИЗАЦИЯ КЛАССов/////////////////////////////
TaskHandle_t Task1; //Для ядра 0 создадим Task1
TaskHandle_t Task2; //Для ядра 1 создадим Task2
TaskHandle_t LogTask;
TaskHandle_t EevTask;
TaskHandle_t TempTask;
TaskHandle_t PressureTask;
//------Температура-----
DS18B20Solo temp1(PIN_TEMP1, 8, 1000); // pin, type (не используется), prd
DS18B20Solo temp2(PIN_TEMP2, 8, 1300); // pin, type (не используется), prd
//Управление температурой (включение и пауза работы ТН)
GyverRelay regulator(REVERSE); // mode: NORMAL / REVERSE // установка, гистерезис, направление регулирования
//TEMP temp(1000, 1500); //время обновления A и B
//TEMP upd_tempB(0, 500); //id сенсора и время обновления
//-------Давление-------
//0.148 и 0.108 - датчик ВАЗ, расчет у меня в табличке в Google
pressure pressure_low(PIN_LOW_PRESSURE, 0.148, 0.108, 1000, 0); // пин датчика, a0, a1, время обновления, debug mode
pressure pressure_high(PIN_HIGH_PRESSURE, 0.148, 0.108, 1500, 0); // пин датчика, a0, a1, время обновления, debug mode
//Определение температуры по фреону
freon freon(freon_type); //0 = 22 //1 = 410 //6 R290 пропан .....
//---------------------AccelStepper--------------------------
//------------HALF4WIRE четырехпроводный мотор---------------
//AccelStepper stepper(AccelStepper::HALF4WIRE, 16, 17, 5, 18);
//AccelStepper stepper(AccelStepper::HALF4WIRE, 17, 16, 5, 18);
//AccelStepper stepper(AccelStepper::HALF4WIRE, 5, 18, 16, 17);
//AccelStepper stepper(AccelStepper::HALF4WIRE, 17, 18, 5, 16);
//AccelStepper stepper(AccelStepper::HALF4WIRE, 5, 18, 17, 16);
//AccelStepper stepper(AccelStepper::FULL4WIRE, 5, 18, 17, 16);
//AccelStepper stepper(AccelStepper::FULL4WIRE, 16, 17, 5, 18);
//AccelStepper stepper(AccelStepper::HALF4WIRE, 17, 18, 5, 16);
//AccelStepper stepper(AccelStepper::FULL4WIRE, 17, 18, 5, 16); //---
/* tmp
#define PIN_EEV1 15 // ++ первая нога ЭРВ D24 ОРАНЖЕВЫЙ +А
#define PIN_EEV2 16 // ++ вторая нога ЭРВ D25 КРАСНЫЙ +B
#define PIN_EEV3 17 // ++ третья нога ЭРВ D26 ЖЕЛТЫЙ -A
#define PIN_EEV4 18 // ++ четвертая нога ЭРВ D27 ЧЕРНЫЙ -B
*/
AccelStepper stepper(AccelStepper::FULL4WIRE, 17, 18, 15, 16);
//AccelStepper stepper(AccelStepper::HALF4WIRE, 15, 16, 17, 18); //-- в правильную сторону bowa + HALF4WIRE
//EEV PID (ПИД регулирование клапана EEV)
QuickPID EEV_PID(¤t_overheat, &eev_position, &overheat); //&Input, &Output, &Setpoint
//--------------- Инициализация BUTTON and Sensors ----------------
button sensor_coldside_circle(9); // указываем пин кнопки
button sensor_hotside_circle(10); // указываем пин кнопки
//------ Инициализация реле
RUN motor_tn(RELAY_PIN_1); //Компрессор теплового насоса
RUN motor_coldside(RELAY_PIN_2); //Мотор насос скважины
RUN motor_hotside(RELAY_PIN_3); //Мотор насос теплого пола
//--------------NEO Таймеры-----------------------
Neotimer timer_boot_reboot = Neotimer(boot_reboot_time * 1000); //Таймер первого запуска платы или ребута
Neotimer timer_motor_start = Neotimer(motor_start_time * 1000); // Пауза между запуском мотора скважины и мотора теплого пола
//Neotimer timer_compressor = Neotimer(timeout_start_compressor * 1000); //Пока не использую
Neotimer timer_motor_coldside = Neotimer(motor_coldside_time * 1000); //Ждем n... секунд старта протока
Neotimer timer_motor_hotside = Neotimer(motor_hotside_time * 1000); //Ждем n... секунд старта протока
//-------------обработчик ошибок--------------
//---------Описание ошибок в logger.h---------
logger logger(1);
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, TN5!");
Serial.printf("Arduino Stack was set to %d bytes", getArduinoLoopTaskStackSize());
// Print unused stack for the task that is running setup()
Serial.printf("\nSetup() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
//Гистезис целевой температуры
//pinMode(RELAY_PIN, OUTPUT); // пин реле
regulator.setpoint = temp_target_set; // Целевая температура
regulator.hysteresis = temp_target_hysteresis; // ширина гистерезиса
regulator.k = temp_target_feedback; // коэффициент обратной связи (подбирается по факту)
//regulator.dT = 500; // установить время итерации для getResultTimer
//PID SETUP
EEV_PID.SetTunings(eev_kp, eev_ki, eev_kd); // only set pid tunings, other pid modes are unchanged
//turn the PID on //включите PID
EEV_PID.SetMode(EEV_PID.Control::automatic); //// Set PID mode to manual, automatic or timer
EEV_PID.SetOutputLimits(66, 480); // Set and clamps the output to (0-255 by default)
EEV_PID.SetOutputSum(200); // sets the output summation value
//EEV_PID.SetControllerDirection(REVERSE);
//EEV_PID.SetControllerDirection(EEV_PID.Action::reverse);
//создаем задачу, которая будет выполняться на ядре 0 с максимальным приоритетом (1)
xTaskCreatePinnedToCore(
Fastcode, /* Функция задачи. */
"Task1", /* Ее имя. */
5000, /* Размер стека функции */
NULL, /* Параметры */
0, /* Приоритет */
&Task1, /* Дескриптор задачи для отслеживания */
0); /* Указываем пин для данного ядра */
delay(300);
//Создаем задачу, которая будет выполняться на ядре 1 с наивысшим приоритетом (1)
xTaskCreatePinnedToCore(
Slowcode, /* Функция задачи. */
"Task2", /* Имя задачи. */
5000, /* Размер стека */
NULL, /* Параметры задачи */
0, /* Приоритет */
&Task2, /* Дескриптор задачи для отслеживания */
1); /* Указываем пин для этой задачи */
delay(300);
//Задачка для логера
xTaskCreatePinnedToCore(
Logcode, /* Функция задачи. */
"LogTask", /* Имя задачи. */
5000, /* Размер стека */
NULL, /* Параметры задачи */
0, /* Приоритет */
&LogTask, /* Дескриптор задачи для отслеживания */
APP_CPU_NUM); /* Указываем пин для этой задачи */ //APP_CPU_NUM
delay(300);
//Задачка для eev
xTaskCreatePinnedToCore(
Eevcode, /* Функция задачи. */
"EevTask", /* Имя задачи. */
5000, /* Размер стека */
NULL, /* Параметры задачи */
0, /* Приоритет */
&EevTask, /* Дескриптор задачи для отслеживания */
APP_CPU_NUM); /* Указываем пин для этой задачи */ //APP_CPU_NUM
delay(300);
//Задачка для датчиков температуры
xTaskCreatePinnedToCore(
Tempcode, /* Функция задачи. */
"TempTask", /* Имя задачи. */
5000, /* Размер стека */
NULL, /* Параметры задачи */
0, /* Приоритет */
&TempTask, /* Дескриптор задачи для отслеживания */
APP_CPU_NUM); /* Указываем пин для этой задачи */ //APP_CPU_NUM
delay(300);
//Задачка для датчиков температуры
xTaskCreatePinnedToCore(
Pressurecode, /* Функция задачи. */
"PressureTask", /* Имя задачи. */
5000, /* Размер стека */
NULL, /* Параметры задачи */
0, /* Приоритет */
&PressureTask, /* Дескриптор задачи для отслеживания */
APP_CPU_NUM); /* Указываем пин для этой задачи */ //APP_CPU_NUM
delay(300);
//--------------------------TN Setup--------------------------
Serial.println("Boot TN");
//-------------Stepper-------------------
/*
Serial.print("Set Acceleration and MaxSpeed: 100:40 \n");
delay(1000);
stepper.setAcceleration(EEV_ACCELERATION); //Ускорение 100
stepper.setMaxSpeed(EEV_SPEED); //80 //было 40
Serial.print("set Zerro Position: 0 \n");
// int ttt = (-EEV_MAX_STEPS-40);
// Serial.println(ttt);
delay(1000);
stepper.runToNewPosition(-EEV_MAX_STEPS-40); //Закрыть полностью
//stepper.runToNewPosition(-40); //Закрыть полностью
stepper.setCurrentPosition(0);
Serial.print("set Position: 66 \n");
delay(3000);
stepper.runToNewPosition(EEV_MIN_STEPS); //открыть на минимальное значение шагов
stepper.disableOutputs();
*/
/*
Serial.print("set Position: 0 \n");
delay(3000);
//test в нулевую позицию
stepper.enableOutputs();
stepper.runToNewPosition(0);
delay (100);
stepper.disableOutputs();
Serial.print("set Position: 100 \n");
delay(3000);
stepper.enableOutputs();
stepper.runToNewPosition(100);
delay (100);
stepper.disableOutputs();
Serial.print("set Position: 50 \n");
delay(3000);
stepper.enableOutputs();
stepper.runToNewPosition(50);
delay (100);
stepper.disableOutputs();
Serial.print("set Position: 250 \n");
delay(3000);
stepper.enableOutputs();
stepper.runToNewPosition(250);
delay (100);
stepper.disableOutputs();
Serial.print("set Position: 0 \n");
delay(3000);
stepper.enableOutputs();
stepper.runToNewPosition(0);
delay (100);
stepper.disableOutputs();
*/
/* в лооп
//Motor set
stepper.enableOutputs();
stepper.runToNewPosition(st);
delay (100);
stepper.disableOutputs();
*/
///PIN
//pin_setup();
//Serial.println("Pin Setup OK");
//Ну и тут сервер и wifi
}
/* регулятор температуры с гистезисом */
void temp_regul(float current_temp) {
static uint32_t tmr;
if (millis() - tmr > 500) {
tmr = millis();
regulator.input = current_temp; //25 // сообщаем регулятору текущую температуру
//digitalWrite(RELAY_PIN, regulator.getResult()); // отправляем на реле (ОС работает по своему таймеру)
tn_pause = regulator.getResult(); // 0 пауза // 1 ТН включен //По умолчанию в момент включения включена пауза работы компрессора ТН
//Serial.print("SET RELAY: ");
//Serial.println(regulator.getResult()); // сост. реле
//Serial.print("PAUSE: ");
//Serial.println(tn_pause); // сост. реле
}
}
//https://www.xiron.ru/content/view/1700/28/
/* Вычисление перегрева фреона*/
//Режим определения перегрева // 1 - два датчика температуры, 2 - датчик давления и температуры, 3 - два датчика давления
float get_overheat(uint8_t eev_type, float value_in, float value_out){ //in - вход в теплообменник //out - выход из теплообменника
if(eev_type == 1){
//Serial.println("get_overheat_type_1:" + (String)(value_out - value_in));
return (value_out - value_in);
}
if(eev_type == 2){
isp_freon_temp_pressure_in = freon.PresstoTemp(low_pressure_value_in); //5.20 bar
isp_freon_temp_pressure_in = isp_freon_temp_pressure_in / 100;
Serial.println("isp_freon_temp_pressure_in:" + (String)(isp_freon_temp_pressure_in));
return (value_out - isp_freon_temp_pressure_in);
}
if(eev_type == 3){
isp_freon_temp_pressure_in = freon.PresstoTemp(low_pressure_value_in); //5.20 bar
isp_freon_temp_pressure_in = isp_freon_temp_pressure_in / 100;
Serial.println("isp_freon_temp_pressure_in:" + (String)(isp_freon_temp_pressure_in));
isp_freon_temp_pressure_out = freon.PresstoTemp(low_pressure_value_out); //5.20 bar
isp_freon_temp_pressure_out = isp_freon_temp_pressure_out / 100;
Serial.println("isp_freon_temp_pressure_out:" + (String)(isp_freon_temp_pressure_out));
return (isp_freon_temp_pressure_out - isp_freon_temp_pressure_in);
}
}
float logger_logic(){
if(low_pressure_value_in <= min_l_pressure){
Serial.println("ok add error:");
Serial.println("low_pressure_value_in:" + (String)(low_pressure_value_in));
Serial.println("min_l_pressure:" + (String)(min_l_pressure));
logger.add_error(4); //Нет минимального давления фреона
}
}
void Fastcode( void * pvParameters ){
Serial.print("Task1 Fastcode running on core ");
Serial.println(xPortGetCoreID());
for(;;){ //Аналог loop только на Core 0
//Serial.println("Fastcode 1000");
//Быстрый цикл
delay(1000);
// Print unused stack for the task that is running loop() - the same as for setup()
//Serial.printf("\nFastcode() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
//float temp = sensorRead(); //tn.h
//Serial.println(temp);
/*
if(start){ //Если ТН включен (общий старт)
if(!logger.find_error()){ // нет ошибок, запускаем ТН
// 0 - ручное, 1 - по температуре воздуха, 2 - по температуре подачи, 3 - по температуре обратки
if(work_mode == 0 && start_status == 0){ //ручное управление
if(boot_reboot){ // Проверка на первый пуск или перезапуск ТН, задержка включения
timer_boot_reboot.start();
if(timer_boot_reboot.done()){
boot_reboot = 0;
}
}
if(!boot_reboot){ //не первый запуск и не перезагрузка
//---------- Цикл включения ТН -------------------------
//--Проверить значение текущей и целевой тепрературы (а может это в другом блоке, не блок запуска, а блок проверки состояния)
motor_coldside.control(1); //Включить скважный насос
timer_motor_coldside.start(); //Включить таймер
if(timer_motor_coldside.done()){ //Через n... сукунд проверить проток
if (sensor_coldside_circle.click()){ //Проерка протока
coldside_circle_state = true; //Проток есть
}else{
logger.add_error(1); //Ошибка протока
}
}
timer_motor_start.start(); //Таймаут перед всключением насоса теплого пола
if(timer_boot_reboot.done()){
motor_hotside.control(1); //Включить скважный насос теплого пола
}
//timer_motor_coldside
//timer_motor_hotside
Serial.print("ruch ");
start_status = 1; //ТН запущен
}
}
if(work_mode == 1 && start_status == 0){ //по температуре воздуха
Serial.print("vozduh ");
start_status = 1; //ТН запущен
}
if(work_mode == 2 && start_status == 0){ //по температуре подачи
start_status = 1; //ТН запущен
}
if(work_mode == 3 && start_status == 0){ //по температуре обратки
start_status = 1; //ТН запущен
}
//Остановить ТН по температуре work_mode 1 2 3
}
}
*/
//tn_stop();
//tn_start();
/*
if(logger.find_error()){ //если есть критические ошибки - остановить ТН
//tn_stop();
start_status = 0; //ТН остановлен
}
*/
//if(!e1.find_error() && check_room_temp(20.00, 24.00)){ // нет ошибок, запускаем ТН
//if(!e1.find_error()){ // нет ошибок, запускаем ТН
// tn_start();
//start_status = 1; //ТН запущен
//}
//Запустить ТН в ручном режиме
}
}
void Slowcode( void * pvParameters ){
Serial.print("Task2 Slowcode running on core ");
Serial.println(xPortGetCoreID());
for(;;){ //Аналог loop только на Core 1
//Serial.println("Slowcode 1000");
//Цикл для обновления датчиков(температура, фреон, лог)
delay(1000);
// Print unused stack for the task that is running loop() - the same as for setup()
//Serial.printf("\nSlowcode() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
//Serial.println("");
//Один раз в секунду проверяем:
//current_overheat = 16.00;
//Температура обратки в скважину
//Максимальная температура компрессора
//Проток скважины
//Проток теплого пола
//Поиск ошибок
//logger_logic();
//Вывод ошибок в консоль
//logger.print_error();
}
}
void Logcode( void * pvParameters ){
Serial.print("Task Logcode running on core ");
Serial.println(xPortGetCoreID());
for(;;){ //Аналог loop только на Core 1
//Serial.println("Slowcode 1000");
//Цикл для обновления датчиков(температура, фреон, лог)
delay(1000);
// Print unused stack for the task that is running loop() - the same as for setup()
//Serial.printf("\nLogcode() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
//Serial.println("");
if(!eev_start){ //Ждем старта EEV, в это время не обновляем значаения дачиков
}
//Поиск ошибок
//logger_logic();
//Вывод ошибок в консоль
//logger.print_error();
//logger.find_error()
}
}
void Eevcode( void * pvParameters ){
Serial.print("Task Eevcode running on core ");
Serial.println(xPortGetCoreID());
for(;;){ //Аналог loop только на Core 1
//Serial.println("Slowcode 1000");
//Цикл для обновления датчиков(температура, фреон, лог)
delay(1000);
// Print unused stack for the task that is running loop() - the same as for setup()
//Serial.printf("\nEevcode() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
//Serial.println("");
if(!eev_start){ //первый старт eev при загрузке, найти нулевую позицию
Serial.print("Set Acceleration and MaxSpeed: 100:40 \n");
delay(5000);
stepper.setAcceleration(EEV_ACCELERATION); //Ускорение 100
stepper.setMaxSpeed(EEV_SPEED); //80 //было 40
Serial.print("set Zerro Position: 0 \n");
// int ttt = (-EEV_MAX_STEPS-40);
// Serial.println(ttt);
delay(500);
stepper.runToNewPosition(-EEV_MAX_STEPS);
delay(1000);
stepper.runToNewPosition(-40); //Закрыть полностью
delay(300);
stepper.setCurrentPosition(0);
Serial.print("set min Position: 66 \n");
delay(1000);
stepper.runToNewPosition(EEV_MIN_STEPS); //открыть на минимальное значение шагов
stepper.disableOutputs();
eev_start = 1;
}
//Serial.print("Search new EEV Position \n");
//Вычисляем позизию EEV
EEV_PID.Compute();
//Serial.printf("\nSearch new EEV Position: %d", eev_position);
//Serial.printf("\nTempcode() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
//Serial.println("");
Serial.print("Search new EEV Position:");
Serial.print(eev_position);
Serial.println("");
delay (300);
stepper.enableOutputs();
stepper.runToNewPosition(eev_position);
delay (200);
stepper.disableOutputs();
delay (200);
/*
Serial.print("Mode: ");
Serial.print(EEV_PID.GetMode()); //// manual (0), automatic (1) or timer (2)
Serial.println("");
Serial.print("Input: ");
Serial.print(current_overheat); //Текущее показаные перегрева
Serial.println("");
Serial.print("Output: ");
Serial.print(eev_position); //выход на eev
Serial.println("");
Serial.print("Setpoint: "); //Желамый перегрев
Serial.print(overheat);
Serial.println("");
*/
}
}
void Tempcode( void * pvParameters ){
Serial.print("Task Tempcode running on core ");
Serial.println(xPortGetCoreID());
for(;;){ //Аналог loop только на Core 1
//Serial.println("Slowcode 1000");
//Цикл для обновления датчиков(температура, фреон, лог)
delay(1000);
// Print unused stack for the task that is running loop() - the same as for setup()
//Serial.printf("\nTempcode() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
//Serial.println("");
if(!eev_start){ //Ждем старта EEV, в это время не обновляем значаения дачиков
//Температуру датчиков
temp1.UpdateTemp();
temp2.UpdateTemp();
current_temp = temp1.getRoom(20, 25); //min и max (пока не использую, тест)
/* регулировка температуры по гистезису */
temp_regul(current_temp); //Регулируем паузу ТН по гистезису
/*temp1*/
if(current_temp != old_current_temp){
old_current_temp = current_temp;
Serial.println("current_temp:" + (String)current_temp);
}
isp_water_temp_in = temp1.get_isp_water_in();
if(isp_water_temp_in != old_isp_water_temp_in){
old_isp_water_temp_in = isp_water_temp_in;
Serial.println("isp_water_temp_in:" + (String)isp_water_temp_in);
}
isp_water_temp_out = temp1.get_isp_water_out();
if(isp_water_temp_out != old_isp_water_temp_out){
old_isp_water_temp_out = isp_water_temp_out;
Serial.println("isp_water_temp_out:" + (String)isp_water_temp_out);
}
isp_freon_temp_in = temp1.get_isp_freon_in();
if(isp_freon_temp_in != old_isp_freon_temp_in){ //DS107 isp_in
old_isp_freon_temp_in = isp_freon_temp_in;
Serial.println("isp_freon_temp_in:" + (String)isp_freon_temp_in);
}
isp_freon_temp_out = temp1.get_isp_freon_out();
if(isp_freon_temp_out != old_isp_freon_temp_out){ //DS103 isp_out
old_isp_freon_temp_out = isp_freon_temp_out;
Serial.println("isp_freon_temp_out:" + (String)isp_freon_temp_out);
}
/*temp2*/
cond_water_temp_in = temp2.get_cond_water_in();
if(cond_water_temp_in != old_cond_water_temp_in){
old_cond_water_temp_in = cond_water_temp_in;
Serial.println("cond_water_temp_in:" + (String)cond_water_temp_in);
}
cond_water_temp_out = temp2.get_cond_water_out();
if(cond_water_temp_out != old_cond_water_temp_out){
old_cond_water_temp_out = cond_water_temp_out;
Serial.println("cond_water_temp_out:" + (String)cond_water_temp_out);
}
cond_freon_temp_in = temp2.get_cond_freon_in();
if(cond_freon_temp_in != old_cond_freon_temp_in){
old_cond_freon_temp_in = cond_freon_temp_in;
Serial.println("cond_freon_temp_in:" + (String)cond_freon_temp_in);
}
cond_freon_temp_out = temp2.get_cond_freon_out();
if(cond_freon_temp_out != old_cond_freon_temp_out){
old_cond_freon_temp_out = cond_freon_temp_out;
Serial.println("cond_freon_temp_out:" + (String)cond_freon_temp_out);
}
/* вычисление перегрева */
current_overheat = get_overheat(eev_type, isp_freon_temp_in, isp_freon_temp_out);
if(current_overheat != old_current_overheat){
old_current_overheat = current_overheat;
Serial.println("current_overheat SH:" + (String)current_overheat);
}
}
}
}
void Pressurecode( void * pvParameters ){
Serial.print("Task Pressurecode running on core ");
Serial.println(xPortGetCoreID());
for(;;){ //Аналог loop только на Core 1
//Serial.println("Slowcode 1000");
//Цикл для обновления датчиков(температура, фреон, лог)
delay(1000);
// Print unused stack for the task that is running loop() - the same as for setup()
//Serial.printf("\nPressurecode() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
//Serial.println("");
if(!eev_start){ //Ждем старта EEV, в это время не обновляем значаения дачиков
//Давление фреона
pressure_low.update_pressure(); //(обновить значение датчика)
pressure_high.update_pressure();
low_pressure_value_in = pressure_low.getPressure(); //Получить значение давления
if(low_pressure_value_in != old_low_pressure_value_in){
old_low_pressure_value_in = low_pressure_value_in;
Serial.println("low_pressure_value_in:" + (String)low_pressure_value_in);
}
high_pressure_value_in = pressure_high.getPressure(); //Получить значение давления
if(high_pressure_value_in != old_high_pressure_value_in){
old_high_pressure_value_in = high_pressure_value_in;
Serial.println("high_pressure_value_in:" + (String)high_pressure_value_in);
}
}
}
}
void loop() {
delay(5000); // this speeds up the simulation
//e1.log_error();
//e2.log_error();
//e3.log_error();
//e1.log_error_data();
//e2.log_error_data();
//e3.log_error_data();
//e4.log_error_data();
//Возможно это временное решение log start
if(start){
//Serial.println("LOG: TN GLOBAL RUN");
}else{
//Serial.println("LOG: TN GLOBAL STOP");
}
}
isp in
isp out