'Inteligenty' dom ze sterownikiem PLC

 Language:
Szukanie zaawansowane  

Aktualności:

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

Autor Wątek: Zliczanie energii i mocy  (Przeczytany 3395 razy)

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Zliczanie energii i mocy
« dnia: Marca 28, 2021, 10:31:21 am »

Witam,

Dzisiaj w końcu podpiąłem licznik energii do PLC i wszystko ruszyło bez problemu, ale mam jedno "ale". Wejście cyfrowe ładnie zlicza każdy impuls, bo widać każdy błysk diody, niestety program wydaje się gubić impulsy niezależnie czy jest to 300 W czy 2 kW. Czy ktoś coś podobnego zaobserwował u siebie? Czy włączając np. czajnik macie w miarę stabilne wyniki bo u mnie pokazuje raz 2 kW a za chwile potrafi zejść poniżej 1 kW.

Energy_All_Trigger(CLK:=xIN_Licznik_Energii_All);
IF Energy_All_Trigger.Q THEN
    Energy_All_Duration:=TIME_TO_DWORD(TIME()-Energy_All_Time);
    Energy_All_Time:=TIME();
    Energy_All_Consum:=3600000/(Energy_All_Duration);
END_IF;
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #1 dnia: Marca 28, 2021, 11:44:38 am »

Zerknij w podglądzie, jaki jest odstęp między impulsami Energy_All_Duration. Jeżeli włączysz grzałkę (np. czajnik), to ta wartość powinna być z grubsza stała. Zapewne zobaczysz, że raz masz np. 450ms innym razem 530ms itd.

Przy dużych mocach/częstych impulsach (np. 2kW) pojawia się problem nieregularnego wykonania programu odpowiedzialnego za zliczanie energii. Sterownik obciążony zadaniami raz zajrzy do Twojego programu z opóźnieniem np. 30ms i już masz gotową różnicę w zmiennej Energy_All_Consum. W tym samym czasie wskazanie licznika będzie narastać prawidłowo, bo sterownik nie gubi impulsów tylko nieregularnie wykonuje obliczenia. Przy rzadkich impulsach różnica wskazań w Energy_All_Consum będzie niezauważalna.

W bloku IF dodaj jeszcze Energy_All_Meter := Energy_All_Meter + 0.001; żeby mieć wskazanie liczydła z licznika.

Rozwiązaniem jest wyliczenie zmiennej Energy_All_Consum raz na kilka impulsów i będzie jak należy. Idealnie w zależności od aktualnego poboru energii.

Miałem podobny problem z falownikiem, który bardzo szybko zmieniał wskazania produkcji i chciałem to uśrednić. Poniżej fragment kodu, który nakreśli Ci ogólną koncepcję.

IF ((PV_FroniusLicznik_Total-PV_FroniusLicznik_Total_prev) >= PV_FroniusCounterStep) THEN


PV_FroniusCounterChange := DWORD_TO_INT(PV_FroniusLicznik_Total-PV_FroniusLicznik_Total_prev);
PV_FroniusLicznik_CurrentAvg := REAL_TO_INT(3600000.0/PV_FroniusLicznik_Total_prev_duration * PV_FroniusCounterChange);

PV_FroniusLicznik_Total_prev := PV_FroniusLicznik_Total;
PV_FroniusLicznik_Total_prev_time := TIME();

(* spowolnienie usredniania jezli produkcja jest wysoka, a impulsy zbyt czeste *)
CASE (DWORD_TO_INT(PV_FroniusLicznik_CurrentAvg)) OF
0..800:
PV_FroniusCounterStep := 1;
801..1400:
PV_FroniusCounterStep := 2;
1401..2000:
PV_FroniusCounterStep := 3;
2001..3000:
PV_FroniusCounterStep := 4;
ELSE
PV_FroniusCounterStep := 5;
END_CASE;

END_IF;

W Twoim przypadku byłoby jakoś tak:
Energy_All_Trigger(CLK:=xIN_Licznik_Energii_All);
IF Energy_All_Trigger.Q THEN
Energy_All_Meter := Energy_All_Meter + 0.001;
END_IF;

IF (Energy_All_Meter - Energy_All_Meter_prev >= Energy_All_Meter_step / 1000) THEN
(*
    Energy_All_Meter_prev := Energy_All_Meter;
tutaj wszystkie obliczenia


*)

CASE (DWORD_TO_INT(Energy_All_ConsumAvg)) OF
0..800:
Energy_All_Meter_step := 1;
801..1400:
Energy_All_Meter_step := 2;
1401..2000:
Energy_All_Meter_step := 3;
2001..3000:
Energy_All_Meter_step := 4;
ELSE
Energy_All_Meter_step := 5;
END_CASE;
END_IF;


Zwróć uwagę na typy zmiennych, ja trzymam liczniki w zmiennych REAL. Ponadto zmienna Energy_All_Meter powinna być w bloku VAR RETAIN PERSISTENT, żeby wskazania nie przepadały przy restartach.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #2 dnia: Marca 28, 2021, 03:11:24 pm »

Dzieki za wskazowke. Widze, ze mozna probowac w ten sposob rozwoazac moj problem. Ale zastanawiam sie czy np. licznik energii przypadkiem nie generuje zlych impulsow. Sprawa jest o tyle dziwna, ze nie ma to znaczenia czy jest jakies obciazenie wlaczone czy moze dom jest w stanie spoczynku. I tutaj i tutaj "gubia" sie impulsy w powyzszym kodzie. Widze to dobrze bo czasy miedzy impulsami, duration sa niemal dokladnie dwa albo trzy razy wieksze co wskazuje na to, ze program nie wychwycil impulsu raz lub dwa razy z rzedu, ale dioda na wejsciu cyfrowym zawsze sie zaswiecila. Probowalem szybko klikac wlacznikiem swiatla i nie bylo zadnych problemow, a czestotliwosc klikniec byla pewnie kolo 0,2 sekundy. Zawsze swiatlo zapalalo sie i gaslo a tutaj przy czestotliwosci impulsow 12 sekund czy 1 sekunda program wszystkich nie wychwytuje. Sprawdze czy chociaz bedzie je zliczal dobrze. Moj licznik to sdm72d. Zastanawia mnie czemu sterownik nigdy nie pomija w ten sposob impulsu z wlacznika swiatla.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #3 dnia: Marca 28, 2021, 03:21:38 pm »

Przy 2 kW odstepy miedzy impulsami wynosily jakies 1,8 sekundy nie jest to chyba jakas zabojcza czestotliwosc. Kiedys zagladalem do instrukcji licxnika i kojarzy mi sie ze czas trwania impulsu wynosil 70 ms, to tez chyba sporo.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #4 dnia: Marca 28, 2021, 03:51:43 pm »

Dodałem linijkę mającą zliczać impulsy, ale też je pomija. Ogólnie wygląda na to jakby Trigger się nie wyzwalał, ale dioda na wejściu cyfrowym (xIN_Licznik_Energii_All) swieci się.

Energy_All_Trigger(CLK:=xIN_Licznik_Energii_All);
IF Energy_All_Trigger.Q THEN
   

    Energy_Counter := Energy_Counter +1;
   

    Energy_All_Duration:=TIME_TO_DWORD(TIME()-Energy_All_Time);
    Energy_All_Time:=TIME();
    Energy_All_Consum:=3600000/(Energy_All_Duration);
END_IF;
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #5 dnia: Marca 29, 2021, 11:44:44 am »

Wrzuć obsługę licznika do osobnego POU i wywołaj to w Task Configuration jako osobne zadanie z większą częstotliwością. Zobacz czy coś pomoże.

Ponadto podejrzyj co się dzieje z taskami, skoro gubisz impulsy. Podłącz się do sterownika i przejdź do PLC-Browser i wpisz "login admin wago" a następnie "tsk" i zobacz co tam ciekawego wypisuje. Być może jakiś program blokuj Ci sterownik na dłuższy czas, to będziesz to tam widział.

70ms to bardzo długi impuls, więc gubienia impulsu z powodów sprzętowych nie podejrzewam.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #6 dnia: Marca 31, 2021, 11:35:52 am »

Wygląda na to, że udało się. Licznik przerzucony do POU i ustawiony na 20 ms nie gubi impulsów (główny program jest ustawiony na 50 ms nic tutaj nie zmieniałem). Tylko teraz mam kilka pytan, bo programuje w eCockpicie PFC200 i nigdzie nie widzę opcji Browse PLC. Ogólnie wydaje mi się, że dziwnie to POU na liście po lewej stronie wskoczyło. Czy teraz mogę jakoś odwoływać się do zmiennych z tego POU w głównym programie?
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #7 dnia: Marca 31, 2021, 11:57:18 am »

Z nowym eCockpit nie miałem do czynienia, więc nie pomogę. Ale poszperaj po zakładkach, bo gdzieś to powinno być. Ewentualnie szukaj w internecie, jak odczytać statystyki wykonania programów na PLC.

Takie spowolnienia dla sterownika, to mogą powodować jakieś funkcje związane z obsługą sieci (mysql, mqtt lub inne), warto ustalić co jest nie tak.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #8 dnia: Marca 31, 2021, 12:55:13 pm »

W glownym programie mam tylko serwer modbusa odpalony i tak sie zbieram zeby go wyrzucic do innego pou tyloo wlasnie sie zastanawiam czy pozniej z glownego programu jest dostep do zmiennych w innym pou.
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #9 dnia: Marca 31, 2021, 03:51:23 pm »

Jest dostęp do zmiennych, użyj NAZWA_POU.zmienna
Zmienna nie musi być globalna.

Dziel na bloki wszystko jak leci, brama, światła, liczniki, itd. wszystkie w osobnych POU.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #10 dnia: Marca 31, 2021, 05:32:20 pm »

Zbieram się do tego, tylko zawsze odkładam na potem :) Pytanie pomocnicze, czy ktoś wie jak przekonwertować wartość REAL na dwa Wordy, aby zapisać je dalej do Holding Registers modbusa? Jak już pomiar energii działa chciałbym to przesłać do wizualizacji na OpenHabie i póki co kompilator wywala, że nie może zmieścić REAL w WORD i w sumie mu się nie dziwię. Próbuję walczyć ze wskaznikami, ale coś nie idzie...
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #11 dnia: Kwietnia 01, 2021, 08:33:43 am »

Cytuj
jak przekonwertować wartość REAL na dwa Wordy

Na początek pomyślałem o przesuwania bitów w lewo lub prawo (funkcje SHL i SHR).

Ale znalazłem to:
https://forge.codesys.com/forge/talk/Engineering/thread/029f5a8611/
https://forge.codesys.com/forge/talk/CODESYS-V2/thread/807002cc9e/

Nie wczytywałem się w szczegóły ale masz tam przedstawione ciekawe rozwiązania.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #12 dnia: Kwietnia 01, 2021, 11:03:51 am »

Mój tok rozumowania też był na początku podobny i też widziałem to co podlinkowałeś, ale coś nie chciało to działać tak jak chciałem. Ogólnie zmiany były proporcjonalne, ale coś nie tak było z wartościami wpisywanymi do rejestrów.

Na szczęście przypomniałem sobie o czymś takim jak REAL_TO_WORD. Zapewne traci się część wartości, ale w moim przypadku nie ma to znacznia chyba, bo ani nie będą to duże liczby, ani ujemne. Ale już zastanawia mnie co zrobię z czujnikami temperatury, gdzie wartość ujemna już występuje. no i w jaki sposób przekazać faktycznie wartość dziesiętną liczby przez modbus.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #13 dnia: Kwietnia 01, 2021, 12:40:43 pm »

Licznik energii powiedzmy, że mam zrobiony. Zabrałem się za wodę. Trochę zmodyfikowałem kod. Mój licznik impulsuje co litr, ale problem w tym, że woda może być długo nieużywana, a on cały czas pokazuje ostatnią wartość.
Water_All_Trigger(CLK:=xIN_Licznik_Wody_All);
IF Water_All_Trigger.Q THEN
Water_All_Duration:=TIME_TO_REAL(TIME()-Water_All_Time);
Water_All_Time:= TIME();
Water_All_Consum:=60000/(Water_All_Duration);   
END IF


Ma ktoś pomysł jak to zmodyfikować, aby sterownik patrzył także na czas trwania odstępu między impulsami i jak jest zbyt duży to Water_All_Consum zerował. Ogólnie to z takim mierzeniem jest więcej problemów, bo nawet jak z zerujemy zuzycie, to później sterownik pierwszy odczyt także mocno zaniży... Ktoś ma w praktyce sprawdzony pomiar zużycia wody?
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #14 dnia: Kwietnia 01, 2021, 08:32:32 pm »

Zerowanie licznika, przy ustaniu poboru wody:
IF (Water_All_Consum>0 AND TIME_TO_REAL(TIME()-Water_All_Time) > 5000) THEN
   Water_All_Consum := 0;
END_IF;

Musisz dopasować typy zmiennych i czas trwania impulsu do swoich potrzeb. Wg mnie niepotrzebnie używasz tutaj typu REAL, zamień to na DWORD, czas trwania impulsu może być dużą liczbą naturalną (nawet nie całkowitą), więc nie ma potrzeby trzymania tego w REAL.

Co do wysyłania typu REAL przed modbusa, to możesz to zrobić jeszcze np. tak: X := REAL_TO_WORD(T+100)*100; Gdzie T to temperatura.
Czyli temperatura T=-32.55 stopnia zamieni się na 6745. A po drugiej stronie zrobisz odwrotną konwersję T := WORD_TO_REAL(X)/100-100;
Tutaj tak samo, typy zmiennych i parametry do dopracowania.
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #15 dnia: Kwietnia 01, 2021, 08:45:14 pm »

Pomyłka, tak miało być:
X := REAL_TO_WORD((T+100)*100);
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #16 dnia: Kwietnia 01, 2021, 10:52:18 pm »

No tego reala narazie testowo wrzucilem, zeby miec wartosc dziesietna na sterowniku a pozniej zaatanawiac sie jak przepchnac ja przez modbusa, ale pokazales mi jak rozwiazac ten problem. Calkiem sprytnie :)
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #17 dnia: Kwietnia 07, 2021, 09:35:46 pm »

Co do wysyłania typu REAL przed modbusa, to możesz to zrobić jeszcze np. tak: X := REAL_TO_WORD(T+100)*100; Gdzie T to temperatura.
Czyli temperatura T=-32.55 stopnia zamieni się na 6745. A po drugiej stronie zrobisz odwrotną konwersję T := WORD_TO_REAL(X)/100-100;
Tutaj tak samo, typy zmiennych i parametry do dopracowania.

Okay, na papierze wydaje się to jasne i klarowne, ale wracając do mojego przykładu z licznikiem wody. Powróciłem do TIME_TO_DWORD zamiast REAL, ale teraz zastanawia mnie jedno. Skoro mam takie zmienne:

Cytuj
Water_All_Duration: DWORD;
Water_All_Time: TIME;
Water_All_Consum: REAL;

To czemu PLC Water_All_Consum:=60000/(Water_All_Duration); zawsze zaokrągla do pełnych liczb? Chciałbym, aby Water_All_Consum było faktycznie realem, zamieniłbym to sobie na WORDA lub DWORDA i do modbusa wrzucił tak jak napisałeś mnożąc wynik, ale w tym momencie jest to bez sensu.   
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #18 dnia: Kwietnia 08, 2021, 11:11:42 am »

To zrób tak i będzie dobrze:
Water_All_Consum := 60000/DWORD_TO_REAL(Water_All_Duration);
Water_All_Duration jest WORDem, 60000 jest WORDem, więc wynik też będzie WORDem. Niejawna konwersja wyniku na REAL jest już ze stratą części dziesiętnej. Wymuszając konwersję typu przed wykonaniem działania zaczynasz działać na właściwym typie danych.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #19 dnia: Kwietnia 08, 2021, 08:59:44 pm »

Zadam jeszcze głupie pytanie, ale wymuszenie konwersji typu przed wykonaniem działania ma polegać na zmianie zmiennej Water_All_Duration na REAL czy jakoś inaczej się do tego podchodzi?
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: Zliczanie energii i mocy
« Odpowiedź #20 dnia: Kwietnia 11, 2021, 11:11:08 pm »

Do obliczeń tworzona jest tymczasowa kopia zmiennej z nowym typem REAL. Jej wartość jest taka sama ale sposób jej zapisu w pamięci jest inny. Dzięki temu możesz wykonać obliczenia na liczbie zmiennoprzecinkowej, której część dziesiętna nie przepadnie, bo tym razem masz ją gdzie przechować. Zmienna Water_All_Duration pozostaje nietknięta, jej typ się nie zmienia.
Zapisane