как выполнить функцию по событию и времени

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

всем привет, я новичок в это деле, пишу код для контроллера пеллетной горелки, не получается сделать один момент...

 

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

пытался сделать таймер на миллисе, получается фингя... не работает... 

timer_fire = millis();
   if(val_f>1000 and start1 == 1 and (millis()-timer_fire>30000) and start_count<=2){
   startWork();
  }
 
не работает потому что надо переменную timer_fire записать один раз и от нее отталкиваться, а оно постоянно её переписывает:( 
 
неделю уже пробую разные варианты:(
Smarodina
Offline
Зарегистрирован: 03.02.2018
тут был неправильный код!
mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Smarodina пишет:

не работает потому что надо переменную timer_fire записать один раз и от нее отталкиваться, а оно постоянно её переписывает:

Так переписывай ее внутри if(){}. А первый раз назначь в сетапе.

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

пробовал, не подходит

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Smarodina пишет:

пробовал, не подходит

Стесьняюсь спросить - а почему? Где-то еще используется - так создайте еще одну переменную. А так- это стандартный ход.

А может потому что

 if(val_f>1000 && start1 == 1 && (millis()-timer_fire>30000) && start_count<=2){
   startWork();
  }

 

b707
Offline
Зарегистрирован: 26.05.2017

mykaida пишет:

Smarodina пишет:

пробовал, не подходит

Стесьняюсь спросить - а почему?

посмотри на строчку 441 и 460 кода. И таких циклов у ТС в коде полно. Понятно, что с таким кодом таймер на миллис не работает

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

b707 пишет:

посмотри на строчку 441 и 460 кода. И таких циклов у ТС в коде полно. Понятно, что с таким кодом таймер на миллис не работает

Не долистал. Убило наповал :)

Про цикл while() похоже неизвестно. Хотя и с ним не прокатит. А for(;;) - это что то из питона?

b707
Offline
Зарегистрирован: 26.05.2017

mykaida пишет:

Про цикл while() похоже неизвестно. Хотя и с ним не прокатит. А for(;;) - это что то из питона?

это ровно то же самое, как while(1)

По действию на код абсолютно аналогично delay() . У ТС этим "прогрессивным методом" написано 80% циклов, видимо избавлялся от задержек, а миллис так и не освоил. Это даже исправлять нет смысла, по мне так выкинуть в мусор и написать заново.

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

Я по образованию сварщик... Не зря же я в песочнице пишу... Этот код работает. греет мастерскую котел:) я понимаю что многое не правильно, но как смог... А вот сделать условие для перезапуска если огня нет определенное время не получается...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Smarodina пишет:
Я по образованию сварщик... Не зря же я в песочнице пишу... Этот код работает.

Код, возможно, и работает, но не допускает расширения функциональности.

Т.е. добавить к нему еще что-то нельзя.

Цитата:

греет мастерскую котел:) я понимаю что многое не правильно, но как смог... А вот сделать условие для перезапуска если огня нет определенное время не получается...

С таким кодом и не получится.

Правильно говорят - его надо переписывать с нуля.

С какой точностью Вам нужно выдержать время? 

Если, скажем, 0.1с, от это значит, что весь loop() у Вас должен гарантированно заканчиваться за 0.1с. А у Вас он сколько ждет?

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:
Не зря же я в песочнице пишу... .

из того, что мы в Песочнице - вовсе не следует что кто-то бросится переписывать код из 500 строк. Если бы в нем была пара ошибок - я бы подсказал, но, на мой взгляд,  код изначально написан неверно.

Логика построения программы на delay() и на millis() абсолютно разная, поменяв пару строк один в другой не переделать. А у вас ваши циклы все являются, по сути, функцией delay(), например

for(;;){
 startPWM(100);
   if(millis()-timer_produvka>5000){
    break;
   }
 }

полностью аналогично вот такому коду:

 startPWM(100);
 delay(5000);

 

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

andriano пишет:

А у Вас он сколько ждет?

Не ждёт, этих for(;;) в процессе работы нету

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

Я никого не прошу переписывать мой код! Да он не ПРАВИЛЬНЫЙ но он работает! Я не учился этому!!! Что за люди...

Если не правильно, скажите маленьким примером как правильно, я постараюсь исправится. А просто критиковать могу все...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Если он работает, какие еще у Вас вопросы к форуму? ("работает не так, как хочется" и "не работает" - это одно и то же)

А пример - классический: blink without delay.

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:
Не ждёт, этих for(;;) в процессе работы нету

Да как не ждет-то, если по тому самому условию, которое у вас не работает и с которым вы пришли на форум - запускается функция startWork(). которая просто набита подобными циклами - в строке 315 на 5 секунд, в строке 331 - на 15 сек, в строке 347 - АЖНО НА 6 МИНУТ!!

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

но самое интересное - в конце! В конце этой функции startWork(),  в строке 363 - вы запускаете эту же функцию из нее самой... Да, возможно в реальной программе этого не происходит, не вникал, но в коде это есть.

Рискну сказать. что этот код просто никуда не годится.

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

Я имел в виду что когда горит огонь в горелке никаких фор не происходит

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:
Я имел в виду что когда горит огонь в горелке никаких фор не происходит

Когда горит огонь в горелке, эта программа не нужна вовсе. Она нужна при запуске, при выключении или в случае угасания пламени. А именно в этот момент эта программа и не работает. 

А если вы считаете, что эти for никак не влияют на работу - зачем вы их туда навставляли?  Вычистите их из кода.

 

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

тогда вопрос, как мне сделать без delay() подачу шнеком стокера 15сек?

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:

тогда вопрос, как мне сделать без delay() подачу шнеком стокера 15сек?

Запустить шнек, запомнить время, продолжить выполнение программы.

Когда пройдет 15 секунд - выключить шнек.

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

b707 пишет:

Запустить шнек, запомнить время, продолжить выполнение программы.

Когда пройдет 15 секунд - выключить шнек.

 

так нечего выполнять паралельно, нужно выполнить это, потом выполнить "розжиг", а потом уже выполняется work() который выбирает режим работы и работает work_timer()

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый ТС, а Вы не пытались на бумажке, обычным языком написать алгоритм программы? А то, похоже, что Вы ее писали "как получится".

Я вижу такой минимальный алгоритм:

1) Разжигаем, если несколько раз не зажигается - уходим в ошибку.

2) Пока горит - отрабатываем алгоритмы при горении

3) Если погасло - п.1

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

По моему логично.

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

Я уже решил свою проблему, добавил библиотеку GyverTimer. Если огня нет запускается таймер, если огонь появился раньше чем таймер сработал таймер сбрасывается. Если таймер протикал и огонь не появился запускается функция которая пытается вернуть огонь...

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

mykaida пишет:

Уважаемый ТС, а Вы не пытались на бумажке, обычным языком написать алгоритм программы? А то, похоже, что Вы ее писали "как получится".

Я вижу такой минимальный алгоритм:

1) Разжигаем, если несколько раз не зажигается - уходим в ошибку.

2) Пока горит - отрабатываем алгоритмы при горении

3) Если погасло - п.1

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

По моему логично.

В сетапе мне не нужно запускать горелку... Она запускается по нажатию кнопки.

Когда два месяца назад начинал это писать был листок бумаги с алгоритмом что примерно я хочу.

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:
Я уже решил свою проблему, добавил библиотеку GyverTimer. .

Смародина, делайте что хотите. Но запомните - так писать нельзя. Тем более программы. управляющие опасным оборудованием. Когда ваша мастерская сгорит из-за того что у вас скетч тупит по 6 минут в бесконечных циклах - надеюсь что хотя бы никто из окружающих не пострадает.

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

b707 пишет:

Smarodina пишет:
Я уже решил свою проблему, добавил библиотеку GyverTimer. .

Смародина, делайте что хотите. Но запомните - так писать нельзя. Тем более программы. управляющие опасным оборудованием. Когда ваша мастерская сгорит из-за того что у вас скетч тупит по 6 минут в бесконечных циклах - надеюсь что хотя бы никто из окружающих не пострадает.

Вместо того чтобы обливать гавном можно иногда пробовать дать направление...

Мне некому помочь сделать правильно.

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

И чего цикл бесконечный?! Он заканчивается или по появлению огня или по прошествии отведённого времени. Как можно это сделать по другому?

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:

Вместо того чтобы обливать гавном можно иногда пробовать дать направление...

Мне некому помочь сделать правильно.


Почему вам кто-то должен помогать, вы маленькая девочка штоль? Берите книжки, читайте интернет и осваивайте. Я вам дал направление - делать таймеры на миллис. Можно даже использовать таймеры гайвера, только нужно делать это не в одной строчке, а по всему коду. И да, логику кода придется менять полностью, в итоге вы сами поймете, что написать заново проще, чем переделать это.

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

чтоб сделать на таймерах мне надо будет делать кучу переменных(флагов) которые будут блокировать работу других таймеров чтоб все работало своим чередом, правильно мыслю?

b707
Offline
Зарегистрирован: 26.05.2017

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

почитайте что-нибудь о "машине состояний" или "конечных автоматах"

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

b707 пишет:

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

почитайте что-нибудь о "машине состояний" или "конечных автоматах"

 

почитал о "конечных автоматах"... да... пту образования явно маловато будет...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Smarodina пишет:
Вместо того чтобы обливать гавном можно иногда пробовать дать направление... Мне некому помочь сделать правильно.

Smarodina, ну как Вам не стыдно!

Вам уже в сообщениях № 2, 4, 5, 7, 9, 10, 13, 14, 14, 18 и 20 несколько человек "пробовали дать направление". А Вы, вместо того, чтобы хоть чуть пошевелить пальцем, только высказываете неудовольствие.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Smarodina пишет:

чтоб сделать на таймерах мне надо будет делать кучу переменных(флагов) которые будут блокировать работу других таймеров чтоб все работало своим чередом, правильно мыслю?

Нет.

В том то и дело, что ничего никогда не должно блокировать. Если Вы в 99 случаях напишете неблокирующий код, а одном-единственном - блокирующий, это работать не будет. Код на все 100% должен быть неблокирующим.

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

andriano пишет:

Smarodina пишет:

чтоб сделать на таймерах мне надо будет делать кучу переменных(флагов) которые будут блокировать работу других таймеров чтоб все работало своим чередом, правильно мыслю?

Нет.

В том то и дело, что ничего никогда не должно блокировать. Если Вы в 99 случаях напишете неблокирующий код, а одном-единственном - блокирующий, это работать не будет. Код на все 100% должен быть неблокирующим.

 

тогда вы просто не понимаете как оно должно работать... нельзя сделать все сразу... нужна последовательность.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Smarodina пишет:

тогда вы просто не понимаете как оно должно работать... нельзя сделать все сразу... нужна последовательность.

Да, чего-то я не понимаю.

В частности, не понимаю, что именно Вы хотели сказать.

Я понимаю, как следует писать программы. И понимаю, чего следует избегать при их написании.

В то же время, я не понимаю, как должна работать Ваша программа, т.к. Вы об этом нигде подробно не написали. 

Что же касается "нельзя все сделать сразу" - да, делать нужно постепенно, если хотите - последовательно. Но при этом каждый очередной шаг не должен исключать возможность сделать следующий шаг. В противном случае мы остановимся на середине и не будем иметь возможности завершить проект.

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:

тогда вы просто не понимаете как оно должно работать... нельзя сделать все сразу... нужна последовательность.

нет, это вы не понимаете. Если у вас код неблокирующий - вы можете выполнять задачи как попеременно, так и последовательно. А когда блокирующий - только ждать, пока одна закончит, чтобы сделать что-то еще. А между тем, в подобных системах всегда есть необходимость оперативного отслеживания каких-то датчиков, например датчика пламени, ОДНОВРЕМЕННО С ВЫПОЛНЕНИЕМ ДРУГИХ ОПЕРАЦИЙ. В вашем исходном коде это в принципе невозможно.

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

ну почему же, мой блокирующий for(;;) отслеживает датчик огня и таймер в нем тикает

Smarodina
Offline
Зарегистрирован: 03.02.2018
если это:
unsigned long fireTimer;
   fireTimer = millis();
   for(;;){
   digitalWrite(feederAugerPin, HIGH);
   PWM_val=80;
   startPWM();                                      
   digitalWrite(heatingElementPin, LOW);                         
   average_fire();
   average_temp();
   button();
   screen();
        if(val_f<=750||millis()-fireTimer>=240000){
        fireTimer = millis();
        break;
        }
   }
  

заменить этим:

unsigned long fireTimer;
   if(millis()-fireTimer<240000 or val_f<=750){
  digitalWrite(heatingElementPin, LOW);}
else{
fireTimer=millis();
digitalWrite(heatingElementPin, HIGH);}

будет тоже самое, но как выполнять только его?

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

b707 пишет:

 или "конечных автоматах"

Спасибо за наводку. Очень интересно.

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:

будет тоже самое, но как выполнять только его?

не понимаю, в чем проблема. Когда не надо ничего выполнять параллельно - не делайте. Вы о конечных автоматах прочитали? - это как раз оно

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

не знаю что такие "конечное автоматы", но кажись доперло как реализовать. на днях напишу новую startWork() и выложу на ваш суд!

b707
Offline
Зарегистрирован: 26.05.2017

Smarodina пишет:

на днях напишу новую startWork() и выложу на ваш суд!

похоже вы опять упустили то, что вам писали Андриано и я в сообщениях #31 и #26. Нельзя переписать только startWork() - в неблокирующем стиле должен быть написан ВЕСЬ КОД, иначе это бессмысленно

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

я не упустил, а решил начать с startWork()

for(;;) есть только в startWork() и finishWork()

да некоторым изменениям подвергнутся и остальные части кода, но не существенно. 

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

теперь жду комментариев где не правильно!



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

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

#define CLK A4
#define DIO A5
#define ONE_WIRE_BUS 11
#define FILTER_STEP_temp 100
#define FILTER_COEF_temp 0.05

GyverTM1637 disp(CLK, DIO);
GyverPID pid(0.35, 0, 0, 3000);
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 temperatureSensorPin = 11;     //пин датчика температуры
const int photoresistorPin = 12;         //пин фоторезистора
const int infraredSensorPin = A3;        //пин ИК датчика
const int potentiometerPin = A0;         //пин потенциометра
////////////////////иполнители////////////////////////////////////////
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;
byte working;
byte start_count;
byte photoresistor;
int p_pause;
int w_pause;
byte start1;
int val_f;
int val[3];
int index;
int val_temp;
int val_Ftemp;
byte starting;                                    
byte finishing;                                    
byte plusButton;
byte minusButton;
byte dispButton;
int dose;
byte displ;
char fan_val;
int PWM_val;
byte start_work;
byte stop_FP;
byte pause_work;
byte dozig;
byte fanspeed_pr;
byte pid_out_last;
unsigned int punk;
int phase;
int switch_start;
int switch_stop;
int stop_FPB;

GTimer start_timer0(MS);
GTimer start_timer1(MS);
GTimer start_timer2(MS);
GTimer start_timer3(MS);
GTimer stop_timer1(MS);
GTimer AS_timer(MS);

auto timer_up = timer_create_default();
auto firebar_up = timer_create_default();

int middle_of_3(int a, int b, int c) {
  int middle;
  if ((a <= b) && (a <= c)) {
    middle = (b <= c) ? b : c;
  }
  else {
    if ((b <= a) && (b <= c)) {
      middle = (a <= c) ? a : c;
    }
    else {
      middle = (a <= b) ? a : b;
    }
  }
  return middle;
}

bool test_timer_up() {
  digitalWrite(stokerAugerPin, !digitalRead(stokerAugerPin));
    return false; 
}

bool test_firebar_up() {                                                                     
  digitalWrite(firebarPin, !digitalRead(firebarPin));
    return false; 
}

void setup() {
  switch_stop=9;
  switch_start=9;
  pid_out_last=100;
  dozig=0;
  pause_work=0;
  PWM_val=0;
  displ=0;
  working=0;
  start1=0;
  start_count=0;
  start_work=0;
  desiredTemperature=500;
  stop_FP=1;
  
  disp.clear();
  disp.brightness(0);  // яркость, 0 - 7 (минимум - максимум)
  
    startButtonPin.setTickMode(AUTO);
    stopButtonPin.setTickMode(AUTO);
    plusButtonPin.setTickMode(AUTO);
    minusButtonPin.setTickMode(AUTO);
    disp_ButtonPin.setTickMode(AUTO);
	
	  pinMode(potentiometerPin, INPUT);
    pinMode(photoresistorPin, INPUT);
    pinMode(infraredSensorPin, INPUT);
    pinMode(temperatureSensorPin, 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(2,9);
  pid.setpoint = desiredTemperature; 
  sensors.begin();
  start_timer0.setTimeout(5000);
  start_timer1.setTimeout(15000);
  start_timer2.setTimeout(180000);
  start_timer3.setTimeout(10000);
  stop_timer1.setTimeout(60000);
  AS_timer.setTimeout(30000);
}

void loop() {
  button();
  fillPillets();
  pid_timer();
  average_fire();
  average_temp();
  work();
  startWork();
  finishWork();
  //start_stop();
  //auto_start();
  //fire_bar();
  startPWM();
  screen();
}

void pid_timer(){                                                                            //Функция таймер ПИД регулятора
  unsigned long timer_pid;
if(working==1){
  if(millis() - timer_pid >= 1000){
    timer_pid = millis();
    pid.input = val_Ftemp;
    pid.setpoint = desiredTemperature;
    pid.getResult();
  }
}
}

void fire_bar(){                                                                             //Функция таймера работы подвижного колосника
   int phase_firebar;
   unsigned long firebar_punk;
   digitalWrite(firebarPin, HIGH); 
   firebar_punk = firebar_up.tick();
    if (firebar_punk<=10) {
    phase_firebar = digitalRead(firebarPin);
    if (phase_firebar == LOW){
    firebar_up.cancel();
    firebar_up.in(10000, test_firebar_up);
    }
    
    if (phase_firebar == HIGH){
    firebar_up.cancel();
    firebar_up.in(300000, test_firebar_up);
    }
   }
}

void average_temp(){                                                                         //Функция обработки сигнала датчика температуры
   unsigned long filter_temp_timer;
   int currentTemp;
   sensors.requestTemperatures();
   currentTemp = sensors.getTempC(insideThermometer)*10;
   if (millis() - filter_temp_timer > FILTER_STEP_temp) {
    filter_temp_timer = millis();   
    val_temp = currentTemp;
    val_Ftemp = val_temp * FILTER_COEF_temp + val_Ftemp * (1 - FILTER_COEF_temp);
    }
 }
 
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() {                                                                            //функция управления ШИМ вентилятора
  int fanspeed;
  //fan_val=constrain(fan_val,-20,20);
  fanspeed_pr = PWM_val;//+fan_val;
  fanspeed_pr = constrain(fanspeed_pr, 0, 100);
  fanspeed = map(fanspeed_pr, 0, 100, 0, 253);
  analogWrite(pwmPin, fanspeed);
}

void start_stop(){                                                                           //Функция автоматической оставноки и запуска горелки по температуре
    if((desiredTemperature - val_temp) >= 50 and pause_work==1 and photoresistor == HIGH and val_f>1000){
    pause_work=0;
    working=1;
	switch_start=0;  
  }

  if((val_temp - desiredTemperature) >= 50 and start1==1 and val_f<1000){
    pause_work=1;
    working==0;
	switch_stop=0;
  }

}

void button(){                                                                               //Функция обработки кнопок
  desiredTemperature = constrain(desiredTemperature, 300, 800);
  stop_FP = digitalRead(stokerAugerPin);
  
  if(disp_ButtonPin.isClick()){
    displ = displ+1;
    if(displ >= 4){
      displ=0;
    }
  }
  if(startButtonPin.isClick() and photoresistor==1 and val_f>900){
    switch_start=0;
    }
  if(startButtonPin.isPress() and val_f<900){
    working=1;
    start1=1;
	  }
  if(stopButtonPin.isClick()){
      stop_FPB=1;
	  working=0;
      start1=0;
      switch_stop=0;
    }
}

void auto_start(){                                                                           //Функция автостарта горелки при потере огня
  
  if(val_f>1000 and start1==1 and start_count<2 and pause_work==0){
    if(AS_timer.isReady())switch_start=5;}else{AS_timer.reset();}
  
  
  if(start_count>=3){
    start1=0;
	working=0;
    //сюда надо подкючить сирену или какое то еще оповещение о аварии.
    }
 
}

void screen(){                                                                               //функция вывода информации на дисплей
 int for_disp;
 switch (displ){
  case 0 :
    for_disp = desiredTemperature * 10;
      for_disp = for_disp + val_temp/10;
      disp.displayInt(for_disp);                                                      
      disp.point(true);
    if(plusButtonPin.isPress()){
      desiredTemperature = desiredTemperature + 10;
      }
      if(minusButtonPin.isPress()){
      desiredTemperature = desiredTemperature - 10;
      }
    break;
  case 1 :
    disp.displayInt(dose);
      disp.point(false);
    break;
  case 2 :
    disp.displayInt(fanspeed_pr);
    disp.displayByte(0, 0x71);
    //disp.displayInt(fan_val);
      disp.point(false);
    if(plusButtonPin.isPress()){
      fan_val = fan_val + 1;
      }
      if(minusButtonPin.isPress()){
      fan_val = fan_val - 1;
      }
    break;
    case 3 :
    disp.displayInt(val_f);
      disp.point(false);
    break;
    
  }
}
 
void fillPillets() {                                                                         //Функция подачи пеллет из бункера в стокер
  photoresistor = digitalRead(photoresistorPin);
  if(stop_FPB==0){
  if (photoresistor == 0 and stop_FP==1) {
     digitalWrite(feederAugerPin, LOW);}
  else {
     digitalWrite(feederAugerPin, HIGH);}
  }
}

void startWork(){                                                                            //функция розжига
  switch(switch_start){
	   
	   case 0:
        PWM_val=100;
	    break;
	   
	   case 1:
	    PWM_val=20;
	    digitalWrite(feederAugerPin, HIGH);
	    digitalWrite(stokerAugerPin, LOW);
		break;
	   
	   case 2:
	    digitalWrite(stokerAugerPin, HIGH);
	    switch_start=3;
		break;
	   
	   case 3:
	    PWM_val=80;
	    digitalWrite(heatingElementPin, LOW);
        break;
	   
	   case 4:
	    digitalWrite(heatingElementPin, HIGH);
	    PWM_val=80;
      dose=1111;
		break;
		
	   case 5:
	    digitalWrite(heatingElementPin, HIGH);
        start_count=start_count+1;
		if(start_count<=3){
	    switch_start=0;}
        break;

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

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

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

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.reset();}

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

void work() {                                                                                //Функция выбора варианта работы горелки
  if (working == 1) { 
    start_count = 0;
    
  if (pid_out_last != pid.output){
  digitalWrite(stokerAugerPin,HIGH);
    
    switch (pid.output) {
    case 0 :p_pause=10000;w_pause=100;PWM_val=20;dose = 180;break;
    case 1 :p_pause=8500;w_pause=100;PWM_val=25;dose = 210;break;
    case 2 :p_pause=7500;w_pause=100;PWM_val=30;dose = 240;break;
    case 3 :p_pause=6000;w_pause=100;PWM_val=35;dose = 300;break;
    case 4 :p_pause=5000;w_pause=100;PWM_val=40;dose = 360;break;
    case 5 :p_pause=4500;w_pause=100;PWM_val=45;dose = 400;break;
    case 6 :p_pause=2500;w_pause=125;PWM_val=65;dose = 850;break;
    case 7 :p_pause=3750;w_pause=200;PWM_val=80;dose = 1000;break; 
    case 8 :p_pause=3000;w_pause=200;PWM_val=95;dose = 1630;break;
    case 9 :p_pause=3000;w_pause=250;PWM_val=100;dose = 2000;break;            
    }
  timer_up.cancel();
  timer_up.in(p_pause,test_timer_up);      
  }
  pid_out_last = pid.output;
  work_timer();
  }
  
  
}

void work_timer(){                                                                           //Функция таймер работы горелки
    punk = timer_up.tick();
  if (punk<=10) {
    phase = digitalRead(stokerAugerPin);
    if (phase == LOW){
    timer_up.cancel();
    timer_up.in(w_pause, test_timer_up);
    }
    
    if (phase == HIGH){
    timer_up.cancel();
    timer_up.in(p_pause, test_timer_up);
    } 
   }
}

void finishWork(){                                                                           //Функция остановки работы горелки
  switch(switch_stop){
	 case 0:
	  p_pause=3000;
      w_pause=250;
      PWM_val=100;
      work_timer();
      break;
	 case 1:
      PWM_val=100;
	  break;
	}
if(switch_stop==0){
 if(val_f<1000){switch_stop=0;}}
if(switch_stop==0){
 if(val_f>1000){switch_stop=1;}}
if(switch_stop==1){
 if(stop_timer1.isReady()){switch_stop=3;stop_FPB=0;PWM_val=0;}else{stop_timer1.reset();}}
}

и попутно вопрос, ячейка EEPROM Хранит значение 0...255 и только? или -128...127

b707
Offline
Зарегистрирован: 26.05.2017

в логику кода пока не вникал. но сразу замечания по структуре

1. Зачем условия в строчках 390-402 вынесены отдельно, почему бы не добавить их в Switch строка 350

2. Длинный Switch cтрочки 412-472 легко заменяется 4 строчками кода. если предварительно положить значения изменяющихся переменных в массивы с индексом по значению ключа свитча

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

b707 пишет:

в логику кода пока не вникал. но сразу замечания по структуре

1. Зачем условия в строчках 390-402 вынесены отдельно, почему бы не добавить их в Switch строка 350

2. Длинный Switch cтрочки 412-472 легко заменяется 4 строчками кода. если предварительно положить значения изменяющихся переменных в массивы с индексом по значению ключа свитча

 

1. Сначала делал их в Switch но не работает. вынес и все заработало.

2. к сожалению еще не умею.

 

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А сворачивать код при публикации тоже "еще не умеете"?

Размещать без сворачивания код длиной больше чем один экран - mauvais ton.

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

andriano пишет:

А сворачивать код при публикации тоже "еще не умеете"?

Размещать без сворачивания код длиной больше чем один экран - mauvais ton.

 

свернул

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

andriano пишет:

А сворачивать код при публикации тоже "еще не умеете"?

Размещать без сворачивания код длиной больше чем один экран - mauvais ton.

 

а по коду комментарии будут?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Smarodina пишет:

и попутно вопрос, ячейка EEPROM Хранит значение 0...255 и только? или -128...127

Ячейка хранит 8 бит, а EEPROM хранит то, что скажешь. char - 1 байт, int -  2 байта, float -  4 байта. Как скажете - так и будет.

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

mykaida пишет:

Smarodina пишет:

и попутно вопрос, ячейка EEPROM Хранит значение 0...255 и только? или -128...127

Ячейка хранит 8 бит, а EEPROM хранит то, что скажешь. char - 1 байт, int -  2 байта, float -  4 байта. Как скажете - так и будет.

 

помогите примером пожалуйста, как хранить переменную char у которой диапазон от -30 до 30. спасибо

b707
Offline
Зарегистрирован: 26.05.2017

по коду вот еще :)

искать среднее из трех значений можно быстрее, чем так:

int middle_of_3(int a, int b, int c) {
  int middle;
  if ((a <= b) && (a <= c)) {
    middle = (b <= c) ? b : c;
  }
  else {
    if ((b <= a) && (b <= c)) {
      middle = (a <= c) ? a : c;
    }
    else {
      middle = (a <= b) ? a : b;
    }
  }
  return middle;
}

 

вот например так

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] } 
}