Контроллер пелетного котла

Smarodina
Offline
Зарегистрирован: 03.02.2018

Всем привет, меня зовут Дима, и я сварщик:) живу я в Украине, в городе Харьков. Когда то газ был дешевый и некого не парило отопление дома, но в 2008 он подорожал почти на 100% и я утеплил дом пенопластом, стало легче:) жил дальше... но пришел 2014 год и газ подорожал в 7 раз, что стало очень накладно с расходом 300-500 кубометров в месяц и я сварил себе котел на дровах шахтного типа. но через две зимы пришел к тому что дрова топливо хоть и дешевое но очень не стабильное... заинтересовался пеллетами и сделал "гравитационную" горелку, стало лучше. качество топлива стабильное, засыпал в бункер и нагрел теплоаккамулятор но напрягало что гравитационная горелка вредная к тяге в дымоходе и получалось что нужно 2-4 часа в день что бы нагреть ТА, и без присмотра её не оставить... и сделал свою первую факельную горелку, управление сделал на модулях из китая, выставил время подачи и паузы подкрутил вентилятор и работает:) но хотелось сделать "автоматику" которая была бы автоматической и знала что делать с нештатными ситуациями но знания мои в програмировании не позволяли... потом я сделал котел в мастерскую и тоже контроллер на модулях, но в мастерской ТА нет, и котел греет радиаторы на прямую. а хотелось чтоб он мог поддерживать заданную темературу и не палил лишнего, и конце 2019 года понеслось... напряг своих друзей кто понимал больше меня начать контроллер, что то получалось, как я думал, но к весне 2020 года я таки понял как надо сделать и теперь только "допиливаю" свое детище:) в общем вот:

#define PID_INTEGER
#define PID_INTEGRAL_WINDOW 50
#define BTN1 4
#define BTN2 5
#define BTN3 2
#define BTN4 3
#define BTN5 A0

#include <GyverPID.h>
#include <GyverButton.h>
#include <GyverTimer.h>
#include <GyverTM1637.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define CLK A4
#define DIO A5
#define ONE_WIRE_BUS 11

GyverTM1637 disp(CLK, DIO);
GyverPID pid(1, 0.05, 0.8, 10000);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer {0x28, 0xB8, 0x86, 0xD5, 0x33, 0x20, 0x01, 0xCA  };  //УКАЗАТЬ имя  датчика
////////////////////кнопки////////////////////////////////////////////
GButton startButtonPin(BTN1);            //пин кнопки Старт
GButton stopButtonPin(BTN2);             //пин кнопки Стоп
GButton plusButtonPin(BTN3);             //пин кнопки "+"
GButton minusButtonPin(BTN4);            //пин кнопки "-"
GButton disp_ButtonPin(BTN5);            //пин кнопки дисплея
////////////////////датчики///////////////////////////////////////////
const int photoresistorPin = 12;         //пин фоторезистора
const int infraredSensorPin = A3;        //пин ИК датчика
////////////////////иполнители////////////////////////////////////////
const int feederAugerPin = 6;            //пин шнека питателя
const int pumpPin = 7;                   //пин цикуляционного насоса
const int heatingElementPin = 8;         //пин зажигалки
const int stokerAugerPin = 9;            //пин шнека стокера
const int pwmPin = 10;                   //пин для ШИМ
const int firebarPin = 13;               //пин подвижного колосника 
////////////////////переменные///////////////////////////////////////
int desiredTemperature;
int currentTemp;
byte working;
byte start_count;
byte photoresistor;
int p_pause;
int w_pause;
byte start1;
int val_f;
int val[3];
int index;
byte starting;                                    
byte plusButton;
byte minusButton;
byte dispButton;
int dose;
byte displ;
signed char fan_value;
int PWM_val;
byte fanspeed_pr;
byte pid_out_last;
int switch_start;
int switch_stop;
int stop_FPB;
int startpwm;
int disp_on;
uint8_t start_1;
uint8_t stop_1;
int fire_off;  
int reg1;
  
GTimer start_timer0(MS);
GTimer start_timer1(MS);
GTimer start_timer2(MS);
GTimer start_timer3(MS);
GTimer stop_timer1(MS);
GTimer stop_timer2(MS);

int middle_of_3(int a, int b, int c) {
 int x[2];
if (a > b) {x[0] = b; x[1] = a;} 
else {x[0] = a; x[1] = b;} 
if (x[1] > c) {return (x[0]< c) ? c : x[0];} 
else {return x[1];} 
}

void setup() {
  start_1=0;
  stop_1=0;
  disp_on=1;
  switch_stop=9;
  switch_start=9;
  pid_out_last=100;
  PWM_val=0;
  displ=0;
  working=0;
  start1=0;
  start_count=0;
  desiredTemperature=500;
  stop_FPB=1;
  startpwm=0;
  fire_off=0;
  
  disp.clear();
  disp.brightness(0);  // яркость, 0 - 7 (минимум - максимум)
  
    startButtonPin.setTickMode(AUTO);
    stopButtonPin.setTickMode(AUTO);
    plusButtonPin.setTickMode(AUTO);
    minusButtonPin.setTickMode(AUTO);
    disp_ButtonPin.setTickMode(AUTO);
	
	  pinMode(photoresistorPin, INPUT);
    pinMode(infraredSensorPin, INPUT);
    pinMode(pumpPin, OUTPUT);
    pinMode(feederAugerPin, OUTPUT);
    pinMode(stokerAugerPin, OUTPUT);
    pinMode(pwmPin, OUTPUT);
    pinMode(heatingElementPin, OUTPUT);
    pinMode(firebarPin, OUTPUT);
    
    digitalWrite(feederAugerPin, HIGH);
    digitalWrite(stokerAugerPin, HIGH);
    digitalWrite(heatingElementPin, HIGH);
    digitalWrite(pumpPin, HIGH);
    digitalWrite(firebarPin, HIGH);
    
  pid.setDirection(NORMAL); 
  pid.setLimits(1,9);
  pid.setpoint = desiredTemperature; 
  sensors.begin();
  start_timer0.setTimeout(10000);//время продувки перед запуском горелки
  start_timer1.setTimeout(20000);//время загрузки пеллет на розжиг
  start_timer2.setTimeout(180000);//время работы зажигалки
  start_timer3.setTimeout(25000);//время стабилизации пламени
  stop_timer1.setTimeout(100000);//время дожига пеллет перед останокой горелки
  stop_timer2.setTimeout(300000);//время продувки перед останокой горелки
  //Serial.begin(9600);
}

void loop() {
  /*static uint32_t timer_ser;
  if(millis() - timer_ser >= 2000){
    timer_ser = millis();
    Serial.println(pid.output);
    Serial.println(reg1);
   } 
 */ 
  button();
  fillPillets();
  pid.input = currentTemp;
  pid.setpoint = desiredTemperature; 
  pid.getResultTimer();
  reg_limits();
  average_fire();
  temp();
  work();
  startWork();
  finishWork();
  auto_start();
  //fire_bar();
  startPWM();
  screen();
}

void reg_limits(){
  reg1=desiredTemperature-currentTemp;
  if(reg1>=40){
    pid.setLimits(1,9);
  }else if(reg1>=30){
    pid.setLimits(1,7);
  }else if(reg1>=20){
    pid.setLimits(1,5);
  }else if(reg1>=10){
    pid.setLimits(1,3);
  }
}

void fire_bar(){                                                                             //Функция таймера работы подвижного колосника
    static uint32_t oldMillis = millis();
    static uint32_t onOffTime=500000;
    uint32_t newMillis = millis();
    boolean firebar_On = digitalRead(firebarPin);
    
    if(newMillis-oldMillis>=onOffTime){
        oldMillis=millis();
        firebar_On=!firebar_On;
        onOffTime=5000+(300000*firebar_On);//!firebar_On для мосфета, firebar_On для реле управление по LOW.
        digitalWrite(firebarPin,firebar_On);
    }    
}

void temp(){                                                                         //Функция обработки сигнала датчика температуры
   static uint32_t temp_timer;
   sensors.requestTemperatures();
   if(millis()-temp_timer>1000){
   temp_timer=millis(); 
   currentTemp = sensors.getTempC(insideThermometer)*10;}
    }
 
void average_fire(){                                                                         //Функция обработки сигнала датчика огня   
 if (++index > 2) index = 0; 
  val[index] = analogRead(A3); 
  val_f = middle_of_3(val[0], val[1], val[2]);
 
 }

void startPWM() {                                                                            //функция управления ШИМ вентилятора
  static int fanspeed;
  if(startpwm==1){
  fan_value=constrain(fan_value,-30,30);
  fanspeed_pr = PWM_val+fan_value;
  fanspeed_pr = constrain(fanspeed_pr, 0, 100);
  fanspeed = map(fanspeed_pr, 0, 100, 0, 253);
  analogWrite(pwmPin, fanspeed);
  }
}

void button(){                                                                               //Функция обработки кнопок
  desiredTemperature = constrain(desiredTemperature, 300, 800);
  
  if(disp_ButtonPin.isClick()){
    displ+=1;
    if(displ >= 4)displ=0;
  }
  if(startButtonPin.isClick() and photoresistor==1){
    startpwm=1;
    switch_start=0;
    }
  if(stopButtonPin.isClick()){
    startpwm=1;
    stop_FPB=0;
	  working=0;
    start1=0;
    switch_stop=0;
    }
	if(currentTemp>=800 and working==1){
    startpwm=1;
    stop_FPB=0;
    working=0;
    start1=0;
	  switch_stop=0;
	  }
	if(currentTemp>=350){
	digitalWrite(pumpPin, LOW);}
	else{digitalWrite(pumpPin, HIGH);
	}
	if(currentTemp<50 and start_count>=3){
		digitalWrite(pumpPin, LOW);
	}
}

void auto_start(){                                                                           //Функция автостарта горелки при потере огня
 static uint32_t timer_fire;
  if(millis() - timer_fire >= 100){
    timer_fire = millis();
  if(val_f>1000 and start1==1){
    fire_off+=1;
    }
    else{fire_off=0;
    }
  }
  if(fire_off==600 and start1==1){
    start1=0;
      working=0;
      pid_out_last=100;
      switch_start=5;
  }
}

void screen(){                                                                               //функция вывода информации на дисплей
 static int for_disp;
 if(disp_on==1){
 switch (displ){
  //вывод температур, изменение заданной температуры
  case 0 :
    for_disp = desiredTemperature * 10;
      for_disp = for_disp + currentTemp/10;
      disp.displayInt(for_disp);                                                      
      disp.point(true);
    if(plusButtonPin.isClick()){
      desiredTemperature+=50;
      plusButtonPin.resetStates();
      }
    if(minusButtonPin.isClick()){
      desiredTemperature-=50;
      minusButtonPin.resetStates();
      }
    break;
  //вывод расхода грамм\час
  case 1 :
      disp.displayInt(dose);
      disp.point(false);
    break;
  //вывод скорости вентилятора в процентах с возможностью корректировки
  case 2 :
    disp.displayInt(fanspeed_pr);
    disp.displayByte(0, 0x71);
    disp.point(false);
    if(plusButtonPin.isClick() and fanspeed_pr<100){
      fan_value+=5;
      plusButtonPin.resetStates();
      }
    if(minusButtonPin.isClick()){
      fan_value-=5;
      minusButtonPin.resetStates();
      }
    break;
  //вывод уровня пламени 0-1000 или таймер если огня нет
  case 3 :
      if(val_f<1000){
      disp.displayInt(val_f);
      disp.point(false);
      }else{
        disp.displayInt(fire_off/10);
        disp.point(false);}
    break;
  }
 }
}
 
void fillPillets() {                                                                         //Функция подачи пеллет из бункера в стокер
    static uint32_t timer_photo;
  if(millis() - timer_photo >= 500){
    timer_photo = millis();
    photoresistor = digitalRead(photoresistorPin);
  }
  if(stop_FPB==1){
  if (photoresistor == 0) {
     digitalWrite(feederAugerPin, LOW);}
  else {
     digitalWrite(feederAugerPin, HIGH);}
  }
}

void startWork(){                                                                            //функция розжига
  switch(switch_start){
	   case 0:
      PWM_val=100;
      if(val_f<900){
    switch_start=4;}
		break;
	   
	   case 1:
	    PWM_val=20;
		  digitalWrite(stokerAugerPin, LOW);
      if(val_f<600){
    switch_start=2;}
		break;
	   
	   case 2:
	     digitalWrite(stokerAugerPin, HIGH);
	     switch_start=3;
		break;
	   
	   case 3:
	     PWM_val=90;
	     digitalWrite(heatingElementPin, LOW);
    break;
	   
	   case 4:
	     digitalWrite(heatingElementPin, HIGH);
	     p_pause=3750;
	     w_pause=200;
	     PWM_val=60;
       work_timer();
	  break;
		
	   case 5:
        digitalWrite(heatingElementPin, HIGH);
        start_count+=1;
		    	if(start_count<=3){
			    switch_start=0;}
				   else{
				    switch_start=9;
				    start1=0;
				    working=0;
				   }
		break;

	   case 6:
		    start1=1;
		    working=1;
		    switch_start=8;
		break;
    }

if(switch_start==0){
  if(start_timer0.isReady())switch_start=1;}else{start_timer0.start();}

if(switch_start==1){
  if(start_timer1.isReady())switch_start=2;}else{start_timer1.start();}

if(switch_start==3){
  if(val_f<750)switch_start=4;}

if(switch_start==3){
  if(start_timer2.isReady())switch_start=5;}else{start_timer2.start();}

if(switch_start==4){
  if(start_timer3.isReady())switch_start=6;}else{start_timer3.start();}
}

void work() {                                                                                //Функция выбора режима мощности работы горелки
  if (working == 1) { 
    start_count = 0;
    if (pid_out_last != pid.output){
  digitalWrite(stokerAugerPin,HIGH);
    switch (pid.output) {
    //p_pause=пауза подачи. w_pause=подача. PWM_val=вентилятор в процентах. dose=расход грамм\час.
	  case 0 :p_pause=10000;w_pause=100;PWM_val=35;dose = 180;break;
    case 1 :p_pause=8520;w_pause=100;PWM_val=40;dose = 210;break;
    case 2 :p_pause=7500;w_pause=100;PWM_val=45;dose = 240;break;
    case 3 :p_pause=6000;w_pause=100;PWM_val=50;dose = 300;break;
    case 4 :p_pause=5000;w_pause=100;PWM_val=60;dose = 360;break;
    case 5 :p_pause=4500;w_pause=100;PWM_val=65;dose = 400;break;
    case 6 :p_pause=3000;w_pause=155;PWM_val=75;dose = 850;break;
    case 7 :p_pause=3750;w_pause=200;PWM_val=80;dose = 1000;break; 
    case 8 :p_pause=3300;w_pause=200;PWM_val=90;dose = 1630;break;
    case 9 :p_pause=3000;w_pause=300;PWM_val=100;dose = 2000;break;            
    }
  }
  pid_out_last = pid.output;
  work_timer();
  }
}

void work_timer(){                                                                           //Функция таймер работы горелки
    static uint32_t oldMillis = millis();
    static uint16_t onOffTime;
    uint32_t newMillis = millis();
    boolean soker_On = digitalRead(stokerAugerPin);
    
    if(newMillis-oldMillis>=onOffTime){
        oldMillis=millis();
        soker_On=!soker_On;
        onOffTime=w_pause+((p_pause - w_pause)*soker_On);//!soker_On для мосфета, soker_On для реле управление по LOW.
        digitalWrite(stokerAugerPin,soker_On);
    }    
}

void finishWork(){                                                                           //Функция остановки работы горелки
  switch(switch_stop){
	 case 0:
	    disp_on=0;
	    stop_FPB=0;
		  p_pause=3000;
		  w_pause=250;
		  PWM_val=100;
		  disp.displayByte(0x6d, 0x78, 0x3f, 0x73);
		  disp.point(false);
		  work_timer();
   break;
	 
	 case 1:
      digitalWrite(stokerAugerPin, HIGH);
      stop_FPB=0;
	    PWM_val=100;
   break;
   
   case 2:
      disp_on=1;
      PWM_val=0;
      startpwm=0;
      stop_FPB=1;
      switch_stop=3;
   break;
	}
if(switch_stop==0){
    if(stop_timer1.isReady())
    switch_stop=1;}else{stop_timer1.start();}
if(switch_stop==1){
    if(stop_timer2.isReady()){
    PWM_val=0;
    switch_stop=2;}
    }else{stop_timer2.start();}
}

контроллеру нужно задать режимы работы в скетче, а затем он управляется при помощи четырех кнопок. пуск, стоп, плюс и минус температура. есть еще кнопка которая переключает дисплей, показывать температуру, расход пеллет, значение вентилятора (с возможностью коррекции), и значение датчика огня но то уже я делал для себя... основные это температура и вентилятор.

в планах сделать что бы режимы задавались не рукописно, а вводить контроллеру например вес некого объема пеллет и он относительно этого веса перещитывал режимы подачи и паузы. 

 

у меня есть канал на ютубе где я делаю это все https://www.youtube.com/channel/UCW6PoUoch5vHGwUPKVOn-cA

Smarodina
Offline
Зарегистрирован: 03.02.2018

сделал новую версию, теперь контроллер универсальный, настраивается из меню. задаются 3 основных параметра и контроллер на их основании расчитывает время подачи

#define PID_INTEGER
#define BTN1 A0             //пин кнопки Enter
#define BTN2 A1             //пин кнопки Exit
#define BTN3 A3             //пин кнопки "+"
#define BTN4 A2             //пин кнопки "-"

#include <AC_Dimmer.h>
#include <EEPROM.h>
#include <GyverPID.h>
#include <GyverButton.h>
#include <GyverTimer.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define Dimmer_1 0
#define ONE_WIRE_BUS 11                  //пин датчика ds18b20

LiquidCrystal_I2C lcd(0x27,20,4);        //пины А4 и А5
GyverPID pid(1.3, 0.01, 4.3, 30000);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer {0x28, 0x55, 0xA9, 0x2C, 0x33, 0x20, 0x01, 0xDC  };  //УКАЗАТЬ имя  датчика
////////////////////кнопки////////////////////////////////////////////
GButton enterButtonPin(BTN1);            //пин кнопки Enter
GButton exitButtonPin(BTN2);             //пин кнопки Exit
GButton plusButtonPin(BTN3);             //пин кнопки "+"
GButton minusButtonPin(BTN4);            //пин кнопки "-"
////////////////////датчики///////////////////////////////////////////
const int photoresistorPin = A6;         //пин фоторезистора
const int infraredSensorPin = A7 ;        //пин ИК датчика
////////////////////иполнители////////////////////////////////////////
const int feederAugerPin = 7;            //пин шнека питателя
const int pumpPin = 6;                   //пин цикуляционного насоса
const int heatingElementPin = 8;         //пин зажигалки
const int stokerAugerPin = 9;            //пин шнека стокера
const int firebarPin = 12;               //пин подвижного колосника 
////////////////////переменные///////////////////////////////////////

uint16_t currentTemp;
boolean working;
uint8_t start_count;
uint16_t w_pause;
boolean start1;
uint16_t val_f;
uint16_t val[3];
uint16_t index;
uint16_t val_foto;
uint16_t val_fot[3];
uint16_t index2;
uint8_t PWM_val;
uint8_t switch_start;
uint8_t switch_stop;
boolean startpwm;
uint16_t fire_off;  
uint32_t displ;
uint8_t fanspeed;
uint8_t cursor_;
uint8_t kwt;
boolean feeder_On;
boolean flag;
uint32_t counter;
boolean f_load;
boolean f_loading;
boolean f_m;
boolean f_work;
boolean stoker_On;

uint8_t min_power;
uint8_t max_power;
uint16_t desiredTemperature;
signed char fan_value;
uint8_t min_fan;
uint8_t max_fan;
float pr;
float kkal;
uint16_t p_pause;
bool pid_start;
uint32_t counter2;
uint8_t gramm;
uint32_t time_stabilize;
uint32_t time_blow;
uint16_t fire_Ok;
uint32_t time_stop;
uint32_t time_stop_blow;
uint32_t load_ms;
uint32_t load_counter;
uint32_t ms_g;
uint8_t percent;
  
GTimer start_timer0(MS);
GTimer start_timer2(MS);
GTimer start_timer3(MS);
GTimer stop_timer1(MS);
GTimer stop_timer2(MS);

int middle_of_3(int a, int b, int c) {
 int x[2];
if (a > b) {x[0] = b; x[1] = a;} 
else {x[0] = a; x[1] = b;} 
if (x[1] > c) {return (x[0]< c) ? c : x[0];} 
else {return x[1];} 
}

int middle_of_3_1(int a, int b, int c) {
 int x[2];
if (a > b) {x[0] = b; x[1] = a;} 
else {x[0] = a; x[1] = b;} 
if (x[1] > c) {return (x[0]< c) ? c : x[0];} 
else {return x[1];} 
}

void setup() {
  Dimmer_init_begin();
  Dimmer_pin_assign(Dimmer_1, 3);  
  Dimmer_init_end();
  int adc_read;

  val_f=1000;
  val_foto=1000;
  
/*
min_power = 1;
max_power = 15;
desiredTemperature = 500;
fan_value = 1;
min_fan = 30;
max_fan = 80;
pr = 10000;
kkal = 4.65;
p_pause = 15000;
pid_start = 1;
counter2 = 0;
gramm = 150;
time_stabilize = 300000;
time_blow = 30000;
fire_Ok = 700;
*/

  percent=0;
  load_ms=0;
  ms_g=0;
  stoker_On=0;
  feeder_On=0;
  load_counter=0;
  f_work=0;
  f_loading=0;
  f_load=0;
  cursor_=0;
  switch_stop=9;
  switch_start=9;
  working=0;
  start1=0;
  start_count=0;
  startpwm=0;
  fire_off=0;
  displ=0;
///*
  EEPROM.get(20, min_power);
  EEPROM.get(22, max_power);
  EEPROM.get(24, desiredTemperature);
  EEPROM.get(28, fan_value);
  EEPROM.get(32, min_fan);
  EEPROM.get(34, max_fan);
  EEPROM.get(36, pr);
  EEPROM.get(40, kkal);
  EEPROM.get(46, p_pause);
  EEPROM.get(48, pid_start);
  EEPROM.get(50, counter2);
  EEPROM.get(56, gramm);
  EEPROM.get(58, time_stabilize);
  EEPROM.get(64, time_blow);
  EEPROM.get(70, fire_Ok);
  EEPROM.get(74, time_stop);
  EEPROM.get(80, time_stop_blow);
  
//*/  

  
   lcd.init();                      // initialize the lcd 
   lcd.backlight();
   lcd.clear();
    
    enterButtonPin.setTickMode(AUTO);
    exitButtonPin.setTickMode(AUTO);
    plusButtonPin.setTickMode(AUTO);
    minusButtonPin.setTickMode(AUTO);
	
	  pinMode(photoresistorPin, INPUT);
    pinMode(infraredSensorPin, INPUT);
    pinMode(pumpPin, OUTPUT);
    pinMode(feederAugerPin, OUTPUT);
    pinMode(stokerAugerPin, OUTPUT);
    pinMode(heatingElementPin, OUTPUT);
    pinMode(firebarPin, OUTPUT);
    
    digitalWrite(feederAugerPin, HIGH);
    digitalWrite(stokerAugerPin, HIGH);
    digitalWrite(heatingElementPin, HIGH);
    digitalWrite(pumpPin, HIGH);
    digitalWrite(firebarPin, HIGH);
    
  pid.setMode(ON_RATE);
  pid.setDirection(NORMAL);
  pid.setLimits(min_power,max_power);
  pid.setpoint = desiredTemperature; 
  sensors.begin();
  start_timer0.setTimeout(time_blow);//время продувки перед запуском горелки
  start_timer2.setTimeout(300000);//время работы зажигалки
  start_timer3.setTimeout(time_stabilize);//время стабилизации пламени
  stop_timer1.setTimeout(time_stop);//время дожига пеллет перед останокой горелки
  stop_timer2.setTimeout(time_stop_blow);//время продувки перед останокой горелки
 }

void loop() {
  menu();
  rgs();
  startPWM();
  //average_fire();
  temp();
  pump();
  pidstart();
  startWork();
  finishWork();
  auto_start();
  fire_bar();
  eeprom();
}

void rgs(){                                                                                  //функция счета пеллеты
  ms_g = 3600000/pr;
  if(feeder_On==0)flag=1;
  if(feeder_On==1 and flag==1){
    counter2+=w_pause;
    flag=0;
  }
  counter=counter2/ms_g;
  load_ms=gramm*ms_g; 

  percent=load_counter/(load_ms/100);
  
 if(switch_start==1){
  if(feeder_On==0)f_load=1;
   if(feeder_On==1 and f_load==1){
    switch_start=1;
    load_counter+=w_pause;
    f_load=0;
  }
     if(load_counter>=load_ms)f_loading=0;
 }
}

void eeprom(){                                                                               //функция обработки EEPROM памяти
  min_power=constrain(min_power,0,max_power);
  max_power=constrain(max_power,min_power,100);

  w_pause =(((kwt/kkal)*1000)/(pr/3600000))/((3600000-((kwt/kkal)*1000)/(pr/3600000))/p_pause);

  EEPROM.put(20, min_power);
  EEPROM.put(22, max_power);
  EEPROM.put(24, desiredTemperature);
  EEPROM.put(28, fan_value);
  EEPROM.put(32, min_fan);
  EEPROM.put(34, max_fan);
  EEPROM.put(36, pr);
  EEPROM.put(40, kkal);
  EEPROM.put(46, p_pause);
  EEPROM.put(48, pid_start);
  EEPROM.put(50, counter2);
  EEPROM.put(56, gramm);
  EEPROM.put(58, time_stabilize);
  EEPROM.put(64, time_blow);
  EEPROM.put(70, fire_Ok);
  EEPROM.put(74, time_stop);
  EEPROM.put(80, time_stop_blow);
}

void pidstart(){                                                                             //функция запуска ПИД регулятора
  //if(working==1){
  pid.input = currentTemp;
  pid.setpoint = desiredTemperature; 
  pid.setLimits(min_power,max_power);
  if(pid_start==1 and working==1){
  pid.getResultTimer();
  kwt=pid.output;//}
  digitalWrite(heatingElementPin, HIGH);
  work_timer();
  work_timer2();
  }
}

void fire_bar(){                                                                             //Функция таймера работы подвижного колосника
    static uint32_t oldMillis = millis();
    static uint32_t onOffTime=500000;
    uint32_t newMillis = millis();
    boolean firebar_On = digitalRead(firebarPin);
    
    if(newMillis-oldMillis>=onOffTime){
        oldMillis=millis();
        firebar_On=!firebar_On;
        onOffTime=5000+(300000*firebar_On);//!firebar_On для мосфета, firebar_On для реле управление по LOW.
        digitalWrite(firebarPin,firebar_On);
    }    
}

void temp(){                                                                                 //Функция обработки сигнала датчика температуры
   static uint32_t temp_timer;
   static bool flag=0;
   
   if(millis()-temp_timer>1000){
   temp_timer=millis();
   lcd.clear();
   flag=!flag;
   if(flag=0){
   //sensors.requestTemperatures();
   }else{
    //currentTemp = sensors.getTempC(insideThermometer)*10;
   }
   
   }
}
 
void average_fire(){                                                                         //Функция обработки сигнала датчика огня   
   if (++index > 2) index = 0; 
   val[index] = analogRead(A7); 
   val_f = middle_of_3(val[0], val[1], val[2]);
   if (++index2 > 2) index2 = 0; 
   val_fot[index2] = analogRead(A6); 
   val_foto = middle_of_3_1(val_fot[0], val_fot[1], val_fot[2]);
}

void startPWM() {                                                                            //функция управления ШИМ вентилятора 
   static int fann;
   if(startpwm==1){
   fan_value=constrain(fan_value,-20,20);
   if(working==1){
   fanspeed = PWM_val+fan_value;
   }else{fanspeed=PWM_val;}
   
   if(working==1){
    fanspeed=map(kwt,min_power,max_power,min_fan,max_fan);
    fanspeed = constrain(fanspeed, min_fan, max_fan);
   }
   
   fann = map(fanspeed, 0, 100, 0, 250);
   
   //////////////////////////
   Dimm_value(Dimmer_1,fann);
   //////////////////////////
   }  
}

void pump(){                                                                                 //функция включения циркуляционного насоса
   if(currentTemp>=350){
    digitalWrite(pumpPin, LOW);}
     else{digitalWrite(pumpPin, HIGH);
  }
   if(currentTemp<50 and start_count>=3)digitalWrite(pumpPin, LOW);
}

void main_screen(){                                                                          //функция обработки главного экрана
 
      lcd.setCursor(0, 0);
      lcd.print("Ty.");
      lcd.setCursor(4, 0);
      lcd.print(desiredTemperature/10);
      lcd.setCursor(6, 0);
      lcd.print("C");
      
      lcd.setCursor(0, 1);
      lcd.print("Tk.");
      lcd.setCursor(4, 1);
      lcd.print(currentTemp/10);
      lcd.setCursor(6, 1);
      lcd.print("C");
      
      lcd.setCursor(0, 2);
      lcd.print("kWt");
      lcd.setCursor(4, 2);
      lcd.print(kwt);

      lcd.setCursor(0, 3);
      lcd.print("Fan");
      lcd.setCursor(4, 3);
      lcd.print(fanspeed);
      if(fanspeed<10){
      lcd.setCursor(5, 3);
      lcd.print("%");  
      }else if(fanspeed<100){
        lcd.setCursor(6, 3);
      lcd.print("%");
      }else if(fanspeed>99){
        lcd.setCursor(7, 3);
      lcd.print("%");
      }
     
      lcd.setCursor(16, 0);
      lcd.print("Fire");
      lcd.setCursor(16, 1);
      lcd.print("Fire");
      lcd.setCursor(12, 0);
      lcd.print(val_f);
      lcd.setCursor(12, 1);
      lcd.print(val_foto);

      if(working==1){
      lcd.setCursor(8, 2);
      lcd.print(F("W.pause"));
      lcd.setCursor(15, 2);
      lcd.print(w_pause);
      lcd.setCursor(8, 3);
      lcd.print(F("P.pause"));
      lcd.setCursor(15, 3);
      lcd.print(p_pause);
      }
      if(displ==0)cursor_=0;  
}

void menu(){                                                                                 //функция обработки меню
  desiredTemperature = constrain(desiredTemperature, 400, 800);
  //////////////////////////////////////////////////////////////////////////////////////////
  if(displ==0 and enterButtonPin.isHold()){startpwm=1;switch_start=0;}
  if(displ==0 and exitButtonPin.isHold()){startpwm=1;working=0;start1=0;switch_stop=0;}
  //////////////////////////////////////////////////////////////////////////////////////////
 if(f_work==0){
 if(pid_start==1){
  if(displ==0 and plusButtonPin.isClick())desiredTemperature+=10;
  if(displ==0 and minusButtonPin.isClick())desiredTemperature-=10;
  if(displ==0 and plusButtonPin.isHold())desiredTemperature+=10;
  if(displ==0 and minusButtonPin.isHold())desiredTemperature-=10;
 }else{
  if(displ==0 and plusButtonPin.isClick())kwt+=1;
  if(displ==0 and minusButtonPin.isClick())kwt-=1;
  if(displ==0 and plusButtonPin.isHold())kwt+=1;
  if(displ==0 and minusButtonPin.isHold())kwt-=1;
 }
  //////////////////////////////////////////////////////////////////////////////////////////
      if(displ==0)main_screen();
      if(displ==0 and enterButtonPin.isClick())displ+=10;
      if(displ>0 and exitButtonPin.isDouble())displ=0;
      if(displ!=0 and enterButtonPin.isClick())displ*=10;
      if(displ!=0 and exitButtonPin.isClick())displ/=10;
      if(displ!=0 and f_m==0 and minusButtonPin.isPress())displ+=1;
      if(displ!=0 and f_m==0 and plusButtonPin.isPress())displ-=1;
      if(displ!=0){cursor_ = constrain(cursor_, 0, 3);lcd.setCursor(0,cursor_);lcd.print(">");}
 }
  ///////////////////////////////////////////////////////////////////////////////////////////
      if(displ>=10 and displ<=13){                                                    //menu
         lcd.setCursor(1,0);
         lcd.print(F("Setings"));
         lcd.setCursor(1,1);
         lcd.print(F("setting burner"));
         lcd.setCursor(1,2);
         lcd.print(F("setting power"));
         lcd.setCursor(1,3);
         lcd.print(F("Count pellet"));
         lcd.setCursor(14,3);
         lcd.print(counter/1000);
         lcd.setCursor(18,3);
         lcd.print(F("KG"));
         if(displ==13 and plusButtonPin.isHold())counter2=0;
         cursor_=displ-10;
         displ=constrain(displ,10,13);
      }
      if(displ>=100 and displ<=103){                                                  //setings
        lcd.setCursor(1,0);
         lcd.print(F("set start"));
         lcd.setCursor(1,1);
         lcd.print(F("set stop"));
         lcd.setCursor(1,2);
         lcd.print(F("set fan"));
         lcd.setCursor(1,3);
         lcd.print(F("set PID"));
         cursor_=displ-100;
       }
      if(displ>=1000 and displ<=1003 or displ>=10000 and displ <=10030){              //set_start
         set_start();
         lcd.setCursor(1,0);
         lcd.print(F("time blow sec"));
         lcd.setCursor(16,0);
         lcd.print(time_blow/1000);
         lcd.setCursor(1,1);
         lcd.print(F("fire Ok"));
         lcd.setCursor(16,1);
         lcd.print(fire_Ok);
         lcd.setCursor(1,2);
         lcd.print(F("load gramm"));
         lcd.setCursor(15,2);
         lcd.print(gramm);
         lcd.setCursor(18,2);
         lcd.print(F("g"));
         lcd.setCursor(1,3);
         lcd.print(F("time stab sec"));
         lcd.setCursor(16,3);
         lcd.print(time_stabilize/1000);
         cursor_=displ-1000;
         
       }
      if(displ>=1010 and displ<=1013 or displ>=10100 and displ <=10130){              //set stop
        set_stop();
        lcd.setCursor(1,0);
         lcd.print(F("time stop sec"));
         lcd.setCursor(16,0);
         lcd.print(time_stop/1000);
         lcd.setCursor(1,1);
         lcd.print(F("time sblow sec"));
         lcd.setCursor(16,1);
         lcd.print(time_stop_blow/1000);
         cursor_=displ-1010;
      }
      if(displ>=1020 and displ<=1023 or displ>=10200 and displ <=10230){              //set fan
         set_fan();
         lcd.setCursor(3,0);
         lcd.print(F("Settingis fan"));
         lcd.setCursor(1,1);
         lcd.print(F("min power fan"));
         lcd.setCursor(17,1);
         lcd.print(min_fan);
         lcd.setCursor(1,2);
         lcd.print(F("max power fan"));
         lcd.setCursor(17,2);
         lcd.print(max_fan);
         lcd.setCursor(1,3);
         lcd.print(F("correction fan"));
         lcd.setCursor(17,3);
         lcd.print(fan_value);
         cursor_=displ-1020;
         }
      if(displ>=1030 and displ<=1033 or displ>=10300 and displ <=10330){              //set pid
        set_pid();
        lcd.setCursor(1,0);
        lcd.print(F("set work PID"));
         if(pid_start==1){lcd.setCursor(15,0); lcd.print(F("ON"));}
         else{lcd.setCursor(15,0); lcd.print(F("OFF"));}
        lcd.setCursor(1,1);
        lcd.print(F("set pid.Kp"));
        lcd.setCursor(15,1);
        lcd.print(pid.Kp);
        lcd.setCursor(1,2);
        lcd.print(F("set pid.Ki"));
        lcd.setCursor(15,2);
        lcd.print(pid.Ki);
        lcd.setCursor(1,3);
        lcd.print(F("set pid.Kd"));
        lcd.setCursor(15,3);
        lcd.print(pid.Kd);
        cursor_=displ-1030;
        }
      if(displ>=110 and displ<=113 or displ>=1100 and displ<=1130){                   //set burner
        set_gor();
        lcd.setCursor(1,0);
        lcd.print(F("TEST performans"));
        lcd.setCursor(1,1);
        lcd.print(F("set Kkal"));                                            //качество пеллет
        lcd.setCursor(11,1);
        lcd.print(kkal*1000);   
        lcd.setCursor(1,2);
        lcd.print(F("set pause"));                                           //пауза между подачами
        lcd.setCursor(11,2);
        lcd.print(p_pause);
        lcd.setCursor(1,3);                                                
        lcd.print(F("set perfo"));                                            //производительность шнека грамм\час
        lcd.setCursor(11,3);
        lcd.print(pr);
        cursor_=displ-110;
        }
      if(displ>=120 and displ<=123 or displ>=1200 and displ<=1230){                   //set min/max power
        set_pow();
        lcd.setCursor(1,0);
        lcd.print(F("set Power"));
        lcd.setCursor(1,1);
        lcd.print(F("Max power Kwt"));
        lcd.setCursor(15,1);
        lcd.print(max_power);
        lcd.setCursor(1,2);
        lcd.print(F("Min power Kwt"));
        lcd.setCursor(15,2);
        lcd.print(min_power);
        cursor_=displ-120;
        }
}

void set_start(){                                                                            //функция настройки старта 
   if(displ==10000 and exitButtonPin.isHold())time_blow=0;
   if(displ==10000 and plusButtonPin.isClick())time_blow+=1000;
   if(displ==10000 and plusButtonPin.isHold())time_blow+=1000;
   if(displ==10000 and minusButtonPin.isClick())time_blow-=1000;
   if(displ==10000 and minusButtonPin.isHold())time_blow-=1000;
   if(displ==10000){lcd.setCursor(19,0);lcd.print("<");}
   if(displ==10010 and exitButtonPin.isHold())fire_Ok=0;
   if(displ==10010 and plusButtonPin.isClick())fire_Ok+=10;
   if(displ==10010 and plusButtonPin.isHold())fire_Ok+=10;
   if(displ==10010 and minusButtonPin.isClick())fire_Ok-=10;
   if(displ==10010 and minusButtonPin.isHold())fire_Ok-=10;
   if(displ==10010){lcd.setCursor(19,1);lcd.print("<");}
   if(displ==10020 and exitButtonPin.isHold())gramm=0;
   if(displ==10020 and plusButtonPin.isClick())gramm+=10;
   if(displ==10020 and minusButtonPin.isClick())gramm-=10;
   if(displ==10020 and plusButtonPin.isHold())gramm+=10;
   if(displ==10020 and minusButtonPin.isHold())gramm-=10;
   if(displ==10020){lcd.setCursor(19,2);lcd.print("<");}
   if(displ==10030 and exitButtonPin.isHold())time_stabilize=0;
   if(displ==10030 and plusButtonPin.isClick())time_stabilize+=1000;
   if(displ==10030 and plusButtonPin.isHold())time_stabilize+=1000;
   if(displ==10030 and minusButtonPin.isClick())time_stabilize-=1000;
   if(displ==10030 and minusButtonPin.isHold())time_stabilize-=1000;
   if(displ==10030){lcd.setCursor(19,3);lcd.print("<");}
   if(displ>=10000 and displ<=10030){f_m=1;}else{f_m=0;}
}

void set_stop(){                                                                             //функция настройки остановки
   if(displ==10100 and exitButtonPin.isClick())time_stop=0;
   if(displ==10100 and plusButtonPin.isClick())time_stop+=1000;
   if(displ==10100 and plusButtonPin.isHold())time_stop+=1000;
   if(displ==10100 and minusButtonPin.isClick())time_stop-=1000;
   if(displ==10100 and minusButtonPin.isHold())time_stop-=1000;
   if(displ==10100){lcd.setCursor(19,0);lcd.print("<");}
   if(displ==10110 and exitButtonPin.isClick())time_stop_blow=0;
   if(displ==10110 and plusButtonPin.isClick())time_stop_blow+=1000;
   if(displ==10110 and plusButtonPin.isHold())time_stop_blow+=1000;
   if(displ==10110 and minusButtonPin.isClick())time_stop_blow-=1000;
   if(displ==10110 and minusButtonPin.isHold())time_stop_blow-=1000;
   if(displ==10110){lcd.setCursor(19,1);lcd.print("<");}
   if(displ>=10100 and displ<=10110){f_m=1;}else{f_m=0;}
}

void set_fan(){                                                                              //функция настройки вентилятора
   if(displ==10210 and exitButtonPin.isHold())min_fan=0;
   if(displ==10210 and plusButtonPin.isClick())min_fan+=1;
   if(displ==10210 and plusButtonPin.isHold())min_fan+=1;
   if(displ==10210 and minusButtonPin.isClick())min_fan-=1;
   if(displ==10210 and minusButtonPin.isHold())min_fan-=1;
   if(displ==10210){lcd.setCursor(19,1);lcd.print("<");}
   if(displ==10220 and exitButtonPin.isHold())max_fan=0;
   if(displ==10220 and plusButtonPin.isClick())max_fan+=1;
   if(displ==10220 and plusButtonPin.isHold())max_fan+=1;
   if(displ==10220 and minusButtonPin.isClick())max_fan-=1;
   if(displ==10220 and minusButtonPin.isHold())max_fan-=1;
   if(displ==10220){lcd.setCursor(19,2);lcd.print("<");}
   if(displ==10230 and exitButtonPin.isHold())fan_value=0;
   if(displ==10230 and plusButtonPin.isClick())fan_value+=1;
   if(displ==10230 and plusButtonPin.isHold())fan_value+=1;
   if(displ==10230 and minusButtonPin.isClick())fan_value-=1;
   if(displ==10230 and minusButtonPin.isHold())fan_value-=1;
   if(displ==10230){lcd.setCursor(19,3);lcd.print("<");}
   if(displ>=10210 and displ<=10230){f_m=1;}else{f_m=0;}
}
   
void set_gor(){                                                                              //функция настройки параметров работы горелки
  if(displ==1100){
    lcd.setCursor(19,0);
    lcd.print("<");
  }
  if(displ==1100 and enterButtonPin.isHolded()){
    digitalWrite(feederAugerPin,LOW);
    displ= 1131;
    lcd.clear();
    delay(100);
    lcd.setCursor(3,0);
    lcd.print(F("Runing test!"));
    lcd.setCursor(3,1);
    lcd.print(F("Wait 10sec!"));
    delay(10000);
    digitalWrite(feederAugerPin,HIGH);
    displ=1100;}
   
   if(displ==1110 and exitButtonPin.isHold())kkal=0;
   if(displ==1110 and plusButtonPin.isClick())kkal+=0.05;
   if(displ==1110 and plusButtonPin.isHold())kkal+=1;
   if(displ==1110 and minusButtonPin.isClick())kkal-=0.05;
   if(displ==1110 and minusButtonPin.isHold())kkal-=1;
   if(displ==1110){lcd.setCursor(19,1);lcd.print("<");}
   if(displ==1120 and exitButtonPin.isHold())p_pause=0;
   if(displ==1120 and plusButtonPin.isClick())p_pause+=100;
   if(displ==1120 and plusButtonPin.isHold())p_pause+=1000;
   if(displ==1120 and minusButtonPin.isClick())p_pause-=100;
   if(displ==1120 and minusButtonPin.isHold())p_pause-=1000;
   if(displ==1120){lcd.setCursor(19,2);lcd.print("<");}
   if(displ==1130 and exitButtonPin.isHold())pr=0;
   if(displ==1130 and plusButtonPin.isClick())pr+=50;
   if(displ==1130 and plusButtonPin.isHold())pr+=1000;
   if(displ==1130 and minusButtonPin.isClick())pr-=50;
   if(displ==1130 and minusButtonPin.isHold())pr-=1000;
   if(displ==1130){lcd.setCursor(19,3);lcd.print("<");}
   if(displ>=1110 and displ<=1130){f_m=1;}else{f_m=0;}

}

void set_pid(){                                                                              //функция настройки ПИД регулятора
   if(displ==10300 and plusButtonPin.isClick())pid_start=1;
   if(displ==10300 and minusButtonPin.isClick())pid_start=0;
   if(displ==10300){lcd.setCursor(19,0);lcd.print(F("<"));}
   if(displ==10310 and plusButtonPin.isClick())pid.Kp=+0.1;
   if(displ==10310 and minusButtonPin.isClick())pid.Kp-=0.1;
   if(displ==10310){lcd.setCursor(19,1);lcd.print(F("<"));}
   if(displ==10320 and plusButtonPin.isClick())pid.Ki=+0.01;
   if(displ==10320 and minusButtonPin.isClick())pid.Ki-=0.01;
   if(displ==10320){lcd.setCursor(19,2);lcd.print(F("<"));}
   if(displ==10330 and plusButtonPin.isClick())pid.Kd=+0.1;
   if(displ==10330 and minusButtonPin.isClick())pid.Kd-=0.1;
   if(displ==10330){lcd.setCursor(19,3);lcd.print(F("<"));}
   if(displ>=10300 and displ<=10330){f_m=1;}else{f_m=0;}
}

void set_pow(){                                                                              //функция настройки ограничения мощности
   if(displ==1210 and plusButtonPin.isClick())max_power+=1;
   if(displ==1210 and minusButtonPin.isClick())max_power-=1;
   if(displ==1210 and plusButtonPin.isHold())max_power+=1;
   if(displ==1210 and minusButtonPin.isHold())max_power-=1;
   if(displ==1210){lcd.setCursor(19,1);lcd.print("<");}
   if(displ==1220 and plusButtonPin.isClick())min_power+=1;
   if(displ==1220 and minusButtonPin.isClick())min_power-=1;
   if(displ==1220 and plusButtonPin.isHold())min_power+=1;
   if(displ==1220 and minusButtonPin.isHold())min_power-=1;
   if(displ==1220){lcd.setCursor(19,2);lcd.print("<");}
   if(displ>=1210 and displ<=1220){f_m=1;}else{f_m=0;}
}

void auto_start(){                                                                           //Функция автостарта горелки при потере огня
    static uint32_t timer_fire;
    static int time_no_fire;

  if (kwt==1 or kwt==2 or kwt==3 or kwt==4 or kwt==5){
   time_no_fire = 1400;}
     else{time_no_fire = 600;}
  if(millis() - timer_fire >= 100){
    timer_fire = millis();
  
  if((val_f>1000) and start1==1){
    fire_off+=1;
    }
    else{
      fire_off=0;
    }
  }
  if(fire_off==time_no_fire and start1==1){
      start1=0;
      working=0;
      switch_start=5;
  }
}

void startWork(){                                                                            //функция розжига
  static uint32_t timer_start;
  static uint8_t tt1=time_blow/1000;
  static uint16_t tt3=300;
  static uint8_t tt4=time_stabilize/1000;
  switch(switch_start){
	   case 0:
      PWM_val=99;
      if(millis() - timer_start >= 1000){
      timer_start = millis();
      tt1-=1;
      }
      if(displ==0){
      lcd.setCursor(14, 2);
      lcd.print(tt1);
      lcd.setCursor(17, 2);
      lcd.print(F("sec"));
      lcd.setCursor(9, 2);
      lcd.print(F("mode:"));
      lcd.setCursor(9, 3);
      lcd.print(F("Blow..."));}
     break;
	   
	   case 1:
	    PWM_val=50;
      if(displ==0){
      lcd.setCursor(9, 2);
      lcd.print(F("mode:"));
      lcd.setCursor(17, 3);
      lcd.print(percent);
      lcd.setCursor(19, 3);
      lcd.print("%");
      lcd.setCursor(9, 3);
      lcd.print(F("Loading"));
      }
      digitalWrite(heatingElementPin, LOW);
      kwt=15;
      if(f_loading==1){
        work_timer();
        work_timer2();
      }
      
      
    break;
	   
	   case 2:
	     digitalWrite(stokerAugerPin, HIGH);
       digitalWrite(feederAugerPin, HIGH);
       switch_start=3;
		break;
	   
	   case 3:
	     PWM_val=60;
       if(millis() - timer_start >= 1000){
       timer_start = millis();
       tt3-=1;
       }
       if(displ==0){
       lcd.setCursor(14, 2);
       lcd.print(tt3);
       lcd.setCursor(17, 2);
       lcd.print(F("sec"));
	     lcd.setCursor(9, 2);
       lcd.print(F("mode:"));
	     lcd.setCursor(9, 3);
       lcd.print(F("Heating..."));}
       //digitalWrite(heatingElementPin, LOW);
    break;
	   
	   case 4:
	     digitalWrite(heatingElementPin, HIGH);
	     startpwm=1;
	     if(millis() - timer_start >= 1000){
       timer_start = millis();
       tt4-=1;
       }
       if(displ==0){
       lcd.setCursor(14, 2);
       lcd.print(tt4);
       lcd.setCursor(17, 2);
       lcd.print(F("sec"));
       lcd.setCursor(9, 2);
       lcd.print(F("mode:"));
       lcd.setCursor(9, 3);
       lcd.print(F("Stabilize.."));}
	     kwt=4;
       work_timer();
       work_timer2();
       
  	  break;
		
	   case 5:
        digitalWrite(heatingElementPin, HIGH);
        start_count+=1;
		    	if(start_count<=3){
			    switch_start=0;}
				   else{
				    switch_start=9;
				    start1=0;
				    working=0;
            tt1=time_blow/1000;
            tt3=300;
            tt4=time_stabilize/1000;
				   }
		break;

	   case 6:
		    digitalWrite(heatingElementPin, HIGH);
		    start1=1;
		    working=1;
        tt1=time_blow/1000;
        tt3=300;
        tt4=time_stabilize/1000;
		    switch_start=8;
		break;
    }

if(switch_start==0){
  if(val_f<900 or val_foto<900)switch_start=6;
  if(start_timer0.isReady()){
    switch_start=1;
    f_loading=1;
  }
 }else{start_timer0.start();}

if(switch_start==1){
  if(val_f<900 or val_foto<900)switch_start=6;
  if(f_loading==0)switch_start=2;
}
if(switch_start==3){
  if(val_f<fire_Ok or val_foto<fire_Ok)switch_start=4;
  if(start_timer2.isReady())switch_start=5;
 }else{start_timer2.start();}

if(switch_start==4){
  if(start_timer3.isReady())switch_start=6;
 }else{start_timer3.start();}
}

void work_timer(){                                                                           //Функция таймер работы горелки
    static uint32_t oldMillis = millis();
    static uint16_t onOffTime;
    uint32_t newMillis = millis();
    stoker_On = digitalRead(stokerAugerPin);
    
    if(newMillis-oldMillis>=onOffTime){
        oldMillis=millis();
        stoker_On=!stoker_On;
        onOffTime=(w_pause*2)+(((p_pause - w_pause)/2)*stoker_On);//!soker_On для мосфета, soker_On для реле управление по LOW.
        digitalWrite(stokerAugerPin,stoker_On);
    }   
}

void work_timer2(){                                                                          //Функция таймер работы горелки
    static uint32_t oldMillis = millis();
    static uint16_t onOffTime;
    uint32_t newMillis = millis();
    feeder_On = digitalRead(feederAugerPin);
    
    if(newMillis-oldMillis>=onOffTime){
        oldMillis=millis();
        feeder_On=!feeder_On;
        onOffTime=w_pause+((p_pause - w_pause)*feeder_On);//!soker_On для мосфета, soker_On для реле управление по LOW.
        digitalWrite(feederAugerPin,feeder_On);
    }        
}

void finishWork(){                                                                           //Функция остановки работы горелки
 static uint32_t timer_stop;
 static int tt=time_stop/1000;
 static int tt1=time_stop_blow/1000; 
  switch(switch_stop){
	 case 0:
      f_work=1;
      startpwm=1;
      PWM_val=99;
	    kwt=10;
		  if(millis() - timer_stop >= 1000){
      timer_stop = millis();
      tt-=1;
      }
		  lcd.setCursor(14, 2);
      lcd.print(tt);
		  lcd.setCursor(17, 2);
      lcd.print(F("sec"));
		  lcd.setCursor(9, 2);
      lcd.print(F("mode:"));
		  lcd.setCursor(9, 3);
      lcd.print(F("STOPing..."));
      work_timer();
   break;
	 
	 case 1:
      digitalWrite(stokerAugerPin, HIGH);
      digitalWrite(feederAugerPin, HIGH);
      f_work=1;
      startpwm=1;
      PWM_val=99;
      if(millis() - timer_stop >= 1000){
      timer_stop = millis();
      tt1-=1;
      }
      lcd.setCursor(14, 2);
      lcd.print(tt1);
      lcd.setCursor(17, 2);
      lcd.print(F("sec")); 
      lcd.setCursor(9, 2);
      lcd.print(F("mode:"));
      lcd.setCursor(9, 3);
      lcd.print(F("Shutdown..."));
   break;
   
   case 2:
      PWM_val=0;
      startpwm=0;
      f_work=0;
      tt=time_stop/1000;
      tt1=time_stop_blow/1000;
      switch_stop=3;
   break;
	}
 
if(switch_stop==0){
    if(stop_timer1.isReady())
    switch_stop=1;}else{stop_timer1.start();}
if(switch_stop==1){
    if(stop_timer2.isReady()){
    PWM_val=0;
    switch_stop=2;}
    }else{stop_timer2.start();}
}

 

Василий Gava
Offline
Зарегистрирован: 19.12.2021

Какая плата и схема?

Smarodina
Offline
Зарегистрирован: 03.02.2018

я еще не умею делать схему, все собрано на модулях...

-NMi-
Offline
Зарегистрирован: 20.08.2018

11 задач крутить в лупе, это, канеш крута, но, код бы значительно упростился при использовании любой ртос. имхо.

Smarodina
Offline
Зарегистрирован: 03.02.2018

Что такое ртос?

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015
Василий Gava
Offline
Зарегистрирован: 19.12.2021

Сделай фото модулей которые используются для работы котла.

dmitron1036
Offline
Зарегистрирован: 10.01.2016

Присоединюсь.

Из всего котла интересует:

1) Механика (мотор - редуктор - шнек)

2) КПД

3) Котёл в разрезе

4) Цена 1 кг пеллет?

5) Цена 1 кВт электроэнергии?

Поделюсь своим опытом:

В результате изысканий сделал себе котёл + батареи + насос + разводку. Уложился в 100 баксов:

https://youtu.be/WKGTGtQIwkk?list=PLWPGkgnA_YMaTwBM0gq4aywByMRI9SBjY

работает на дровах.

Smarodina
Offline
Зарегистрирован: 03.02.2018
Smarodina
Offline
Зарегистрирован: 03.02.2018

dmitron1036 пишет:

Присоединюсь.

Из всего котла интересует:

1) Механика (мотор - редуктор - шнек)

2) КПД

3) Котёл в разрезе

4) Цена 1 кг пеллет?

5) Цена 1 кВт электроэнергии?

Поделюсь своим опытом:

В результате изысканий сделал себе котёл + батареи + насос + разводку. Уложился в 100 баксов:

https://youtu.be/WKGTGtQIwkk?list=PLWPGkgnA_YMaTwBM0gq4aywByMRI9SBjY

работает на дровах.

1. моторы 68ktyz

2. хз.

3. на канале есть видео по его сборке.

4. хз. было 2-3грн\кг,  в том году подорожало 8-10грн\кг, в этом не узнавал.

5. 1.68грн