Próbuję zaimplementować podstawowy algorytm PID w Arduino Leonardo do mieszania ciepłej i zimnej wody z kranu za pomocą serwozaworów. Celem jest utrzymanie temperatury możliwie najbliżej wartości zadanej. Szczególnie ważne jest, aby temperatura wyjściowa nie przekroczyła wartości zadanej, aby chronić użytkownika przed poparzeniem. Po drugie ważne jest jak najszybsze zbliżenie temperatury do wartości zadanej.
W przypadku niewielkich zmian temperatury standardowa implementacja algorytmu PID wydaje się działać poprawnie. Ale nie wiem, jak uwzględnić długie opóźnienia, które mogą wystąpić podczas oczekiwania na dotarcie ciepłej wody do zaworu, ponieważ opóźnienia te są znacznie dłuższe niż standardowe opóźnienia po zmianie pozycji zaworu.
Oczywiście w zależności od długości linii ciepłej wody i czasu od ostatniego użycia gorącej wody, dotarcie gorącej wody do zaworu może zająć kilkadziesiąt sekund, więc w tym czasie temperatura wody pozostaje dość stała w niskiej temperaturze a zawór ciepłej wody wkrótce otwiera się w 100%. Zintegrowany element zaczyna gromadzić dużą wartość błędu.
Gdy gorąca woda w końcu dotrze do zaworu, wykryta temperatura bardzo szybko wzrasta do maksymalnej temperatury ciepłej wody. Ze względu na duży błąd całkowania zawór ciepłej wody jest utrzymywany na poziomie 100% przez długi czas po przekroczeniu temperatury zadanej, ponieważ oczekiwanie na wartość całki zostanie zredukowane do normalnego poziomu. Tak więc wynikiem jest woda o maksymalnej temperaturze przez kilka (kilkadziesiąt) sekund.
Nie jestem pewien, jak uwzględnić to możliwe duże opóźnienie. Czy w takim przypadku rozsądnie byłoby ustawić górną (i dolną) granicę wartości błędu integralnego, aby ograniczyć maksymalny czas odpowiedzi? Wydaje się, że pokonuje to cel integralnego komponentu i nadal narzuca pewne opóźnienie po osiągnięciu wartości zadanej.
Czy jest lepszy sposób na radzenie sobie z szybkimi zmianami danych wejściowych po długim opóźnieniu?
Dziękuję za wszelkie porady!