'Inteligenty' dom ze sterownikiem PLC

 Language:
Szukanie zaawansowane  

Aktualności:

Powrót do strony głównej: www.edom-plc.pl

Autor Wątek: Zmienne persistent  (Przeczytany 902 razy)

schuey

  • Newbie
  • *
  • Wiadomości: 36
    • Zobacz profil
Zmienne persistent
« dnia: Maj 20, 2018, 11:09:27 am »

 Witam,

Chciałem skorzystać z funkcji FbSunshadeActuator, w tym celu stworzyłem blok na zmienna przechowujące położenie rolet i czasy pracy silnika:

VAR RETAIN PERSISTENT
   SunshadePosition : typSunshadePosition;
   SunshadeConfig : typConfigSunshade := (
      tTotalRunningTimeUp := T#8S,
      tTotalRunningTimeDown := T#5S
   );
END_VAR

Niestety eCockpit informuje mnie o błędzie - No VAR_PERSISTENT-list is part of the application to enter instance path for var Czy należy dodać globalną listę tych zmiennych aby je modyfikować? Spodziewałem się, że wystarczy mieć to w podprogramie dotyczącam danej funkcji - w tym przypadku sterowania roletami.

Pozdrawiam,
Zapisane

schuey

  • Newbie
  • *
  • Wiadomości: 36
    • Zobacz profil
Odp: Zmienne persistent
« Odpowiedź #1 dnia: Maj 20, 2018, 09:14:49 pm »

W załączniku screenshot z aplikacji - blok zmiennych, kod właściwy i informacja o błędzie na dole.

Sterownik faktycznie nie pamięta pozycji i pozwala na ponowne podnoszeni albo opuszczanie mimo wykonania zadanego kierunku do krańcowej pozycji. Zatrzymanie w połowie czasu i ponowne otwarcie/zamknięcie załącza wyjście na całkowity czas ruchu a nie pozostały.
Zapisane

mkochniarczyk

  • Newbie
  • *
  • Wiadomości: 15
    • Zobacz profil
Odp: Zmienne persistent
« Odpowiedź #2 dnia: Czerwiec 04, 2018, 04:34:16 pm »

Też walczyłem z tymi wbudowanymi funkcjami z bibliotek. Niestety żadna nie działała tak jakbym chciał... w końcu napisałem swoją funkcję.
Nacisnę dłużej = zamyka lub otwiera do końca.
Nacisnę dwa razy = pozycja uchylona
Zatrzymanie = krótkie naciśnięcie

FUNCTION_BLOCK BLIND
VAR_INPUT

   key_up,key_down : BOOL;

END_VAR

VAR_IN_OUT
   param :  type_param_blinds;
END_VAR

VAR_OUTPUT
   engine_up, engine_down : BOOL;
END_VAR
VAR

   _click_up , _click_down :CLICK_MODE;
   k_long_up , k_single_up , k_double_up : BOOL;
   k_long_down , k_single_down , k_double_down : BOOL;

   shadow   :BOOL := FALSE;

   start_pulse_up,start_pulse_down, start_pulse_shadow : BOOL;
   pulse_up, pulse_down,pulse_shadow :BOOL;
   g_puls_up,  g_puls_down,g_puls_shadow : GEN_PULSE;
   r_puls_up, r_puls_down,  r_puls_shadow : R_TRIG;

END_VAR


_click_up(
   IN:= key_up ,
   T_LONG:= _T_LONG ,
   SINGLE=> k_single_up,
   DOUBLE=> k_double_up,
   LONG=> k_long_up ,
   TP_LONG=> );

_click_down(
   IN:= key_down ,
   T_LONG:= _T_LONG ,
   SINGLE=> k_single_down,
   DOUBLE=> k_double_down,
   LONG=> k_long_down ,
   TP_LONG=> );



(*generatory impulsow do licznika CV*)
g_puls_up (ENQ := engine_up, PTH := DWORD_TO_TIME(param.time_up*5  )  , PTL := DWORD_TO_TIME(param.time_up*5 ) , Q => pulse_up);
g_puls_down (ENQ := engine_down, PTH := DWORD_TO_TIME(param.time_down*5), PTL := DWORD_TO_TIME(param.time_down*5) , Q => pulse_down);
g_puls_shadow (ENQ := engine_up OR engine_down, PTH := DWORD_TO_TIME(param.time_slot*5), PTL :=DWORD_TO_TIME(param.time_slot*5) , Q => pulse_shadow);


(*wykrywanie impulsow *)
r_puls_up(CLK := pulse_up);
r_puls_down(CLK := pulse_down);
r_puls_shadow (CLK := pulse_shadow);

(*modyfikacja CV zgodnie z wykrytymi impulsami*)
IF(r_puls_up.Q AND param.CV_S =100  AND   param.CV < 100 )          THEN    param.CV := param.CV + 1;END_IF;
IF(r_puls_down.Q  AND  param.CV > 0 )                               THEN   param.CV := param.CV - 1;END_IF;
IF(r_puls_shadow.Q) THEN
    IF(engine_up  AND  param.CV_S < 100 )                         THEN   param.CV_S := param.CV_S + 1;
   ELSIF(engine_down AND param.CV =0  AND param.CV_S > 0)       THEN param.CV_S := param.CV_S -1;
   END_IF;
END_IF;


(*ZATRZYMANIE SILNIKÓW*)
IF(engine_down OR engine_up) THEN
   IF(k_single_down OR k_single_up OR param.open_close > 0) THEN
      param.POS :=0;  param.open_close:=0;   engine_up := FALSE; engine_down := FALSE; shadow := FALSE;
   END_IF;
END_IF;
(*jezeli pozycja auto nie ustalona*)
IF (param.POS = 0) THEN
   (*jezeli roleta jest na dole*)
   IF(param.CV  = 0 ) THEN
      IF(shadow AND param.CV_S = 100) THEN  shadow := FALSE; engine_up := FALSE; engine_down := FALSE;
      ELSIF(engine_down AND param.CV_S = 0) THEN engine_up := FALSE; engine_down := FALSE;
      END_IF;
   (*jezeli jest juz na gorze*)
   ELSIF (param.CV = 100 AND engine_up) THEN  engine_up := FALSE; engine_down := FALSE;
   END_IF;
(*jezeli osiagniela zadana pozycje*)
ELSE IF(param.POS = param.CV)  THEN param.POS := 0;  engine_up := FALSE; engine_down := FALSE;    END_IF;
END_IF;

(*URUCHOMIENIE SILNIKOW*)
IF(key_up OR key_down) THEN param.POS := 0 ; END_IF;
IF((k_long_up OR k_double_up)  AND engine_down = FALSE)  THEN
   IF(k_double_up AND param.CV = 0) THEN shadow:= TRUE; END_IF;
   engine_up := TRUE;
END_IF;
IF((k_long_down OR k_double_down)  AND engine_up = FALSE)  THEN
   IF(k_double_down AND param.CV > 0) THEN shadow:= TRUE; END_IF;
   engine_down := TRUE;

 END_IF;

IF(param.open_close > 0) THEN
   IF (param.open_close = 1) THEN engine_up := TRUE;
   ELSIF (param.open_close = 2) THEN engine_down := TRUE;
   END_IF;
   param.open_close := 0;
END_IF;

IF(param.POS > 0) THEN
   IF(param.POS > param.CV) THEN engine_up := TRUE;
   ELSIF (param.POS < param.CV) THEN engine_down := TRUE;
   ELSE param.POS := 0;
   END_IF;
END_IF;



{attribute 'pack_mode' := '2'}
TYPE type_param_blinds :
STRUCT
   time_up       : BYTE ;      res1: BYTE ;
   time_down    :BYTE ;         res2:BYTE;
   time_slot       :BYTE;         res3 :BYTE ;
   res4          :BYTE ;      res5:BYTE;
   POS         :BYTE := 0;      res6:BYTE;
   open_close   :BYTE := 0;      res7:BYTE;
   CV            : BYTE := 0;   res8:BYTE;
   CV_S          :BYTE;         res9:BYTE;

END_STRUCT
END_TYPE


K_BLIND (
   key_up := K_K_ROL_UP,
   key_down := K_K_ROL_DOWN,
   engine_down => K_ROL_ENGINE_DOWN,
   engine_up => K_ROL_ENGINE_UP,
   param := _RETAIN.param_blinds[ K ],
);
Zapisane

schuey

  • Newbie
  • *
  • Wiadomości: 36
    • Zobacz profil
Odp: Zmienne persistent
« Odpowiedź #3 dnia: Czerwiec 10, 2018, 11:48:23 pm »

Podziwiam determinację i wkład w napisanie własnej funkcji!

Jeśli chodzi o mnie to spędziłem kilka godzin na próbach instalacji bibliotek Oscat w !eCockpit. W końcu się udało i prosty program blind input / blind control działa ekstra i w ogóle nie mam takich problemów jak z natywnym FbSunshadeActuator.

Następny krok to sterowanie żaluzjami i krótkie przyciśnięcia do zmiany lamelek - mam nadzieję, że oscat ogarnia takie rzeczy.
Zapisane

mkochniarczyk

  • Newbie
  • *
  • Wiadomości: 15
    • Zobacz profil
Odp: Zmienne persistent
« Odpowiedź #4 dnia: Czerwiec 12, 2018, 04:06:24 pm »

Jak próbowałem implementować biblioteki Oscat do obsługi rolet napotkałem parę problemów których ni jak nie mogłem zrozumieć.
Gdzieś później wyczytałem że biblioteka idealnie pasuje do żaluzji (nie rolet) gdzie zaciemnienie polega na przekręceniu każdej lamelki o jakiś kąt. Wiem że autor forum korzysta z tej biblioteki ale nie znalazłem nigdzie wniosków po uruchomieniu.
Zapisane