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

Altar
Offline
Зарегистрирован: 08.12.2017

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

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

ну ваш код я бы написал так 

/**/
unsigned long mill; // переменная под millis()
int temproom = 25; //объявляем переменную текущая температура в комнате
//--------------------------------
// класс регулятор
class Cl_regulator {
  protected:
    const byte pin;
    int temp;
    int setTemp;
  public:
    /*конструктор*/
    Cl_regulator(byte pin_, int &temp_, int setTemp_): pin(pin_), temp(temp_), setTemp(setTemp_) {}
    /*инициализация-вставить в setup()*/
    void init() {
      pinMode (pin, OUTPUT);
    }
    /*работа-вставить в loop()*/
    void run() {
      if (temp >= setTemp)digitalWrite (pin, LOW);
      else digitalWrite (pin, HIGH);
    }
};
//---Компоновка-----------------------------
Cl_regulator Radiator(/*пин*/3,/*температура в комнате*/temproom,/*темпер сраб*/24);//подключаем радиатор на 3-й пин
Cl_regulator Warm_floor(/*пин*/4,/*температура в комнате*/temproom,/*темпер сраб*/23); //подключаем pol на 4-й пин
//---main-----------------------------
void setup() {
  Serial.begin(9600); // открываем порт для имитации показаний с датчика температуры
  Radiator.init();
  Warm_floor.init();
}
void loop() {
  mill = millis();
  Radiator.run();
  Warm_floor.run();
  if (Serial.available () > 0) {// для работы с портом
    temproom = Serial.parseInt (); // чтобы переменная принимала цифровые значения
    Serial.println (temproom); // чтобы видеть, что ввел
  }
}
/*Скетч использует 2582 байт (8%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 202 байт (9%) динамической памяти, оставляя 1846 байт для локальных переменных. Максимум: 2048 байт.
*/

 

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

Altar пишет:

Не совсем понял про регулятор. Ощущаемая температура будет колебаться, согласен.

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

Почитайте про ПИД-регулирование.

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

Altar, во-первых, Вы устанавливаете режим на оснеовании только текущей температуры, не принимая во внимание, что было до этого. (В Вашей терминологии - в Москву Вы едете или в Ярославль)

Во-вторых, Ваша программа чувствительна к погрешностям измерения.

В-третьих, она не учитывает тепловую инерционность помещения.

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

Altar
Offline
Зарегистрирован: 08.12.2017

Я не настаиваю на своей программе. Это только мои первые шаги. Буду разбиратьсмя дальше с ПИД-регулированием в том числе.

Что касается учета того, что было до этого, то здесь я не согласен. То, как я описал алгоритм работм в первом посте, этой программой прекрасно выполняется. История заложена последовательностью выполнения, и оно, блин, работает. Если не трудно проверьте. Я меняю температуру так, как бы она изменялась в реальности в идеальных условиях. Пришли холода в комнате +22 нужно +25, я включаю ардуино первый раз и включаются оба выхода. +23 включены оба +24 включены оба, +25 оба выключены, +24 вклечен пол, +25 выключен пол, +24 включен пол, +23 дополнительно включается радиатор, +24 оба включены так как мы понимаем, что пол не справляется и отключив сейчас радиатор температура опять упадет, +25 оба выключены.

Что касается 2, 3, 4 пунктов согласен полностью.

Еще раз повторюсь, я не настаиваю на единственно верном своем решении. Все мои несогласия с вами - это попытка разобраться и научиться, поэтому я и написал на форум. То решение, котрое написал qwone, для меня вообще темный лес, пока. Буду разбираться.

Спасибо! 

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

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

/**/
unsigned long mill;//переменная для millis()
int roomTemp = 25; //объявляем переменную текущая температура в комнате
//----определение и описание-----------------
// класс регулятор
class Cl_Adjustor {
  protected:
    byte pin;
    int *value;
    int Min, Max;
    unsigned long past;
  public:
    /*конструктор*/
    Cl_Adjustor(byte p, int *v, int mi, int ma)
      : pin(p), value(v),  Min(mi), Max(ma) {}
    /*инициализация-вставить в setup()*/
    void init() {
    }
    /*работа-вставить в loop()*/
    void run() {
      if (mill - past >= 500) {
        past = mill;
        *value = map(analogRead(pin), 0, 1023, Min, Max);
        Serial.println(*value);
      }
    }
};
//--------------------------------
// класс регулятор
class Cl_regulator {
  protected:
    const byte pin;
    int *temp;
    int setTemp;
    unsigned long past;
  public:
    /*конструктор*/
    Cl_regulator(byte p, int *t, int s): pin(p), temp(t), setTemp(s) {}
    /*инициализация-вставить в setup()*/
    void init() {
      pinMode (pin, OUTPUT);
    }
    /*работа-вставить в loop()*/
    void run() {
      if (mill - past >= 500) {
        past = mill;
        if (*temp >= setTemp) {
          digitalWrite (pin, LOW);
        }
        else {
          digitalWrite (pin, HIGH);
        }
      }
    }
};
//-----Компоновка----------------
Cl_Adjustor Adjustor(/*пин*/A0,/*значение*/&roomTemp,/*min*/10,/*max*/30);
Cl_regulator Radiator(/*пин*/13,/*температура в комнате*/&roomTemp,/*темпер сраб*/20);//подключаем радиатор на 13-й пин
Cl_regulator Warm_floor(/*пин*/4,/*температура в комнате*/&roomTemp,/*темпер сраб*/23); //подключаем pol на 4-й пин
//----main-----------------
void setup() {
  Serial.begin(9600);
  Adjustor.init();
  Radiator.init();
  Warm_floor.init();
}
void loop() {
  mill = millis();
  Adjustor.run();
  Radiator.run();
  Warm_floor.run();
}
/*Скетч использует 2570 байт (8%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 221 байт (10%) динамической памяти, оставляя 1827 байт для локальных переменных. Максимум: 2048 байт.
*/

 

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

Ну и наконец уже скетч с ШИМ.

/**/
unsigned long mill;//переменная для millis()
int roomTemp = 25; //объявляем переменную текущая температура в комнате
//----определение и описание-----------------
// класс регулятор
class Cl_Adjustor {
  protected:
    byte pin;
    int *value;
    int Min, Max;
    unsigned long past;
  public:
    /*конструктор*/
    Cl_Adjustor(byte p, int *v, int mi, int ma)
      : pin(p), value(v),  Min(mi), Max(ma) {}
    /*инициализация-вставить в setup()*/
    void init() {
    }
    /*работа-вставить в loop()*/
    void run() {
      if (mill - past >= 500) {
        past = mill;
        *value = map(analogRead(pin), 0, 1023, Min, Max);
        Serial.println(*value);
      }
    }
};
//--------------------------------
// класс регулятор
class Cl_regulator {
  protected:
    char *name;
    const byte pin;
    int *temp;
    int MinTemp, MaxTemp;
    const unsigned long intervalPSW = 2000;
    unsigned long past, intervalON, intervalOFF;
    byte state;/*0-анализировать/1-вкл/2-откл*/
    /*установить*/
    void stand(byte s) {
      state = s;
      past = mill;
      switch (s) {
        case 0:
          if (*temp >= MaxTemp) {// если сильно жарко
            intervalON = 0; intervalOFF = intervalPSW; stand(2);
            Serial.println("PSW =0");
          }
          else if (*temp <= MinTemp) { // если очень холодно
            intervalON = intervalPSW; intervalOFF = 0; stand(1);
            Serial.println("PSW =100");
          }
          else {
            int PSW = 100 * (MaxTemp - *temp) / (MaxTemp - MinTemp);
            intervalON = intervalPSW * PSW / 100; intervalOFF = intervalPSW * (100 - PSW) / 100 ; stand(1);
            Serial.print(name);
            Serial.print("  PSW =");
            Serial.print(PSW);
            Serial.println();
          }
          break;
        case 1:
          digitalWrite (pin, HIGH);
          break;
        case 2:
          digitalWrite (pin, LOW);
          break;
      }
    }
  public:
    /*конструктор*/
    Cl_regulator(char *n, byte p, int *t, int mi, int ma)
      : pin(p), temp(t), MinTemp(mi), MaxTemp(ma) {
      int len = strlen(n) + 1;
      name = new char[len];
      strncpy(name, n, len);
    }
    /*инициализация-вставить в setup()*/
    void init() {
      pinMode (pin, OUTPUT);
    }
    /*работа-вставить в loop()*/
    void run() {
      if (state == 0)stand(1);
      if (state == 1 && mill - past >= intervalON)stand(2);
      if (state == 2 && mill - past >= intervalOFF)stand(0);
    }
};
//-----Компоновка----------------
Cl_Adjustor Adjustor(/*пин*/A0,/*значение*/&roomTemp,/*min*/10,/*max*/30);
Cl_regulator Radiator(/*имя*/"Radiator",/*пин*/13,/*температура в комнате*/&roomTemp,/*min*/20,/*max*/27);//подключаем радиатор на 13-й пин
Cl_regulator Warm_floor(/*имя*/"Warm_floor",/*пин*/4,/*температура в комнате*/&roomTemp,/*min*/20,/*max*/27); //подключаем pol на 4-й пин
//----main-----------------
void setup() {
  Serial.begin(9600);
  Adjustor.init();
  Radiator.init();
  Warm_floor.init();
}
void loop() {
  mill = millis();
  Adjustor.run();
  Radiator.run();
  Warm_floor.run();
}
/*Скетч использует 4020 байт (13%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 309 байт (15%) динамической памяти, оставляя 1739 байт для локальных переменных. Максимум: 2048 байт.
*/

 

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

Чуть подправил программу.

/**/
unsigned long mill;//переменная для millis()
int roomTemp = 25; //объявляем переменную текущая температура в комнате
//----определение и описание-----------------
// класс регулятор
class Cl_Adjustor {
  protected:
    byte pin;
    int &value;
    int Min, Max;
    unsigned long past;
  public:
    /*конструктор*/
    Cl_Adjustor(byte p, int &v, int mi, int ma)
      : pin(p), value(v),  Min(mi), Max(ma) {}
    /*инициализация-вставить в setup()*/
    void init() {
    }
    /*работа-вставить в loop()*/
    void run() {
      if (mill - past >= 500) {
        past = mill;
        value = map(analogRead(pin), 0, 1023, Min, Max);
        Serial.println(value);
      }
    }
};
//--------------------------------
// класс регулятор
#define ON_ HIGH // уровень вкл
class Cl_regulator {
  protected:
    char *name;
    const byte pin;
    int &temp;
    int MinTemp, MaxTemp;
    const unsigned long intervalPSW = 2000;
    unsigned long past, intervalON, intervalOFF;
    byte state;/*0-анализировать/1-вкл/2-откл*/
    /*установить*/
    void stand(byte s) {
      state = s;
      past = mill;
      switch (s) {
        case 0:
          if (temp >= MaxTemp) {// если сильно жарко
            intervalON = 0; intervalOFF = intervalPSW; stand(2);
            Serial.println("PSW =0");
          }
          else if (temp <= MinTemp) { // если очень холодно
            intervalON = intervalPSW; intervalOFF = 0; stand(1);
            Serial.println("PSW =100");
          }
          else {
            int PSW = 100 * (MaxTemp - temp) / (MaxTemp - MinTemp);
            intervalON = intervalPSW * PSW / 100; intervalOFF = intervalPSW * (100 - PSW) / 100 ; stand(1);
            Serial.print(name);
            Serial.print("  PSW =");
            Serial.print(PSW);
            Serial.println();
          }
          break;
        case 1:
          digitalWrite (pin, ON_);
          break;
        case 2:
          digitalWrite (pin, !ON_);
          break;
      }
    }
  public:
    /*конструктор*/
    Cl_regulator(char *n, byte p, int &t, int mi, int ma)
      : pin(p), temp(t), MinTemp(mi), MaxTemp(ma) {
      int len = strlen(n) + 1;
      name = new char[len];
      strncpy(name, n, len);
    }
    /*инициализация-вставить в setup()*/
    void init() {
      pinMode (pin, OUTPUT);
    }
    /*работа-вставить в loop()*/
    void run() {
      if (state == 0)stand(1);
      if (state == 1 && mill - past >= intervalON)stand(2);
      if (state == 2 && mill - past >= intervalOFF)stand(0);
    }
};
//-----Компоновка----------------
Cl_Adjustor Adjustor(/*пин*/A0,/*значение*/roomTemp,/*min*/10,/*max*/30);
Cl_regulator Radiator(/*имя*/"Radiator",/*пин*/13,/*температура в комнате*/roomTemp,/*min*/20,/*max*/27);//подключаем радиатор на 13-й пин
Cl_regulator Warm_floor(/*имя*/"Warm_floor",/*пин*/4,/*температура в комнате*/roomTemp,/*min*/20,/*max*/27); //подключаем pol на 4-й пин
//----main-----------------
void setup() {
  Serial.begin(9600);
  Adjustor.init();
  Radiator.init();
  Warm_floor.init();
}
void loop() {
  mill = millis();
  Adjustor.run();
  Radiator.run();
  Warm_floor.run();
}
/*Скетч использует 4020 байт (13%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 309 байт (15%) динамической памяти, оставляя 1739 байт для локальных переменных. Максимум: 2048 байт.
*/

 

Altar
Offline
Зарегистрирован: 08.12.2017

 

Спасибо огромное, буду разбираться.