Алгоритм терморегулятора

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

Здесь TEN_Temp_FLAG - признак работы нагрева
id05 - установленное значение нагрева (до какой температуры греть)
Water_T - текущее значение температуры.
5 - значение гистерезиса

  if (Water_T >= id05){TEN_Temp_FLAG = 0;}else{                              
    if (Water_T <= (id05-5)){TEN_Temp_FLAG = 1;};                          
  };  

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

bool ohl=0;

  if(Water_T >= id05){TEN_Temp_FLAG = 0;ohl=1;}
  else
  {
    if(ohl==1){ if(Water_T <= (id05-5)){ohl=0;}; }else{TEN_Temp_FLAG = 1;};
  };

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

Это наверное, должен быть типовой алгоритм. как лучше (стандартнее)?

Ответить, что и как лучше с такими куцыми входными данными невозможно. Многое зависит от инерционности нагревателя, от конфигурации нагревательных элементов (точечный нагрев, многозонный и т.п.). А так - это просто болтовня “в пользу бедных”.

Попробуйте почитать статью (она там начинается внизу первой страницы файла - найдёте). Вот там и написано

1 лайк

у меня нет таких жестких условий по стабилизации температуры.

Я делаю обычный бойлер для нагрева воды для дома.

Ну, тогда Вам нет никакой разницы

Как нагреете, так и нагреете.

1 лайк

просто переменную TEN_Temp_FLAG при старте устройства (в setup например) инициализируйте сразу в true или 1 по вашему…

А само условие можно сократить так (не обязательно):
void setup() {

  • TEN_Temp_FLAG =1;*
    }

void loop() {

  • TEN_Temp_FLAG = Water_T >= id05 && Water_T <= (id05-5);*

    }
    ЭТО НЕ ВЕРНО! Ниже в теме исправил

Интересно, при каких условиях TEN_Temp_FLAG будет равна true? ))

Ну да, с заменой условия я что-то тупанул… только с ночи приехал, моск спит))

Оставить значит как есть условие из первого поста и первого варианта…

Вот

TEN_Temp_FLAG = Water_T < id05 && TEN_Temp_FLAG || Water_T <= (id05-5);

  1. Определить , растёт температура, или падает.

  2. В зависимости от №1 - выбрать порог переключения

bool TEN_Temp_FLAG = true;
byte id05 = 50;
byte Water_T = 60; //Пробуем любое стартовое значение

void setup() {
  Serial.begin(115200);
}

void loop() {
  bool lastTEN_Temp_FLAG = TEN_Temp_FLAG;

  TEN_Temp_FLAG = Water_T < id05 && TEN_Temp_FLAG || Water_T <= (id05 - 15);

  if (TEN_Temp_FLAG != lastTEN_Temp_FLAG) {
    Serial.print("Temp: "); Serial.print(Water_T);
    Serial.print("°C Ten: "); Serial.println(TEN_Temp_FLAG ? "On" : "Off");
  }
  delay(200);
  if (TEN_Temp_FLAG) Water_T += 2; else Water_T -= 3;
}

Ключевой момент вопроса это - bool TEN_Temp_FLAG = true;
А замена условия - это второстепенно…

Интересно, как это температуре расти, если устройство только включено.

Очень просто. Первое значение - минимальная температура.
Значит после включения будет всегда расти.

const int heatPin=5;
int currentTemp=0;
int setTemp=55;
int histeresisVal=5;

void setup(){
    pinMode(heatPin,OUTPUT);
}

void loop(){
    //currentTemp=readTemp(); //сам напишешь   
       if(currentTemp<setTemp-histeresisVal)digitalWrite(heatPin,1);        
       if(currentTemp>=setTemp){digitalWrite(heatPin,0);
}

Что заставляет вас так думать ?
По мне так вообще не факт.

Как будто это что-то плохое ))

У мну есть такой)

void loop(){
    //currentTemp=readTemp(); //сам напишешь   
     digitalWrite(heatPin, currentTemp < setTemp);        
}

-Тааак, а где же гистерезис?
-Он есть! Равен разрешению датчика температуры! Для например ds18b20 его можно устанавливать от 1/16 до 0.5 С. И даже больше - 1, 2, 4 С.

Тогда уж вот так:

digitalWrite(heatPin, Water_T < id05 && digitalRead(heatPin)|| Water_T <= (id05 - 5));
и гистерезис на месте… но самое главное “в начале программы” сделать digitalWrite(heatPin, HIGH); Но лучше использовать переменную, чтобы лишний раз не щелкать реле (Тэном)
:wink:
Хотя как уже замечено, что особо смысла в этом нет, но это просто ответ на вопрос тс.

Я как то пытался составить алгоритм для отопления в теплице. Собрал макет. Картонная коробка 50х40х40 см, у нее открывается дверца, верх прозрачный, сверху лампа накаливания 100 Вт типа солнце. Тен от микроволновки запитан от бп 36 В. Около 40 Вт. Это все близко к реальным условиям. Регулятор должен поддерживать Т и обеспечивать плавный рост или падение Т с установленной скоростью. Причем, Т воздуха начинала рости через минуту после вкл. Тена и стабилизировалась через 40 сек после откл. Во где раздолье)))

тут либо PID… либо скорректировать верхние и нижние границы вкл/откл

Вот так правильно, ну

const int heatPin=5;int currentTemp=0,setTemp=55,histeresisVal=5;void setup(){pinMode(heatPin,OUTPUT);}void loop(){if(currentTemp<setTemp-histeresisVal)digitalWrite(heatPin,1);if(currentTemp>=setTemp)digitalWrite(heatPin,0);