# HG changeset patch # User Michiel Broek # Date 1424353375 -3600 # Node ID 73cd31dc6ce105c76bf9ed5f9486ce54ea0d04dc # Parent 198f3b4bd0d8d75edd3b5ad73bc5744769974bf1 Moved pid function to separate files diff -r 198f3b4bd0d8 -r 73cd31dc6ce1 thermferm/Makefile --- a/thermferm/Makefile Tue Feb 17 23:27:47 2015 +0100 +++ b/thermferm/Makefile Thu Feb 19 14:42:55 2015 +0100 @@ -62,7 +62,8 @@ lock.o: lock.h thermferm.h logger.o: logger.h thermferm.h futil.h xutil.h lcd-pcf8574.o: thermferm.h lcd-pcf8574.h -thermferm.o: lock.h logger.h rdconfig.h devices.h server.h thermferm.h simulator.h lcd-pcf8574.h lcd-buffer.h panel.h futil.h xutil.h +thermferm.o: lock.h logger.h rdconfig.h devices.h server.h thermferm.h simulator.h lcd-pcf8574.h lcd-buffer.h panel.h futil.h xutil.h pid.h +pid.o: thermferm.h pid.h xutil.o: thermferm.h xutil.h server.o: rdconfig.h thermferm.h logger.h devices.h server.h lcd-buffer.h xutil.h simulator.o: thermferm.h simulator.h diff -r 198f3b4bd0d8 -r 73cd31dc6ce1 thermferm/pid.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thermferm/pid.c Thu Feb 19 14:42:55 2015 +0100 @@ -0,0 +1,50 @@ +/***************************************************************************** + * Copyright (C) 2015 + * + * Michiel Broek + * + * This file is part of the mbsePi-apps + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * mbsePi-apps is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ThermFerm; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + *****************************************************************************/ + +#include "thermferm.h" +#include "pid.h" + + +double UpdatePID(pid_var *pid, double error, double position) +{ + double pTerm, dTerm, iTerm; + + pTerm = pid->pGain * error; + + /* + * Calculate the integral state with appopriate limiting + */ + pid->iState += error; + if (pid->iState > pid->iMax) + pid->iState = pid->iMax; + else if (pid->iState < pid->iMin) + pid->iState = pid->iMin; + + iTerm = pid->iGain * pid->iState; + + dTerm = pid->dGain * (pid->dState - position); + pid->dState = position; + + return pTerm + dTerm + iTerm; +} + + diff -r 198f3b4bd0d8 -r 73cd31dc6ce1 thermferm/pid.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thermferm/pid.h Thu Feb 19 14:42:55 2015 +0100 @@ -0,0 +1,17 @@ +#ifndef PID_H +#define PID_H + +typedef struct _pid_var { + double iState; /* Integrator state */ + double dState; /* Last measured value input */ + double iMax; /* Maximum allowable integrator state */ + double iMin; /* Minimum allowable integrator state */ + double iGain; /* Integral gain */ + double pGain; /* Proportional gain */ + double dGain; /* Derivative gain */ +} pid_var; + + +double UpdatePID( pid_var *, double, double); + +#endif diff -r 198f3b4bd0d8 -r 73cd31dc6ce1 thermferm/thermferm.c --- a/thermferm/thermferm.c Tue Feb 17 23:27:47 2015 +0100 +++ b/thermferm/thermferm.c Thu Feb 19 14:42:55 2015 +0100 @@ -32,6 +32,7 @@ #include "panel.h" #include "futil.h" #include "xutil.h" +#include "pid.h" int my_shutdown = FALSE; @@ -845,6 +846,8 @@ #endif int current_step, valid_step, time_until_now; float previous_target; + pid_var *pid; + if (lockprog((char *)"thermferm")) { syslog(LOG_NOTICE, "Can't lock"); @@ -1307,7 +1310,7 @@ */ for (unit = Config.units; unit; unit = unit->next) { if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) { - double pTerm, dTerm, iTerm; +// double pTerm, dTerm, iTerm; sp = unit->beer_set; pv = unit->beer_temperature / 1000.0; @@ -1325,19 +1328,47 @@ if (P_err < unit->idle_rangeH && P_err > unit->idle_rangeL) { P_err = 0.0; } - pTerm = unit->PID_Kp * P_err; + + pid = (pid_var *)malloc(sizeof(pid_var)); + pid->dState = unit->PID_dState; + pid->iState = unit->PID_iState; + pid->iMax = 100.0; + pid->iMin = -100.0; + pid->pGain = unit->PID_Kp; + pid->iGain = unit->PID_Ki; + pid->dGain = unit->PID_Kd; + + Out = UpdatePID(pid, P_err, pv); + + if (Out > 100.0) + Out = 100.0; + if (Out < -100.0) + Out = -100.0; + + if (debug) + fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", + sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); + if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) { + syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f Out=%.2f", + sp, pv, P_err, unit->PID_dState, unit->PID_iState, Out); + } + + unit->PID_iState = pid->iState; + unit->PID_dState = pid->dState; + +// pTerm = unit->PID_Kp * P_err; /* * Calculate the intergral state with appropriate limiting */ - unit->PID_iState += P_err; +// unit->PID_iState += P_err; /* Limit integral error */ - if (unit->PID_iState < -100.0) - unit->PID_iState = -100.0; - if (unit->PID_iState > 100.0) - unit->PID_iState = 100.0; - iTerm = unit->PID_iState * unit->PID_Ki; - dTerm = (unit->PID_dState - pv) * unit->PID_Kd; +// if (unit->PID_iState < -100.0) +// unit->PID_iState = -100.0; +// if (unit->PID_iState > 100.0) +// unit->PID_iState = 100.0; +// iTerm = unit->PID_iState * unit->PID_Ki; +// dTerm = (unit->PID_dState - pv) * unit->PID_Kd; /* * A postive value means heating, a negative value cooling. @@ -1346,19 +1377,19 @@ * Increase Kd until a little damping. * Increase Ki after Kp and Kd are set until longterm convergence. */ - Out = pTerm + dTerm + iTerm; - if (Out > 100.0) - Out = 100.0; - if (Out < -100.0) - Out = -100.0; - if (debug) - fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", - sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); - if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) { - syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f pTerm=%.2f iTerm=%.2f dTerm=%.2f Out=%.2f", - sp, pv, P_err, unit->PID_dState, unit->PID_iState, pTerm, iTerm, dTerm, Out); - } - unit->PID_dState = pv; +// Out = pTerm + dTerm + iTerm; +// if (Out > 100.0) +// Out = 100.0; +// if (Out < -100.0) +// Out = -100.0; +// if (debug) +// fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", +// sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); +// if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) { +// syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f pTerm=%.2f iTerm=%.2f dTerm=%.2f Out=%.2f", +// sp, pv, P_err, unit->PID_dState, unit->PID_iState, pTerm, iTerm, dTerm, Out); +// } +// unit->PID_dState = pv; if (unit->heater_address) { if (Out >= 1) {