Sterowanie ogrzewaniem podłogowym (PID)

Przed okresem grzewczym 2016/2017 stanąłem przed wyzwaniem starowania instalacją ogrzewania podłogowego, które uruchomiłem po wykończeniu poddasza w moim domu. Składa się ona z 11 pętli, pompy obiegowej, zaworu trójdrożnego i głowicy termostatycznej z kapilarą. Ciepło do podłogówki pobierane jest z pionów c.o., z których zasilane są grzejniki w piwnicy i na parterze.

Rozdzielnia

 

Pierwsze próby przeprowadziłem z siłownikami umieszczonymi na poszczególnych pętlach ogrzewania podłogowego. Wykorzystałem część nieużywanych siłowników z rozdzielacza na parterze i dokupiłem kilka Danfossów TWA-K. Na zaworze mieszacza ustawiłem minimalną temperaturę, a zasilanie siłowników oprogramowałem z wykorzystaniem bloków funkcyjnych Fb_Weather z biblioteki building_common.lib.

Niestety układ taki okazał się niewystarczający. Ogrzewanie podłogowe nagminnie przegrzewało pomieszczenia o 1-1,5 stopnia. Przyczyną, najprawdopodobniej, była zbyt wysoka temperatura zasilania instalacji. Głowica termostatyczna nie ograniczała dostatecznie temperatury zasilania. Może byłą wadliwa? Nie wiem. Nie po to jednak mam PLC, by nie wykorzystać takiej okazji, by coś zautomatyzować….

W poszukiwaniu siłownika sterującego zaworem trójrożnym na mieszaczu odrzuciłem firmowe rozwiązania Viessmanna ze względu na cenę i brak miejsca w rozdzielni na piętrze. Siłowniki ESBE wymagały wymiany samego zaworu trójdrożnego, na co absolutnie nie miałem ochoty. Zdecydowałem się więc ostatecznie na siłownik Danfoss AME 120NL sterowany napięciem 0-10V (link: karta katalogowa), który można umieścić w miejscu głowicy termostatycznej, bez ingerowania w układ rur i zaworów. Moduł wyjść analogowych 750-550 kupiłem na allegro i zabrałem się za testowanie.

Oto rozwiązanie, które udało mi się wypracować po kilku próbach. Temperatury w pokojach są w miarę stałe a domownicy zadowoleni:

1. Testuję, czy w ogóle jest sens otwierać jakiekolwiek zawory, czyli czy piec c.o. jest w trybie grzania lub czy kominek dostarcza ciepło do instalacji:

WINTER := ManualWinter OR (VitoMode = 2) OR (SensorReader.T_Kominek > 40);

 

2. Sprawdzam, czy uruchomić siłowniki w pomieszczeniach

Poszczególne siłowniki sterowane są blokami Fb_Weather. Dla przypomnienia, blok ten przyjmuje na wejściu odczyt czujnika temperatury (w moim wypadku uśredniona temperatura z 2 czujników 1-wire), poziom temperatury zadanej, wielkość dopuszczalnego odchylenia (zawór otwiera się, gdy temperatura w pomieszczeniu spadnie poniżej temperatury zadanej pomniejszonej o dopuszczalne odchylenie i wyłączy się, gdy temperatura w pomieszczeniu przekroczy temperaturę zadaną powiększoną o dopuszczalne odchylenie).

HEATER_2PP(iInput_Signal:=SensorReader.T_2_PP, iLimit1:=TEMP_H2PP);
OUT131:=WINTER AND (NOT HEATER_2PP.xActorLimit1);

 

3. Sprawdzam, czy uruchomić pompę obiegową. Nie ma sensu, by pracowała, gdy wszystkie zawory podłogówki są zamknięte. Uruchamiam ją więc na 1 min po włączeniu któregokolwiek z siłowników.

TON_Podl_PUMP(PT := T#1m, IN := OUT131 OR OUT132 OR OUT133 OR OUT134 OR OUT135);

 

4. Obliczam docelową temperaturę w instalacji ogrzewania podłogowego w oparciu o krzywą grzewczą obsługiwaną przez blok FbHeatingCharacteristics z biblioteki Building_HVAC_03.lib. Blok ten przyjmuje na wyjściu docelową temperaturę w pomieszczeniach, temperaturę zewnętrzną oraz parametry nachylenia i wypukłości krzywej. Na wyjściu zwraca wyliczoną temperaturę docelową.

VAR
    heatCurve : FbHeatingCharacteristics;
END_VAR

VAR RETAIN PERSISTENT
    cEnable : BOOL := TRUE;
    cTargetTemp : REAL := 21;
    cConfig : typConfigHeatingCharacteristics;
END_VAR

-----

heatCurve(
    xEnable := cEnable,
    rOutsideTemperature := FuAI_Temp(iTemp := A_IN8),
    rReferenceValueRoom := cTargetTemp,
    typConfigHeatingCharacteristics := cConfig
);

 

5. Steruję siłownikiem analogowym na zaworze trójdrożnym mieszacza za pomocą PIDa FbPIDController również z biblioteki Building_HVAC. Nie chcę w tym miejscu doktoryzować się na temat, jak taki blok konfigurować, zapewniam jednak, że całość okazała się niezbyt trudna

VAR
    Mixer : FbPIDController;
END_VAR

VAR RETAIN PERSISTENT
    mixerConfig : typConfigPIDController;
    mEnable : BOOL := TRUE;
    maunalAction : BOOL := FALSE;
    manualTemp : REAL := 30;
END_VAR

----

Mixer(
    xEnable := mEnable OR PLC_PRG.TON_Podl_PUMP.Q,
    rReferenceValue := heatCurve.rReferenceSupplyTemperature,
    rActualValue := FuAI_Temp(iTemp := A_IN1),
    xManualOperation := maunalAction,
    rManualValue := manualTemp,
    typConfigPIDController := mixerConfig
)

A_OUT1 := Mixer.wY;

 

A więc: gdy temperatura w pokoju spadnie poniżej zadanej (np. 21) pomniejszonej o dopuszczalne odchylenie (0,5 stopnia), sprawdzam, czy mam źródło ciepła (piec c.o. lub kominek) i włączam zasilanie siłownika. Po 1 minutcie uruchamia się pompa obiegowa i zaczynają się wyliczenia optymalnej temperatury zasilania. Przy ustawieniach krzywej 0,8 i 1,1 (zaproponowane w instrukcji biblioteki), wymagana temperatura wody w instalacji to np. 30 stopni. Blok PID płynnie steruje zaworem trójdrożnym, by taka właśnie temperatura zasilała pętle podłogówki.

Oto wizualizacja przygotowana do sterowania krzywą grzewczą i blokiem PID:

Heating Visu

 ..oraz kilka przykładów wizualizacji z dashboardu dostępnego on-line:

heating visu1 1 heating visu2  heating visu3 

Jako że w materii analogowych zaworów i PIDów nie czuję się zbyt pewnie, moje pytania jak i ewentualną dyskusję przenoszę na forum (link).