минимальный и максимальный предел

fayvlad
Offline
Зарегистрирован: 27.03.2014

Здравствуйте, такое тут дело... В общем сделал для аквариума (точнее для отсадника)  термометр-обогреватель. Все навесным монтажом. Прицепил сегментный светодиодный индикатор для отображения температуры, датчик температуры 18b20 (в виде транзистора - залил термоклеем контакты и под термоусадку), реле и резистор на 10 Ом 2 ват (резистор тоже в термоусадку и хорошенько придавил, там где изолятор провода начинается). Накидал быстро скетч, прошил, использовал неделю и закинул т.к. рыбки подросли.

Сейчас опять пришлось использовать все это, но проблема вот в чем - программу написал, что если температура ниже 25градусов - включать релюшку, но воб бида в том, что когда этот момент приходит 24-25 градусов релюшка клацает раз 10-15, пока не прогреет стабильные 25 градусов. Ночью это чуток мешает.

Вот сама суть вопроса, как выставить в программе минимальное и максимальное значение, чтобы при 25 - больше не грело, а при 23 - включалось, но и так, чтобы потом не клацло при 23-24градуса.

Тоисть чтобы гредо до 25 градусов, отключалось, а потом при 23 - включалось. Понимаю, это должно быть очень легко, но мой разум это не может сформулировать.

#define ANODE // закомментируйте или удалите, если у вас общий катод
#if defined (ANODE)
#define SEGMENTS LOW
#define GRIDS HIGH
#elif
#define GRIDS LOW
#define SEGMENTS HIGH
#endif
#include <OneWire.h>
OneWire ds(10);
const int d1 = 8; 
const int d2 = 9; 
const int a = 7; 
const int b = 6; 
const int c = 5; 
const int d = 4; 
const int e = 3; 
const int f = 2; 
const int g = 11; 
int myTemp;
byte relay = 12;

void setup() {
pinMode(a, OUTPUT); 
pinMode(b, OUTPUT); 
pinMode(c, OUTPUT); 
pinMode(d, OUTPUT); 
pinMode(e, OUTPUT); 
pinMode(f, OUTPUT); 
pinMode(g, OUTPUT); 
pinMode(d1, OUTPUT); 
pinMode(d2, OUTPUT);
pinMode(13, OUTPUT); 
pinMode(relay, OUTPUT); 
initos();
none();
}


void loop() 
{
int offrelay = printTemp();
if(offrelay<25) {
digitalWrite(relay, HIGH);
digitalWrite(13, HIGH);}
else {digitalWrite(relay, LOW);digitalWrite(13, LOW);}
}


int getTemp()
{
byte data[2];
ds.reset(); 
ds.write(0xCC);
ds.write(0x44);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data[0] = ds.read(); 
data[1] = ds.read();
int Temp = (data[1]« 8)+data[0];
Temp = Temp»4;
if (Temp>0&&Temp<80) return Temp;
}

void one () 
{ 
digitalWrite(b,SEGMENTS);
digitalWrite(c,SEGMENTS);
}

void two () 
{ 
digitalWrite(a,SEGMENTS);
digitalWrite(b,SEGMENTS);
digitalWrite(g,SEGMENTS);
digitalWrite(e,SEGMENTS);
digitalWrite(d,SEGMENTS);
}

void three () 
{ 
digitalWrite(a,SEGMENTS);
digitalWrite(b,SEGMENTS);
digitalWrite(g,SEGMENTS);
digitalWrite(c,SEGMENTS);
digitalWrite(d,SEGMENTS);
}

void four () 
{ 
digitalWrite(c,SEGMENTS);
digitalWrite(b,SEGMENTS);
digitalWrite(g,SEGMENTS);
digitalWrite(f,SEGMENTS);
}
void five () 
{ 
digitalWrite(a,SEGMENTS);
digitalWrite(f,SEGMENTS);
digitalWrite(g,SEGMENTS);
digitalWrite(c,SEGMENTS);
digitalWrite(d,SEGMENTS);
}
void six () 
{ 
digitalWrite(a,SEGMENTS);
digitalWrite(e,SEGMENTS);
digitalWrite(g,SEGMENTS);
digitalWrite(c,SEGMENTS);
digitalWrite(d,SEGMENTS);
digitalWrite(f,SEGMENTS);
}
void seven () 
{ 
digitalWrite(b,SEGMENTS);
digitalWrite(c,SEGMENTS);
digitalWrite(a,SEGMENTS);
}
void eight () 
{ 
digitalWrite(a,SEGMENTS);
digitalWrite(f,SEGMENTS);
digitalWrite(g,SEGMENTS);
digitalWrite(c,SEGMENTS);
digitalWrite(d,SEGMENTS);
digitalWrite(e,SEGMENTS);
digitalWrite(b,SEGMENTS);
}
void nine () 
{ 
digitalWrite(a,SEGMENTS);
digitalWrite(b,SEGMENTS);
digitalWrite(c,SEGMENTS);
digitalWrite(d,SEGMENTS);
digitalWrite(g,SEGMENTS);
digitalWrite(f,SEGMENTS);
}
void zero () 
{ 
digitalWrite(a,SEGMENTS);
digitalWrite(b,SEGMENTS);
digitalWrite(f,SEGMENTS);
digitalWrite(c,SEGMENTS);
digitalWrite(d,SEGMENTS);
digitalWrite(e,SEGMENTS);
}
void none () // сброс
{ digitalWrite(a,GRIDS);
digitalWrite(b,GRIDS);
digitalWrite(c,GRIDS);
digitalWrite(d,GRIDS);
digitalWrite(e,GRIDS);
digitalWrite(f,GRIDS);
digitalWrite(g,GRIDS);
digitalWrite(d1,SEGMENTS);
digitalWrite(d2,SEGMENTS);
}

void initos ()
{ none(); //понт с экраном при загрузке

digitalWrite(d2,GRIDS); digitalWrite(a,SEGMENTS); delay(50); none();
digitalWrite(d1,GRIDS); digitalWrite(a,SEGMENTS); delay(50); none();
digitalWrite(d1,GRIDS); digitalWrite(b,SEGMENTS); delay(50); none();
digitalWrite(d1,GRIDS); digitalWrite(c,SEGMENTS); delay(50); none();
digitalWrite(d1,GRIDS); digitalWrite(d,SEGMENTS); delay(50); none();
digitalWrite(d2,GRIDS); digitalWrite(d,SEGMENTS); delay(50); none();
}

int printTemp () 
{ 
none();
myTemp = getTemp();
byte first = 0;
byte second =0;

if(myTemp>=10)
{
first=myTemp/10;
second=myTemp%10;
digitalWrite(d2,GRIDS);
switch (first) 
{ 
case 0 : { zero(); break; }
case 1 : { one(); break; }
case 2 : { two(); break; }
case 3 : { three(); break; }
case 4 : { four(); break; }
case 5 : { five(); break; }
case 6 : { six(); break; }
case 7 : { seven(); break; }
case 8 : { eight(); break; }
case 9 : { nine(); break; }
}
delay(5);
none();
digitalWrite(d1,GRIDS);
switch(second) 
{ case 0 : { zero(); break; }
case 1 : { one(); break; }
case 2 : { two(); break; }
case 3 : { three(); break; }
case 4 : { four(); break; }
case 5 : { five(); break; }
case 6 : { six(); break; }
case 7 : { seven(); break; }
case 8 : { eight(); break; }
case 9 : { nine(); break; }
}
delay(5);
none();
}
else
{
digitalWrite(d1,GRIDS); 
switch (myTemp) 
{ case 0 : { zero(); break; }
case 1 : { one(); break; }
case 2 : { two(); break; }
case 3 : { three(); break; }
case 4 : { four(); break; }
case 5 : { five(); break; }
case 6 : { six(); break; }
case 7 : { seven(); break; }
case 8 : { eight(); break; }
case 9 : { nine(); break; }

}
delay(5); 
}
return myTemp;
}

 

 

Fantick
Offline
Зарегистрирован: 09.12.2011

Это называется гистерезис, покапай в этом направлении.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

if температура < 23  {включить реле} ,

if температура >25  {выключить реле}

Araris
Offline
Зарегистрирован: 09.11.2012

Ну Вы же сами все так четко описали : 

"как выставить в программе минимальное и максимальное значение,"

int mintemp = 23; int maxtemp = 25;

"чтобы при 25 - больше не грело, "

if ( offrelay > maxtemp ) { выключаем }

"а при 23 - включалось"

if ( offrelay < mintemp ) { включаем }

И все.

А гистерезис (петля гистерезиса) - не для данного случая, у нас тут два пороговых значения, а не одно.

Поэтому при температурах 23.5 , 24.2 и тому подобное просто не сработает ни одно из условий и ничего происходить не будет. 

fayvlad
Offline
Зарегистрирован: 27.03.2014

24 никогда не нагреет

fayvlad
Offline
Зарегистрирован: 27.03.2014

смысл понял, но поверхостно, возможно какой-то флажок поставить, если 25 нагрело, флаг =1, если 23= 0

и двойное условие? 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Нет не так. Выше уже написали. Если t>25 -выключить, если t<23 - включить. Остальные ситуации не обрабатывать.

fayvlad
Offline
Зарегистрирован: 27.03.2014

В общем сделал вот так

void loop()  // цикл программы
{
  int offrelay = printTemp();
  if(offrelay<25 && flag==0) {
  digitalWrite(relay, HIGH);
  digitalWrite(13, HIGH);}
  else if(offrelay>=25 && flag==0) 
  {
  flag=1;
  digitalWrite(relay, LOW);digitalWrite(13, LOW);
  }
  else if(offrelay<=23&& flag==1)  {
    flag=0;
  digitalWrite(relay, HIGH);digitalWrite(13, HIGH);
}
}

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

 

Fantick
Offline
Зарегистрирован: 09.12.2011
Вот о чем я говорил,  говоря о гистерезисе.

byte setTemp = 24;
byte hysteresis = 1;
if (temperature < (setTemp - hysteresis)) digitalWrite(relay, HIGH);
if (temperature > (setTemp + hysteresis)) digitalWrite(relay, LOW);

nikolaki
nikolaki аватар
Offline
Зарегистрирован: 14.02.2013

post 2  уже все написал

Maverik
Offline
Зарегистрирован: 12.09.2012

добавь еще чтобы часто не щелкало переменную типа unsigned long и в неё записывай время последнего срабатывания.  если разница между следующим срабатыванием и предыдущим меньше, скажем, минуты, то ничего не делать. если больше минуты- то уже смотреть температуру.  так можно избавиться от "дребезга".  а за минуту с рыбками ничего не случится.  

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

fayvlad пишет:

В общем сделал вот так

...

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

У DS18В20 Есть комманда 0x4Eh – запись в память датчика. далее записываются три байта

- верх термостата,

-низ термостата

- значение контрольного регистра.(задаем точность измерения и время "задумчивости" датчика)

Весьма доходчиво описано тут

)

 

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