помогите посчитать

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

всем привет, есть таймер 

  static uint32_t oldMillis = millis();
       static uint16_t onOffTime;
       uint32_t newMillis = millis();
       HE_On = digitalRead(13);
    
    if(newMillis-oldMillis>=onOffTime){
       oldMillis=millis();
       HE_On=!HE_On;
       onOffTime=w_pause+(p_paese*HE_On);
       digitalWrite(13, HE_On);
    }

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А код где? Этот огрызок ни о чём.

Smarodina пишет:

мне нужно считать в переменную w_pause 

Что считать?

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

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

#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 ONE_WIRE_BUS 11

LiquidCrystal_I2C lcd(0x27,20,4);
GyverPID pid(0.8, 0.07, 8.4, 30000);
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;
signed char fan_value;
int PWM_val;
byte fanspeed_pr;
byte pid_out_last;
int switch_start;
int switch_stop;
int startpwm;
uint8_t start_1;
uint8_t stop_1;
int fire_off;  
byte pid_start;
byte displ;
byte min_power;
byte max_power;
uint8_t dopid_power;
  
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;
  switch_stop=9;
  switch_start=9;
  pid_out_last=100;
  PWM_val=30;
  working=0;
  start1=0;
  start_count=0;
  startpwm=0;
  fire_off=0;
  pid_start=0;
  displ=0;
  min_power=EEPROM.get(1,min_power);
  max_power=EEPROM.get(3,max_power);
  desiredTemperature=EEPROM.get(5,desiredTemperature);
  dopid_power=EEPROM.get(7,dopid_power);
  
   lcd.init();                      // initialize the lcd 
   lcd.backlight();
   lcd.clear();
   
    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.setMode(ON_RATE);
  pid.setDirection(NORMAL); 
  pid.setLimits(0,9);
  pid.setpoint = desiredTemperature; 
  sensors.begin();
  start_timer0.setTimeout(15000);//время продувки перед запуском горелки
  start_timer1.setTimeout(25000);//время загрузки пеллет на розжиг
  start_timer2.setTimeout(180000);//время работы зажигалки
  start_timer3.setTimeout(5000);//время стабилизации пламени
  stop_timer1.setTimeout(200000);//время дожига пеллет перед останокой горелки
  stop_timer2.setTimeout(300000);//время продувки перед останокой горелки
}

void loop() {
  average_fire();
  temp();
  button();
  dopid();
  pidstart();
  work();
  startWork();
  finishWork();
  auto_start();
  //fire_bar();
  startPWM();
  screen();
  
}

void dopid(){
  static uint8_t dopid_power_last=dopid_power;
  dopid_power=constrain(dopid_power,1,15);
  if(desiredTemperature-currentTemp>50){
  pid_start=0;
  if(dopid_power!=dopid_power_last){
  dopid_power_last=dopid_power;
  EEPROM.put(7,dopid_power);  
  }
  pid.output=dopid_power-1;
  }
   else{
   pid_start=1; 
  }
}

void pidstart(){
  static uint8_t min_power_last=min_power;
  static uint8_t max_power_last=max_power;
  static uint8_t desiredTemperature_last=desiredTemperature;
  if(pid_start==1){
  pid.input = currentTemp;
  pid.setpoint = desiredTemperature; 
  pid.setLimits(min_power-1,max_power-1);
  min_power=constrain(min_power,0,max_power);
  max_power=constrain(max_power,min_power,15);
  
  if(min_power!=min_power_last){
  min_power_last=min_power;
  EEPROM.put(1,min_power);  
  }
  if(max_power!=max_power_last){
  max_power_last=max_power;
  EEPROM.put(3,max_power);  
  }
  if(desiredTemperature!=desiredTemperature_last){
  desiredTemperature_last=desiredTemperature;
  EEPROM.put(5,desiredTemperature);  
  }
  pid.getResultTimer();
  }
}

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(); 
   lcd.clear();
   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, 400, 800);

  if(displ==0 and plusButtonPin.isClick()){
      desiredTemperature+=10;
      plusButtonPin.resetStates();
      }
  if(displ==0 and minusButtonPin.isClick()){
      desiredTemperature-=10;
      minusButtonPin.resetStates();
      }
  if(displ==0 and plusButtonPin.isHold()){
      desiredTemperature+=10;
      }
  if(displ==0 and minusButtonPin.isHold()){
      desiredTemperature-=10;
      }
  if(disp_ButtonPin.isHolded()){
    digitalWrite(feederAugerPin, LOW);
  }

  if(stopButtonPin.isHolded()){
    digitalWrite(feederAugerPin, HIGH);
    }

  if(disp_ButtonPin.isClick()){
    displ+=1;
    if(displ >= 4)displ=0;
  }
  
  if(startButtonPin.isClick()){
    startpwm=1;
    switch_start=0;
    }
  if(stopButtonPin.isClick()){
    startpwm=1;
	  working=0;
    start1=0;
    switch_stop=0;
    }
	if(currentTemp>=850 and working==1){
    startpwm=1;
    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);
	}

    if(displ==1 and plusButtonPin.isClick()){
      min_power+=1;
      plusButtonPin.resetStates();
      }
    if(displ==1 and minusButtonPin.isClick()){
      min_power-=1;
      minusButtonPin.resetStates();
      }
    if(displ==1 and plusButtonPin.isHold()){
      min_power+=1;
      }
    if(displ==1 and minusButtonPin.isHold()){
      min_power-=1;
      }
    
    if(displ==2 and plusButtonPin.isClick()){
      max_power+=1;
      plusButtonPin.resetStates();
      }
    if(displ==2 and minusButtonPin.isClick()){
      max_power-=1;
      minusButtonPin.resetStates();
      }
    if(displ==2 and plusButtonPin.isHold()){
      max_power+=1;
      }
    if(displ==2 and minusButtonPin.isHold()){
      max_power-=1;
      }
    
    if(displ==3 and plusButtonPin.isClick()){
      dopid_power+=1;
      plusButtonPin.resetStates();
      }
    if(displ==3 and minusButtonPin.isClick()){
      dopid_power-=1;
      minusButtonPin.resetStates();
      }
    if(displ==3 and plusButtonPin.isHold()){
      dopid_power+=1;
      }
    if(displ==3 and minusButtonPin.isHold()){
      dopid_power-=1;
      }
    
}

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

 if (dose==1 or dose==2 or dose==3 or dose==4 or dose==5){
  time_no_fire = 1800;
 }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;
      pid_out_last=100;
      switch_start=5;
  }
}

void screen(){                                                                               //функция вывода информации на дисплей
      static int fire;
      switch(displ){
      case 0:
      if(startpwm==0){
      lcd.setCursor(9, 2);
      lcd.print("press START");
      lcd.setCursor(9, 3);
      lcd.print("ready to go");
      }
      
      lcd.setCursor(0, 0);
      lcd.print("Tyct.");
      lcd.setCursor(6, 0);
      lcd.print(desiredTemperature/10);
      lcd.setCursor(8, 0);
      lcd.print("C");
      
      lcd.setCursor(0, 1);
      lcd.print("Tkot.");
      lcd.setCursor(6, 1);
      lcd.print(currentTemp/10);
      lcd.setCursor(8, 1);
      lcd.print("C");
      
      lcd.setCursor(0, 2);
      lcd.print("kWt");
      lcd.setCursor(4, 2);
      lcd.print(dose);

      lcd.setCursor(0, 3);
      lcd.print("Fan");
      lcd.setCursor(4, 3);
      lcd.print(fanspeed_pr);
      if(fanspeed_pr<10){
      lcd.setCursor(5, 3);
      lcd.print("%");  
      }else if(fanspeed_pr<100){
        lcd.setCursor(6, 3);
      lcd.print("%");
      }else if(fanspeed_pr>99){
        lcd.setCursor(7, 3);
      lcd.print("%");
      }
     
    /*if(plusButtonPin.isClick() and fanspeed_pr<100){
      fan_value+=5;
      plusButtonPin.resetStates();
      }
    if(minusButtonPin.isClick()){
      fan_value-=5;
      minusButtonPin.resetStates();
      }
    */
    if(val_f<1000){
      lcd.setCursor(16, 0);
      lcd.print("Fire");
      lcd.setCursor(12, 0);
      fire=map(val_f,0,1023,100,0);
      lcd.print(fire);
      lcd.setCursor(14, 0);
      lcd.print("%");}
     else{
      lcd.setCursor(14, 0);
      lcd.print("noFire");
      lcd.setCursor(11, 0);
      lcd.print(fire_off/10);}  

     if(working==1){
      lcd.setCursor(9, 2);
      lcd.print("mode:");
      lcd.setCursor(9, 3);
      lcd.print("working...");}  
      break;

      case 1:
      lcd.setCursor(5,1);
      lcd.print("MIN Power");
      lcd.setCursor(9,2);
      lcd.print(min_power);
      lcd.setCursor(8,3);
      lcd.print("kWt");
      break;
      
      case 2:
      lcd.setCursor(5,1);
      lcd.print("MAX Power");
      lcd.setCursor(9,2);
      lcd.print(max_power);
      lcd.setCursor(8,3);
      lcd.print("kWt");
      break;    
      
      case 3:
      lcd.setCursor(4,1);
      lcd.print("Boost Power");
      lcd.setCursor(9,2);
      lcd.print(dopid_power);
      lcd.setCursor(8,3);
      lcd.print("kWt");
      break;    


 }
} 

void heat_timer(){
       static uint32_t oldMillis = millis();
       static uint16_t onOffTime;
       uint32_t newMillis = millis();
       boolean HE_On = digitalRead(heatingElementPin);
    
    if(newMillis-oldMillis>=onOffTime){
       oldMillis=millis();
       HE_On=!HE_On;
       onOffTime=1000;
       digitalWrite(heatingElementPin, HE_On);
    }
}

void startWork(){                                                                             //функция розжига
  static uint32_t timer_start;
  static uint8_t tt1=15;
  static uint8_t tt2=25;
  static uint8_t tt3=180;
  switch(switch_start){
	   case 0:
      PWM_val=100;
      if(millis() - timer_start >= 1000){
      timer_start = millis();
      tt1-=1;
      }
      lcd.setCursor(14, 2);
      lcd.print(tt1);
      lcd.setCursor(17, 2);
      lcd.print("sec");
      lcd.setCursor(9, 2);
      lcd.print("mode:");
      lcd.setCursor(9, 3);
      lcd.print("Blow...");
      if(val_f<900){
    switch_start=4;}
		break;
	   
	   case 1:
	    PWM_val=20;
      if(millis() - timer_start >= 1000){
      timer_start = millis();
      tt2-=1;
      }
      lcd.setCursor(14, 2);
      lcd.print(tt2);
      lcd.setCursor(17, 2);
      lcd.print("sec");
      lcd.setCursor(9, 2);
      lcd.print("mode:");
      lcd.setCursor(9, 3);
      lcd.print("Loading...");
		  digitalWrite(stokerAugerPin, LOW);
      digitalWrite(feederAugerPin, LOW);
  
      if(val_f<800){
    switch_start=2;}
		break;
	   
	   case 2:
	     digitalWrite(stokerAugerPin, HIGH);
       digitalWrite(feederAugerPin, HIGH);
	     switch_start=3;
		break;
	   
	   case 3:
	     PWM_val=100;
       if(millis() - timer_start >= 1000){
       timer_start = millis();
       tt3-=1;
       }
       lcd.setCursor(14, 2);
       lcd.print(tt3);
       lcd.setCursor(17, 2);
       lcd.print("sec");
	     lcd.setCursor(9, 2);
       lcd.print("mode:");
	     lcd.setCursor(9, 3);
       lcd.print("Heating...");
	     //heat_timer();
       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<700)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);
  digitalWrite(feederAugerPin,HIGH);
    switch (pid.output) {
    //p_pause=пауза подачи. w_pause=подача. PWM_val=вентилятор в процентах. dose=расход грамм\час.
	  case 0 :p_pause=15000;w_pause=232;PWM_val=35;dose = 1;break;
    case 1 :p_pause=15000;w_pause=472;PWM_val=40;dose = 2;break;
    case 2 :p_pause=15000;w_pause=719;PWM_val=45;dose = 3;break;
    case 3 :p_pause=15000;w_pause=974;PWM_val=55;dose = 4;break;
    case 4 :p_pause=15000;w_pause=1238;PWM_val=60;dose = 5;break;
    case 5 :p_pause=15000;w_pause=1510;PWM_val=65;dose = 6;break;
    case 6 :p_pause=15000;w_pause=1792;PWM_val=100;dose = 7;break;
    case 7 :p_pause=15000;w_pause=2084;PWM_val=100;dose = 8;break; 
    case 8 :p_pause=15000;w_pause=2385;PWM_val=100;dose = 9;break;
    case 9 :p_pause=15000;w_pause=2698;PWM_val=100;dose = 10;break;            
    case 10 :p_pause=15000;w_pause=3022;PWM_val=100;dose = 11;break;
    case 11 :p_pause=15000;w_pause=3359;PWM_val=100;dose = 12;break;
    case 12 :p_pause=15000;w_pause=3708;PWM_val=100;dose = 13;break; 
    case 13 :p_pause=15000;w_pause=4070;PWM_val=100;dose = 14;break;
    case 14 :p_pause=15000;w_pause=4447;PWM_val=100;dose = 15;break;            
    
    }
   }
  pid_out_last = pid.output;
  work_timer();
  work_timer2();
  }
}

void work_timer(){                                                                           //Функция таймер работы горелки
    static uint32_t oldMillis = millis();
    static uint16_t onOffTime;
    uint32_t newMillis = millis();
    boolean stoker_On = digitalRead(stokerAugerPin);
    
    if(newMillis-oldMillis>=onOffTime){
        oldMillis=millis();
        stoker_On=!stoker_On;
        onOffTime=(w_pause+(w_pause/3))+((p_pause - w_pause)*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();
    boolean 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=200;
 static int tt1=300; 
  switch(switch_stop){
	 case 0:
	    p_pause=7000;
		  w_pause=2572;
		  PWM_val=100;
		  if(millis() - timer_stop >= 1000){
      timer_stop = millis();
      tt-=1;
      }
		  lcd.setCursor(14, 2);
      lcd.print(tt);
		  lcd.setCursor(17, 2);
      lcd.print("sec");
		  lcd.setCursor(9, 2);
      lcd.print("mode:");
		  lcd.setCursor(9, 3);
      lcd.print("STOPing...");
      work_timer();
   break;
	 
	 case 1:
      digitalWrite(stokerAugerPin, HIGH);
      digitalWrite(feederAugerPin, HIGH);
      PWM_val=100;
      if(millis() - timer_stop >= 1000){
      timer_stop = millis();
      tt1-=1;
      }
      lcd.setCursor(14, 2);
      lcd.print(tt1);
      lcd.setCursor(17, 2);
      lcd.print("sec");
      lcd.setCursor(9, 2);
      lcd.print("mode:");
      lcd.setCursor(9, 3);
      lcd.print("Shutdown...");
   break;
   
   case 2:
      PWM_val=0;
      startpwm=0;
      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();}
}

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Поставьте себя на место китайцев, которые сидят в микроконтроллере и все считают ...

Как бы вы считали нужную вам цифру ? Потом свои мысли положите на язык C++ и китайцы, которые ... ну вы поняли - посчитают то что вам нужно ...

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

Не могу разобраться, понимаю что надо считать например относительно millis, но как сделать эти точки отчёта...

sadman41
Offline
Зарегистрирован: 19.10.2016

Включили пин - занесли millis в переменную start. Включили пин - занесли millis в переменную stop. Время работы: stop - start.

AlexTLN
Offline
Зарегистрирован: 14.05.2016

Я бы как-то так сделал бы...

int millisStart = 0;

int millisPin13Delay = 0;

pinMode(13, OUTPUT);

void loop()

{

pinMode(13, HIGH);

millisStart = millis();

delay(1000);

pinMode(13, LOW);

millisPin13Delay = millisPin13Delay + (millis() - millisStart);

}