Jak dodać strefę histerezy do bieżącego kodu?

Odpowiedz Nowy wątek
2018-12-15 12:08
0

Witam. Posiadam takowy kod , jak widać jest uwzględniona w nim strefa nieczułości wynosząca 2%. Czyli przykładowo wilgotność zadana jest ustawiona na 50% więc strefą nieczułości będzie zakres od 49 do 51 %. Jednak moim pytaniem jest jak dodać strefę histerezy do tego kodu? W jaki sposób trzeba to napisać?
Kod jest następujący :

if(wartosc>(WILG+2)) { 
digitalWrite(relay_pin3, HIGH);  
digitalWrite(relay_pin4, HIGH);  
.
.
.
}
else if(wartosc<(WILG-2)){ 
digitalWrite(relay_pin2, HIGH); 
digitalWrite(relay_pin3, LOW); 
.
.
.
}
else { 
digitalWrite(relay_pin, HIGH);
.
.
.
}

Ogólny schemat regulacji jest następujący :
title
gdzie właśnie N to strefa nieczułości , a H strefa histerezy nad którą zastanawiam się w jaki sposób ją dodać do kodu - czy jest to w ogóle możliwe do wykonania?
Z góry dziękuje za zainteresowanie :)

edytowany 1x, ostatnio: furious programming, 2018-12-15 17:59

Pozostało 580 znaków

2018-12-15 16:05
1

tak da się, masz przykłady
https://arduino.stackexchange[...]ysteresis-to-threshold-values


We are the 4p. Existence, as you know it, is over. We will add your biological and technological distinctiveness to our own. Resistance is futile

Pozostało 580 znaków

2018-12-15 21:04
0

Jest taki problem iż kod podesłany przez Ciebie jest napisany na konkretną wartość a w moim przypadku wartość ta nie jest konkretna bo ulega zmianie wraz z kręceniem potencjometrem - wartość zadana jest różna, nie stała.

Ktoś wie może jak rozwiązać ten problem? :)

edytowany 3x, ostatnio: Marooned, 2018-12-17 13:25

Pozostało 580 znaków

2018-12-16 15:39
2
avabuy napisał(a):

Czyli przykładowo wilgotność zadana jest ustawiona na 50% więc strefą nieczułości będzie zakres od 49 do 51 %.

Twój kod mówi coś innego. ;)


if(wartosc>(WILG+2)) { 
  // ..
else if(wartosc<(WILG-2)){ 
  // ..

Jeśli WILG ma wartość 50, to pierwszy warunek zostanie spełniony gdy wartosc wyniesie co najmniej 53, a drugi gdy wyniesie co najwyżej 47. Tak więc Twoja strefa nieczułości wynosi dokładnie 4, a nie 2.

Ten przypadek można naprawić zmieniając operator < na <= oraz > na >=, ale przy innym zakresie nieczułości też będzie kłamał. Dlatego rozmiar strefy nieczułości powinieneś podzielić na 2, wynik odjąć od/dodać do WILG i skorzystać z operatorów < i >. Ale to tak nawiasem.

Z czym konkretnie masz problem, jeśli o histerezę chodzi?


edytowany 1x, ostatnio: furious programming, 2018-12-16 15:40

Pozostało 580 znaków

2018-12-16 15:51
0

To znaczy strefa nieczułości wynosi 4% racja bo wyłączają się urządzenia gdy jest 48 badz 52%. Problem w tym leży , że jak przerobić kod aby była i strefa nieczułości ale również histereza? Tak jak to jest ukazane na tym obrazie co wstawiłem w pierwszym poście. Czy jest to w ogóle możliwe?
PS. Czyli uważasz że obecne warunki są źle napisane ? Bo wcześniej miały one inną składnie lecz coś nie działało jak należy. Według Ciebie jak najlepiej powinny zostać napisane te warunki? ;)

edytowany 1x, ostatnio: avabuy, 2018-12-16 15:53

Pozostało 580 znaków

2018-12-16 16:09
0

Warunki są dobre, jeśli chciałeś mieć strefę nieczułości wynoszącą 4% – w przeciwnym razie trzeba zmienić nagłówki, bo dwukrotnie zwiększają zakres. O ile w ogóle potrzebujesz tej strefy – coś mi się wydaje, że nie jest ona potrzebna, a że dodałeś ją w zastępstwie histerezy. Zgadza się? ;)


edytowany 1x, ostatnio: furious programming, 2018-12-16 16:09

Pozostało 580 znaków

2018-12-16 16:17
0

Tzn strefa nieczułości jest potrzebna bo ona jest niezbędna w przypadku regulatorów trójpołożeniowych ;) chciałem jeszcze do tego kodu dodać histereze według obrazka z pierwszego postu lecz tak sie zastanawiam - w tym przypadku strefa nieczułości jest jakby równoznaczna z histereza- nie wiem czy dobrze to rozumuje? ;) bo jeśli tak to histerezy się nie doda do obecnego kodu chyba ;)

edytowany 3x, ostatnio: avabuy, 2018-12-16 16:18

Pozostało 580 znaków

2018-12-16 17:25
2
avabuy napisał(a):

Tzn strefa nieczułości jest potrzebna bo ona jest niezbędna w przypadku regulatorów trójpołożeniowych ;)

Ok, ok. ;)

chciałem jeszcze do tego kodu dodać histereze według obrazka z pierwszego postu lecz tak sie zastanawiam - w tym przypadku strefa nieczułości jest jakby równoznaczna z histereza- nie wiem czy dobrze to rozumuje?

IMO z tego obrazka wynika, że w pewnym sensie tak – była by to strefa nieczułości na zmianę stanu.

Może inaczej, mamy trzy bazowe zakresy – A, jeśli wartość jest mniejsza od strefy nieczułości; B, jeśli znajduje się w strefie niczułości i C, jeśli jest większa od maksimum strefy nieczułości. Dodatkowo, wyznaczmy dwa zakresy X, gdy wartość znajduje się w okolicach histerezy. Zilustrujmy to prostym rysunkiem:

zakresy.png

Teraz jeśli bieżący stan to A i kolejne wartości pomiaru zawierają się w zbiorze A, to stan się nie zmienia. Wartości pomiarów rosną i zaczynają pasować do zbioru X. Dopóki kolejne pomiary znajdują się w zbiorze X to stan pozostaje bez zmian. Jeśli kolejna wartość pomiaru wykroczy poza zbiór X i będzie pasować do B to wtedy zmieniamy stan z A na stan B.

Analogicznie w sytuacji odwrotnej. Mamy stan B, wartości pomiarów maleją i zaczynają pasować do zbioru X – nie zmieniamy jeszcze stanu. Dopiero kiedy kolejny pomiar da wartość ze zbioru A to zmieniamy stan z B na A. I analogicznie dla przejścia ze stanu B do stanu C i z C do B.

Aby móc obsłużyć histerezę, musisz po prostu nie reagować na wartości dla obu zakresów X.


edytowany 2x, ostatnio: furious programming, 2018-12-16 17:27

Pozostało 580 znaków

2018-12-16 17:59
0

Hmmm rozumiem, dziękuje za naprawdę jasne wytłumaczenie - tylko nie wiem jak to wyjdzie w praktyce jeżeli chodzi o przekaźnik itd ;) czy mógłbyś mi pomóc napisać taki kod? Bo szczerze powiedziawszy sam sobie nie poradzę ;)

edytowany 1x, ostatnio: avabuy, 2018-12-16 18:00
Za pół godzinki/godzinkę będę miał więcej czasu to coś nastukam – nie będzie to trudne. - furious programming 2018-12-16 18:01

Pozostało 580 znaków

2018-12-16 19:35
3

Nie jestem specem od systemów embedded, ani też od elektroniki, ale Twój program w działaniu przypomina mi sterownik do pompy przeznaczonej do kotła CO, z którym zaprzyjaźniam się każdej jesieni. Tyle że ten obsługuje dwa stany – włącza pompę gdy temperatura wody w kotle osiągnie 40°C, a wyłącza się gdy spadnie do 35°C. Zakres tych 5°C pozwala uniknąć ciągłego włączania i wyłączania pompy w okolicach 40°C, a tym samym utknięcia w martwym punkcie (ni grzeje, ni stygnie). Twój program natomisat przewiduje dwa takie zakresy, bo obsługuje trzy stany zamiast dwóch.


No dobrze, moja propozycja niżej. Żeby łatwiej było manipulować rozmiarami zakresów, kilka stałych na początek:

const int humidity = 50;

const int size_range_x = 2;
const int size_range_b = 2;

const int state_x_left_min = humidity - size_range_b - size_range_x;
const int state_x_left_max = humidity - size_range_b;

const int state_x_right_min = humidity + size_range_b;
const int state_x_right_max = munidity + size_range_b + size_range_x;

const int state_x = 0;
const int state_a = 1;
const int state_b = 2;
const int state_c = 3;

Przyda się też zmienna przechowująca indeks bieżącego stanu (domyślnie stan a):

int state = state_a;

Teraz funkcja pobierająca bieżącą wartość z czujnika:

int getCurrentState()
{
  int value = // tu pobierz bieżącą wartość czujnika i ją zmapuj

  if (value >= state_x_left_min  && value <= state_x_left_max)  return state_x;
  if (value >= state_x_right_min && value <= state_x_right_max) return state_x;

  if (value < state_x_left_min)  return state_a;
  if (value > state_x_right_max) return state_c;

  return state_b;
}

Zwraca jedną z czterech wartości – od state_x do state_c. Przydadzą się jeszcze trzy funkcje służące do włączenia konkretnego stanu:

void setStateA()
{
  if (state == state_a) return;

  // tu wywołaj odpowiednie "digitalWrite" dla stanu A
}

void setStateB()
{
  if (state == state_b) return;

  // tu wywołaj odpowiednie "digitalWrite" dla stanu B
}

void setStateC()
{
  if (state == state_c) return;

  // tu wywołaj odpowiednie "digitalWrite" dla stanu C
}

I ostatnia część kodu, czyli główny walidator:

int newState = getCurrentState();

switch (newState)
{
  case state_a: setStateA(); break;
  case state_b: setStateB(); break;
  case state_c: setStateC(); break;
}

Najpierw do zmiennej newState pobierany jest nowy stan za pomocą getCurrentState. Jeśli getCurrentState zwróci state_x to nic się nie dzieje – żadna operacja nie jest wykonywana. Natomiast jeśli zwróci stan od state_a do state_c, to odpalana jest odpowiednia funkcja setState*. Warunki w tych funkcjach powodują, że funkcje te są idempotentne – nie robią nic, jeśli nowy stan jest taki sam jak wcześniejszy.

Tak więc program będzie pomijał aktualizację stanu, jeśli bieżąca wartość po zmapowaniu znajdzie się w zakresie [46 .. 48] lub od [52 .. 54]. Jeśli wartość będzie mniejsza od 46 to ustawi stan A, jeśli większa od 54 to stan C, a jeśli wartość znajdzie się w przedziale [49 .. 51] to ustawi stan B.

Mam nadzieję, że kod jest składniowo poprawny – nie testowałem go. ;)


Jedno trzeba wyjaśnić – stała size_range_b określaja połowę rozmiaru zakresu dla stanu B, a stała size_range_x określa pełny rozmiar zakresu wartości histerezy. Dlatego pierwsze cztery instrukcje warunkowe w funkcji getCurrentState wyglądają tak a nie inaczej. Jeśli w stałej state_range_b chciałbyś przechowywać pełen rozmiar zakresu stanu B, to musiałbyś zmienić warunki w getCurrentState.

Poniższy obrazek ilustruje znaczenie poszczegółnych stałych:

constants.png


edytowany 9x, ostatnio: furious programming, 2018-12-17 14:57

Pozostało 580 znaków

2018-12-16 19:47
0

Hmmm powiem szczerze że kod dosyć skomplikowany jak dla mnie ale dam rade ;) takie pytanie mam - czyli wilgotność początkową należy przyjąć odgórnie w zmiennej? Bez przyjęcia się inaczej tego nie zrobi? ;)

edytowany 2x, ostatnio: avabuy, 2018-12-16 19:55

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 0, botów: 1

Robot: CCBot