Загрузчик для печки.

avgustdon
Offline
Зарегистрирован: 28.02.2016

Задача управлять устройством загрузки топлива в печь. Выглядит это так: по достижении заданной температуры включается загрузочное устройство, работает заданное время (1-5 сек), затем отключается и ждет падения температуры до заданного уровня. Затем цикл повторяется.

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

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014
bool flag = true; // Добавляем переменную-флаг

void loop()
{
  if (flag) // Проверяем флаг. Если установлен, то выполняем действие
  {
    // Тут выполняем какое-то действие
    flag = false; // После выполнения действия сбрасываем флаг
  }

  // Тут продожается выполнение остальной части программы
  flag = true; // В нужный момент устанавливаем флаг, чтобы выполнить действие ещё раз
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

if t01_zadan=заданная_температура_низшая

{flag = true;} else {flag=false;}

if t01_zadan=заданная_температура_высшая && flag=true

{Reley_1 = HIGH;

deley(t02_zadan);

}

Чисто логика, ситаксис не прверял, но само задание глупое, изначально то печь холодная ))) тоже надо включить, это когда вышла на режим тогда может да, но что-то я сомневаюсь

avgustdon
Offline
Зарегистрирован: 28.02.2016

Попробую выложить получившийся скетч. Собрал на сколько понял. 

[code]
bool flag = true; 
#define Out1 10
#define t_sensor  A5
// --------------------------------------------------
int runtime = 500;    //время подачи топлива
int t1 = 500;        // минимальное  значение температуры
int t2 = 700;        // максимальное значение температуры
//------------------------------------------------ 
void setup() 
{ 
Serial.begin (9600); 
pinMode(Out1, OUTPUT);  
pinMode(t_sensor, INPUT);
} 
void loop()
{
  int t;
  t = analogRead(t_sensor);
  
  if (t = t1) 
 {flag = true;} 
 else 
 {flag = false;}
 
 if (t = t2 && flag = true)
 {digitalWrite(Out1, HIGH);}
 delay(runtime);
  }
  

[/code]

При компиляции ругается в строке 26. "lvalue required as left operand of assignment"

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

ua6em пишет:

Чисто логика, ситаксис не прверял

Вот теперь и объясняйте ему, почему там возникает ошибка при компиляции...

Логика тоже не правильная. Сравнивать надо не на равенство температур. Может так получиться, что между двумя замерами значение температуры успеет просокочить порог. Поэтому сравнивать надо так: текущая температура меньше или равна минимальной; текущая температура больше или равна максимальной.

Во-вторых условие if t01_zadan=заданная_температура_высшая && flag=true никогда не выполнится (неправильный синтаксис опустим), потому что flag не может быть true, если t01_zadan=заданная_температура_высшая. 

avgustdon
Offline
Зарегистрирован: 28.02.2016

Ок. Попробовал разобрать ваш вариант. Не вижу смысла просить не кидаться помидорами, поэтому весь открыт как есть. По правде говоря не очень понял как бороться с флагами, но скетч кой-какой сваял. 



[code]
bool flag = true; 
#define Out1 10
#define t_sensor  A5
int t;  
// --------------------------------------------------
int runtime = 1000;    //время подачи топлива
int t1 = 500;        // минимальное  значение температуры
int t2 = 700;        // максимальное значение температуры
//------------------------------------------------ 
void setup() 
{ 
Serial.begin (9600); 
pinMode(Out1, OUTPUT);  
pinMode(t_sensor, INPUT);
} 
void loop()
{
  t = analogRead(t_sensor);
  if (flag) // Проверяем флаг. Если установлен, то выполняем действие
  {
if (t > t2  ) 
   { 
    digitalWrite(Out1, HIGH);
    delay(runtime); // время подачи топлива
   flag = false; // После выполнения действия сбрасываем флаг
   }
  {
if (t < t1  ) 
   { 
    digitalWrite(Out1, LOW);
   }  
  }
   flag = true; 

  Serial.print("  t  "); 
  Serial.print(t); 
  Serial.print("        Out1  "); 
  Serial.println(digitalRead(Out1));   
}}
  

[/code]

 

Разумеется работает не правильно. Прошу толкнуть в нужную сторону. Только по возможности подробнее, а то буду глупые вопросы задавать. ))
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

температура равна нулю и, подачи топлива нет, сначала печь надо выгнать в окно 500-700 градусов подавая топливо, так?

avgustdon
Offline
Зарегистрирован: 28.02.2016

Конечно. Для стартового варианта я предполагал это сделать вручную. Но ни в коем случае от помощи в этом направлении не отказываюсь. Разумеется автоматизация очень порадует. Особенно сам метод ее воплощения.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

То-есть нам надо симитировать обычный прибор с двумя уставками )))

А какое время требуется для выхода на 500 градусов?

avgustdon
Offline
Зарегистрирован: 28.02.2016

Насчет прибора не очень понял. А по температуре думаю за минут 5 выйдет на 500 гр. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

avgustdon пишет:

Насчет прибора не очень понял. А по температуре думаю за минут 5 выйдет на 500 гр. 

И удерживать в диапазоне от 500 до 700 подкидывая топливо?

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

avgustdon пишет:

Прошу толкнуть в нужную сторону. 

Судя по тому, как лихо Вы позволяете себе вот такие конструкции

avgustdon пишет:

 if (t = t2 && flag = true)

и не понимаете почему она

avgustdon пишет:
При компиляции ругается

правильная сторона для Вас находится вот здесь. Правильнее сейчас для Вас ничего нет.

 
avgustdon
Offline
Зарегистрирован: 28.02.2016

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

avgustdon
Offline
Зарегистрирован: 28.02.2016

ua6em пишет:

avgustdon пишет:

Насчет прибора не очень понял. А по температуре думаю за минут 5 выйдет на 500 гр. 

И удерживать в диапазоне от 500 до 700 подкидывая топливо?

Все верно. Только еще можно пороги температуры менять. А 500 гр. набирает за 5 мин. аж бегом. Проверил.

James
Offline
Зарегистрирован: 26.02.2016

Друже 1 знак равно - присваивание, для условия пишут два "=="

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

тогда в setup переносим включение печки, при включении когда температура менее 700 градусов подаём топливо, как только температура стала 700 и более отключаем реле и далее выходим в цикл loop

в цикле  реле включено на время подачи топлива когда температура менее 500 градусов и не более 700 градусов,как бы всё (да, временем подачи подобрать выключение подачи топлива по верхней температуре)

int relay_pin = 10;  
int relay = LOW ;            
int podacha = 1000; 
int t_min =500;
int t_max =700;
int t_tek =0;
int temperature_pin = 0 ;

void setup() {
  Serial.begin(9600);            // Скорость порта для отладки 
  Serial.println("WAIT!");
  pinMode(relay_pin, OUTPUT);
  analogReference(DEFAULT);
  while (analogRead(temperature_pin) <= t_max)
  {digitalWrite(relay_pin, relay);
  t_tek=analogRead(temperature_pin);
  Serial.print(t_tek);
  Serial.println("");
  delay(1000);
  }
  digitalWrite(relay_pin, !relay);
  
}

void loop() {
    Serial.println("IN WORKED");
    t_tek=analogRead(temperature_pin);
    Serial.print(t_tek);
    Serial.println("");
    if (t_tek <= t_min) {   digitalWrite(relay_pin, relay); delay(podacha); digitalWrite(relay_pin, !relay);}
    delay(1000); //опрос раз в секунду
}

Да, но разгонять будет не до максимальной вами определённой температуры, а до температуры, что успеет набрать за время подачи топлива, но не более чем максимальной, при максимальной подача выключится
Переменная relay определена исходя из применения стандартного блока реле с оптической развязкой, если нужно инвертировать, просто поменять на HIGH

Написал в лоб, не проверял, но уверен должно работать, так как никакой витиеватости кода нет )))

 

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ситуация напоминает кругосветное путешествия Ивана Сусанина, который шел домой. Автор топика запутался и всех остальных запутал. А так алгоритм простого гистерезиса и ничего сложного.

/* avgustdon.ino
#1 датчик температуры -> А5 (thermometer_pin)
#2 светодиод подача -> 10 (feed_pin) 1 есть подача/ 0 нет
*/
// #1 датчик температуры
const int thermometer_pin = A5; // пин термометра
int temperature;
const int temperature_min = 500;        // минимальное  значение температуры
const int temperature_max = 700;        // максимальное значение температуры
// #2 подача
const int feed_pin = 10; // пин подачи топлива
bool feed;// подача 1 идет подача/ 0 нет
const uint32_t runtime = 1000; //время частоты опроса температуры и выдачи команды 1 сек

void setup() {
  Serial.begin (9600);
  // #1 датчик температуры
  // #2 подача
  pinMode(feed_pin, OUTPUT);
  digitalWrite(feed_pin, feed=0);// до первого замера не вкл подачу
}
void loop() {
  static uint32_t past_1 = 0 ;
  if (millis() - past_1 >= runtime) { // если прошло
    past_1 = millis() ;
    // #1 датчик температуры
    temperature = analogRead(thermometer_pin);
    Serial.print("  t  ");
    Serial.println(temperature);
    // #2 подача
    if (temperature > temperature_max) {// если температура выше макс
      feed = 0;      //  то выключить подачу
      Serial.println(" Feed OFF ");
    }
    if (temperature < temperature_min) { // если температура ниже мин
      feed = 1;        //  то включить подачу
      Serial.println(" Feed ON ");
    }
    digitalWrite(feed_pin, feed);
  }
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Все переменные должны быть проинициализированы, еще раз ВСЕ!!!

Я не зря написал - analogReference(DEFAULT); //установить режим аналогового входа, по умолчанию он должен быть в этом режиме - НО НЕ ОБЯЗАН, то-есть может и не быть

кстати автор подачу топлива имеет желание организовать по времени ))) зачем - вопрос сложный, а в принципе схема реализуется на приборе из серии Ш45ХХ с двумя уставками (раздельными группами контактов)

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

DEFAULT: стандартное опорное напряжение 5 В (на платформах с напряжением питания 5 В) или 3.3 В (на платформах с напряжением питания 3.3 В) 

http://arduino.ru/Reference/AnalogReference

Если у вас параноя, то можно и так.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ua6em пишет:

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

Сколько раз заливал и игнорировал этот факт. Видно ,по умолчанию стоит измерение от встроенного опорного напряжения. Зачем делать то, о чем разработчики позаботились зарание.

avgustdon
Offline
Зарегистрирован: 28.02.2016

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

qwone пишет:

ua6em пишет:

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

Сколько раз заливал и игнорировал этот факт. Видно ,по умолчанию стоит измерение от встроенного опорного напряжения. Зачем делать то, о чем разработчики позаботились зарание.

Если работает - не зачем!
Я не проверял, непонятно зачем ввели эту команду... как-нибудь покопаю...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

avgustdon пишет:

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

а если не достигнет? ну это ваш скетч, 1-5 сек -  тогда сразу в цикл и не надо гнать до максимальной, и датчики температуры как-то несколько встороне созерцают происходящее:
 

int relay_pin = 10;  
int relay = LOW ;            
int podacha = 1000; 
int t_min =500;
int t_max =700;
int t_tek =0;
int temperature_pin = 0 ;

void setup() {

   Serial.begin(9600);            // Скорость порта для отладки 
   Serial.println("WAIT!");
   pinMode(relay_pin, OUTPUT);
 
   digitalWrite(relay_pin, relay);
   delay(podacha);
   digitalWrite(relay_pin, !relay)

}

void loop() { 

    Serial.println("IN WORKED");
    t_tek=analogRead(temperature_pin);
    if (t_tek >= t_min) {   digitalWrite(relay_pin, relay);  delay(podacha); digitalWrite(relay_pin, !relay);}
   
    Serial.print(t_tek);
    Serial.println("");
 
    delay(1000); //опрос раз в секунду
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

avgustdon пишет:

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

Вы запутались и народ запутали. Вам надо регулировать не вкл- выкл, а объем подачи. То есть использовать ШИМ алгоритм. Да ставить датчик огня. Само топливо тепло не дает, а только если горит. А вот если огня нет, то топливо зальет топку и все будет не очень.

avgustdon
Offline
Зарегистрирован: 28.02.2016

 Вы правы.  Я не достаточно корректно обрисовал задачу. Вот откорректированный вариант.

Задача управлять устройством загрузки твердого топлива (гранулы) в печь. Выглядит это так:

1.       Печь холодная. Растопка осуществляется вручную.

2.       Дальше топливо должно разгореться (температура поднимается) время достижения температуры 500гр порядка 5 мин.   Полагаю, этот порог температуры и следует считать минимальным. 

3.       По достижении заданной температуры включается загрузочное устройство, работает заданное время (1-5 сек), затем отключается. (первый цикл)

4.       Дальше дожидаемся разгорания топлива. Полагаю это 700 гр.  - второй уровень температуры, который необходимо контролировать. (одновременно считаем этот уровень номинальным для режима работы печи)

5.       И только после этого можно разрешать новый цикл подачи топлива, который состоится когда температура снова достигнет 500 гр. Топливо подаем циклами по 1-5 сек.

Вот вроде бы все точно. Возможно пропустил очевидные для себя подробности. Не стесняйтесь, помидоры принимаются в разумном количестве.)) 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Вы не можете повлиять на пункт 4, смысла контролировать 700 градусов, когда повлиять на это не можете, топливо в печи жеж )))

разве что поставить лампочку, что температура уже 700

 

avgustdon
Offline
Зарегистрирован: 28.02.2016

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Вот тут то флаг и потребуется, я поразмышляю, как без датчика огня обойтись

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

avgustdon пишет:

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

А если потухло? Включаем поддув?

avgustdon
Offline
Зарегистрирован: 28.02.2016

если не достигло 700 гр и потухло ничего не делаем (нет подтверждения разгорания). 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

avgustdon пишет:

1.       Печь холодная. Растопка осуществляется вручную.

Здесь надо предусмотреть кнопку , что растопка закончилась. Ведь растопка идет в ручную

Цитата:

2.       Дальше топливо должно разгореться (температура поднимается) время достижения температуры 500гр порядка 5 мин.   Полагаю, этот порог температуры и следует считать минимальным. 

3.       По достижении заданной температуры включается загрузочное устройство, работает заданное время (1-5 сек), затем отключается. (первый цикл)

Нужна индикация , что прошло 5 минут и температура 500 градусов достигла , пошла загрузка

Цитата:

 

4.       Дальше дожидаемся разгорания топлива. Полагаю это 700 гр.  - второй уровень температуры, который необходимо контролировать. (одновременно считаем этот уровень номинальным для режима работы печи)

Как контролировать температуру в 700 гр?  Если меньше 650 усиливать загрузку, а если больше 750 увеличить.

Цитата:

5.       И только после этого можно разрешать новый цикл подачи топлива, который состоится когда температура снова достигнет 500 гр. Топливо подаем циклами по 1-5 сек.

Как оно может достигнуть? если мы держим 700 гр?

ПС: Может вам нужен ручной регулятор подачи топлива. Разожли печь вышли на нужную температуру и выставили нужную подачу топлива и все.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Как то вот так: "в пианиста не стрелять, играет как может"

int relay_pin = 10;  
int relay = LOW ;            
int podacha = 1000; 
int t_min =500;
int t_max =700;
int t_tek =0;
int temperature_pin = 0 ;
int flag_t_max = 0;
int flag_zagruzki =0;


void setup() {
  Serial.begin(9600);            // Скорость порта для отладки 
  Serial.println("WAIT!");
  pinMode(relay_pin, OUTPUT);
  digitalWrite(relay_pin, !relay);
 // analogReference(DEFAULT);
 /* while (analogRead(temperature_pin) <= t_max)
  {digitalWrite(relay_pin, relay);
  t_tek=analogRead(temperature_pin);
  Serial.print(t_tek);
  Serial.println("");
  delay(1000);
  } */
    
}

void loop() {
    Serial.println("IN WORKED");
    t_tek=analogRead(temperature_pin);
    //if (t_tek >= t_max && flag_zagruzki==0){flag_t_max = 1;} // Топливо разгорелось
    if (t_tek >= t_max){flag_t_max = 1;} // Топливо разгорелось дальше ждать понижения

    Serial.print(t_tek);
    Serial.println("");
    while(analogRead(temperature_pin) >= t_min && flag_t_max == 1){
        Serial.println("IN WORKED");
        Serial.println(analogRead(temperature_pin));
       } // Ждём понижения температуры до нижнего порога
       
    if (flag_t_max ==1){
        digitalWrite(relay_pin, relay);
        delay(podacha); 
        digitalWrite(relay_pin, !relay);
         Serial.println("ZAGRUZHENO");
    
        flag_t_max=0;}   // подкинули дровишек
      
    delay(1000);         //опрос раз в секунду если разгорается
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Будет работать без кнопок, даже если в ручном режиме докачегарите выйдет в автомат )))

и подчистил от мусора

int relay_pin = 10;  
int relay = LOW ;            
int podacha = 1000; 
int t_min =500;
int t_max =700;
int t_tek =0;
int temperature_pin = 0 ;
int flag_t_max = 0;



void setup() {
  pinMode(relay_pin, OUTPUT);
  digitalWrite(relay_pin, !relay);   
}

void loop() {
      t_tek=analogRead(temperature_pin);
     if (t_tek >= t_max){flag_t_max = 1;} // Топливо разгорелось дальше ждать понижения
    while(analogRead(temperature_pin) >= t_min && flag_t_max == 1){
           } // Ждём понижения температуры до нижнего порога
       
    if (flag_t_max ==1){
        digitalWrite(relay_pin, relay);
        delay(podacha); 
        digitalWrite(relay_pin, !relay);
        flag_t_max=0;}   // подкинули дровишек
      
    delay(1000);         //опрос раз в секунду если разгорается
}

 

avgustdon
Offline
Зарегистрирован: 28.02.2016

qwone не знаю даже как отвечать на такую стопку вопросов. Некоторые улыбнули, а некоторые озадачили чем, что потребуют слишком подробного ответа и вполне возможно встречного вопроса и т.д. Зафлудим короче тему. Поэтому, если есть желание можем перенести общение скажем вот сюда home2461711@yandex.ru А конструктивные решения, если появятся, можно будет опубликовать в теме.

avgustdon
Offline
Зарегистрирован: 28.02.2016

ua6em, супер! Вы самый продуктивный помощьник в этом вопросе. Спасибо огромное.

На столе вроде все отрабатывает как надо. В работе буду пробовать чуть позже

Попробовал вывести текущую температуру на монитор. Выводит пока температура не достигнет верхнего предела. Потом вывод данных останавливается пока не достигнет нижнего предела. Хотелось бы иметь возможность наблюдать температуру постоянно. 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Прикрутить дисплей и выводить. если надо и, это правильное решение, в подчищенной версии выводить в строках 21 и 28...как то так...да пытался выравнять блок данных по сегменту в 32 байта...но компилятор конечно сильно неоптимален...2394 байта память программы и 190 байт динамической памяти это совсем не айс...мой оптимизированный драйвер для работы с дискетами был всего 1800 байт, при этом он работал напрямую с контроллером прямого доступа памяти, разбирал MBR и BR - ассемблер наше всё )))

КОД

#define temperature_pin  0
int relay_pin = 10;  
int relay = LOW ;            
int podacha = 1000; 
int t_min =500;
int t_max =700;
int t_tek =0;
int flag_t_max = 0;



void setup() {
  pinMode(relay_pin, OUTPUT);
  digitalWrite(relay_pin, !relay);  
  Serial.begin(9600);            // Скорость порта для отладки  
}

void loop() {
      t_tek=analogRead(temperature_pin);
     if (t_tek >= t_max){flag_t_max = 1;} // Топливо разгорелось выходим в автоматический режим
    while(analogRead(temperature_pin) >= t_min && flag_t_max == 1){
    Serial.println(analogRead(temperature_pin));      } // Ждём понижения температуры до нижнего порога
       
    if (flag_t_max ==1){
        digitalWrite(relay_pin, relay);
        delay(podacha); 
        digitalWrite(relay_pin, !relay);
        flag_t_max=0;}   // подкинули дровишек
    Serial.println(analogRead(temperature_pin));  
    delay(1000);         //опрос раз в секунду если разгорается
}

 

avgustdon
Offline
Зарегистрирован: 28.02.2016

Да! На столе работает все Ок. В работе отчитаюсь. Еще раз спасибо!

P.S. В следующий раз видимо будет прикручивание дисплея. Если сам не справлюсь.))

С Наступающим!

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Переработал код с #36

Код сложнее, но сюда можно прикрутить многое.

/*avgustdon.ino
//#1 датчик температуры -> A0(temperature_pin)
//#2 реле подачи -> 10 (relay_pin)  1 идет подача дров / 0 нет
   Принцип кода: 1 если температура достигла максимума, то огонь горит и если он прогорит, то можно подкинуть дров
                 2 если печь остыла и была раньше большая температура, то надо подкинуть немного дров 
*/
//#1 датчик температуры
const int temperature_pin = 0;
int temperature = 0;// текущая темература
const int t_min = 500; // мак температура
const int t_max = 700; // мин. температура
int regim = 0;//режим 0 - ждать пока достигнет макс темпер / 1 подкинуть дров и ждать пока они прогорят
//#2 реле подачи
const int relay_pin = 10;
int relay = 0 ;// состояние реле подачи 1 вкл / 2 выкл
const int time_podacha = 1000;// длительность подачи в миллисек

void setup() {
  Serial.begin(9600);            // Скорость порта для отладки
  //#1 датчик температуры
  temperature = analogRead(temperature_pin);
  //#2 реле подачи
  pinMode(relay_pin, OUTPUT);
  digitalWrite(relay_pin, 0);// выкл реле
}

void loop() {
  //#1 датчик температуры меряем раз в секунду
  static uint32_t past_1 = 0 ;
  if (millis() - past_1 >= 1000) { // если прошло 1000 миллисек=1 секунде
    past_1 = millis()  ;
    temperature = analogRead(temperature_pin);
    Serial.println(analogRead(temperature_pin));
  }
  //#2 реле подачи опрос раз 10 сек
  static uint32_t past_2 = 0 ;
  if (relay && millis() - past_2 >= time_podacha)  // если идет подача дров и подошло время ее выключить
    digitalWrite(relay_pin, relay = 0); // то выключить подачу

  if (millis() - past_2 >= 10000) { // если прошло 10000 миллисек=10 секунде
    past_2 = millis()  ;
    if (regim = 0 && temperature >= t_max) // если был начальный режим и темпер. стала больше макс
      regim = 1; // Топливо разгорелось выходим в автоматический режим
    if (regim = 1 && temperature < t_min) { // если режим автоматический и температература упала
      digitalWrite(relay_pin, relay = 1); //  то включить подачу дров
      regim = 0;// и включить временой маркер окончания подачи дров
    }
  }
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

qwone пишет:

Переработал код с #36

Код сложнее, но сюда можно прикрутить многое.

/*avgustdon.ino
//#1 датчик температуры -> A0(temperature_pin)
//#2 реле подачи -> 10 (relay_pin)  1 идет подача дров / 0 нет
   Принцип кода: 1 если температура достигла максимума, то огонь горит и если он прогорит, то можно подкинуть дров
                 2 если печь остыла и была раньше большая температура, то надо подкинуть немного дров 
*/
//#1 датчик температуры
const int temperature_pin = 0;
int temperature = 0;// текущая темература
const int t_min = 500; // мак температура
const int t_max = 700; // мин. температура
int regim = 0;//режим 0 - ждать пока достигнет макс темпер / 1 подкинуть дров и ждать пока они прогорят
//#2 реле подачи
const int relay_pin = 10;
int relay = 0 ;// состояние реле подачи 1 вкл / 2 выкл
const int time_podacha = 1000;// длительность подачи в миллисек

void setup() {
  Serial.begin(9600);            // Скорость порта для отладки
  //#1 датчик температуры
  temperature = analogRead(temperature_pin);
  //#2 реле подачи
  pinMode(relay_pin, OUTPUT);
  digitalWrite(relay_pin, 0);// выкл реле
}

void loop() {
  //#1 датчик температуры меряем раз в секунду
  static uint32_t past_1 = 0 ;
  if (millis() - past_1 >= 1000) { // если прошло 1000 миллисек=1 секунде
    past_1 = millis()  ;
    temperature = analogRead(temperature_pin);
    Serial.println(analogRead(temperature_pin));
  }
  //#2 реле подачи опрос раз 10 сек
  static uint32_t past_2 = 0 ;
  if (relay && millis() - past_2 >= time_podacha)  // если идет подача дров и подошло время ее выключить
    digitalWrite(relay_pin, relay = 0); // то выключить подачу

  if (millis() - past_2 >= 10000) { // если прошло 10000 миллисек=10 секунде
    past_2 = millis()  ;
    if (regim = 0 && temperature >= t_max) // если был начальный режим и темпер. стала больше макс
      regim = 1; // Топливо разгорелось выходим в автоматический режим
    if (regim = 1 && temperature < t_min) { // если режим автоматический и температература упала
      digitalWrite(relay_pin, relay = 1); //  то включить подачу дров
      regim = 0;// и включить временой маркер окончания подачи дров
    }
  }
}

Всё должно быть сделано просто, насколько возможно, но не проще А Эйнштейн
Все сложное – не нужно, все нужное – просто. М. Калашников

PS не думаю, что сложно будет прикрутить дисплей, остались непонятки, что за топливо )))
С Новым Годом!!!

 

avgustdon
Offline
Зарегистрирован: 28.02.2016

C Новым Годом! 

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

По прикручиванию дисплея скорее всего придется обращаться снова. По крайней мере попытки сделать это пока успехом не увенчались. Имею для этого светодиодные матрицы по 4 сегмента и расширитель выходов НС595. Сначала просто индикация температуры горения, потом индикация нижнего и верхнего порогов и режим установки параметров с клавиатуры (есть клава 4х4 мембранная от китайцев). Как-то так. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну с дисплееем просто

/* counter.ino
Пример использования 4-х значного 7-ми сегментного индикатора на многофункциональной плате
 Multi_function_Shield
2х МС74НС595 АD ->4 семисегментных индикатора
QA1-1;QB1-2;QC1-3;QD1-4;QE1-NC;QF1-NC;QG1-NC;QH1-NC
QA2-a;QB2-b;QC2-c;QD2-d;QE2-e; QF2-f; QG2-g; QH2-h
      DATA  ->8  (Data_pin)
       CLK  ->7  (CLK_pin)
     LATCH  ->4  (LATCH_pin)
*/
//#1 счетчик
uint8_t Count; // счетчик
//#2
const int Latch_pin=4;
const int CLK_pin  =7;
const int Data_pin =8;
// матрица цифр 0 to 9 
const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};
// матрица выбора знакоместа 1 to 4 
const byte SEGMENT_SELECT[] = {0xF1,0xF2,0xF4,0xF8};
// Вывод числа на экран
void WriteNumber(int Number) {
  WriteNumberToSegment(0 , Number / 1000);
  WriteNumberToSegment(1 , (Number / 100) % 10);
  WriteNumberToSegment(2 , (Number / 10) % 10);
  WriteNumberToSegment(3 , Number % 10);
}
// запись нужного числа (0-9) в нужную позицию(1-4) 
void WriteNumberToSegment(byte Segment, byte Value){
  digitalWrite(Latch_pin,0); 
  shiftOut(Data_pin, CLK_pin, MSBFIRST, SEGMENT_MAP[Value]);
  shiftOut(Data_pin, CLK_pin, MSBFIRST, SEGMENT_SELECT[Segment] );
  digitalWrite(Latch_pin,1);    
}

void setup ()  {
  //#1
  Count = 0;
  //#2
  pinMode(Latch_pin,OUTPUT);
  pinMode(CLK_pin,OUTPUT);
  pinMode(Data_pin,OUTPUT); 
}
void loop(){
  static uint32_t MILLIS ;
  MILLIS = millis() ;
  //#1   100 милисек счетчик 
  static uint32_t past_1 = 0 ;
  if (MILLIS - past_1 >= 100) { // если прошло 100 миллисек
    past_1 = MILLIS ;
    Count++;
    if(Count > 9999) Count = 0;
    }
  //#2 непрерывно дисплей
  WriteNumber(Count);
}

ПС:http://www.youtube.com/watch?v=g3kFEgPxT2E

avgustdon
Offline
Зарегистрирован: 28.02.2016

Осталось добыть Multi_function_Shield ))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

avgustdon пишет:

Осталось добыть Multi_function_Shield ))

А схему Multi_function_Shield из инета скачать видно не реально. и реализовать на ваших компонентах и только регистры и матрицы.

avgustdon
Offline
Зарегистрирован: 28.02.2016

Реально конечно. Пока еще не разбирался. Было несколько попыток создать индикатор на семисегментах и регистре. Там вроде попроще чем в вашем скетче. От этого и пляшу. Вполне возможно следующая попытка будет создать свой мультишилд.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

http://yadi.sk/i/Rnj8T3hsunvky    Подключить как здесь индикатор и 2 региста вам сложно. Почему я ссылку на ютуб дал. там ссылка на схему.

avgustdon
Offline
Зарегистрирован: 28.02.2016

Да не сложно конечно. Я же говорю не разбирался. Все посмотрим, все попробуем. За ссылку спасибо большое.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Для двухстрочного LCD 1602 I2C дисплея, тот что в китае за 125 рублей

Будет попроще ))) Кстати самое сложное в Вашем устройстве - механика и пож. безопасность, скетч дело пустяковое

 

#define temperature_pin  0
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int relay_pin = 10;  
int relay = LOW ;            
int podacha = 1000; 
int t_min =500;
int t_max =700;
int t_tek =0;
int flag_t_max = 0;

//Дисплей
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void PLCD(){
  lcd.clear();
  lcd.home ();                   // В Начальную позицию дисплея
  lcd.print("TEMPERATURE- ");
  lcd.print(analogRead(temperature_pin));
  lcd.setCursor(0, 1);
  if(flag_t_max == 1){
  lcd.print("  <<<-DOWN-<<<  ");
  }else {
  lcd.print("  >>>--UP-->>>  ");
  }
  } // Конец подпрограммы вывода температуры на дисплей

  
void setup() {
  pinMode(relay_pin, OUTPUT);
  digitalWrite(relay_pin, !relay);  
  Serial.begin(9600);            // Скорость порта для отладки  
  lcd.begin(16,2);
}

void loop() {
      t_tek=analogRead(temperature_pin);
     if (t_tek >= t_max){flag_t_max = 1;} // Топливо разгорелось выходим в автоматический режим
    while(analogRead(temperature_pin) >= t_min && flag_t_max == 1){
    Serial.println(analogRead(temperature_pin));  
    PLCD(); delay(2000); }                // Ждём понижения температуры до нижнего порога
       
    if (flag_t_max ==1){
        digitalWrite(relay_pin, relay);
        delay(podacha); 
        digitalWrite(relay_pin, !relay);
        flag_t_max=0;}   // подкинули дровишек
    Serial.println(analogRead(temperature_pin));  
    PLCD();
    delay(1000);         //опрос раз в секунду если разгорается
}

 

avgustdon
Offline
Зарегистрирован: 28.02.2016

Тоже спасибо большое! Примерялся к двухстрочному, но у него маленькие знаки и при ярком освещении их плохо видно. То и другое важно. Механику и пож безопасность это первое что решили. Для меня как раз это дело пустяковое.)))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

avgustdon пишет:

Тоже спасибо большое! Примерялся к двухстрочному, но у него маленькие знаки и при ярком освещении их плохо видно. То и другое важно. Механику и пож безопасность это первое что решили. Для меня как раз это дело пустяковое.)))

Да нормально видно, я на синем смотрю, даже скажу чрезмерно ярко, если смотрели скетч, то в верхней строке выводится температура, в нижней - состояние, чего ждём ))) разжигания или прогорания, а большего и не нужно на первых порах, по идее надо бы ввести автоматический режим, который сам подберёт определённый режим загрузка - розжиг - горение в зависимости от топлива с возможностью записи в память программ контроллера, останется только выбрать нужную программу по виду топлива в рабочем режиме

Мы делали контроллеры но несколько для других вещей, там было 32 программы и всё это реализовывалось на PIC16F84 а он значительно скромнее по ресурсам )))

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

PS код как рыба - рабочий, но дюже криво написан, особенно вывод на дисплей ))) что называется в лоб

avgustdon
Offline
Зарегистрирован: 28.02.2016

Согласен, буду вариант двухстрочного иметь ввиду, но в нашем варианте важно чтобы видно было издалека. Я например, с 5 метров его показания не увижу, а подходить неудобно, ну и так далее. Он конечно более информативный чем семисегмент, потому и держу его на прицеле. Но пока однозначно семисегмент. Даже пытаюсь найти исполнение покрупнее. Что касается автоматического режима. Еще не понимаю как его реализовать, но чувствую, что надо. Разберемся с первичной автоматикой и индикацией и будем штурмовать следующий этап.