Library containing essential automation elements with parameters in continuous Laplace domain, and implemented with fixed sample time. This means that "out" member functions should be called using Ticker object.

Dependents:   CurrentMeasurement Zavrsni_rad_NXP_cup HC-SR04 Nucleo_SSD1306_DS1302_ESP8266_AM2320_BME280 ... more

Committer:
tbjazic
Date:
Thu Jan 22 11:41:02 2015 +0000
Revision:
0:3dd7aeceee65
Initial commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tbjazic 0:3dd7aeceee65 1 #include "PI.h"
tbjazic 0:3dd7aeceee65 2
tbjazic 0:3dd7aeceee65 3 PI::PI() {
tbjazic 0:3dd7aeceee65 4 u = y = u_p1 = y_p1 = 0;
tbjazic 0:3dd7aeceee65 5 setParameters(1, 1, 0.1);
tbjazic 0:3dd7aeceee65 6 setOutputLimits(0, 1);
tbjazic 0:3dd7aeceee65 7 setOperationMode(automatic);
tbjazic 0:3dd7aeceee65 8 }
tbjazic 0:3dd7aeceee65 9
tbjazic 0:3dd7aeceee65 10 PI::PI(double K_R_, double T_I_, double T_d_) {
tbjazic 0:3dd7aeceee65 11 u = y = u_p1 = y_p1 = 0;
tbjazic 0:3dd7aeceee65 12 setParameters(K_R_, T_I_, T_d_);
tbjazic 0:3dd7aeceee65 13 setOutputLimits(0, 1);
tbjazic 0:3dd7aeceee65 14 setOperationMode(automatic);
tbjazic 0:3dd7aeceee65 15 }
tbjazic 0:3dd7aeceee65 16
tbjazic 0:3dd7aeceee65 17 void PI::setParameters(double K_R_, double T_I_, double T_d_) {
tbjazic 0:3dd7aeceee65 18 if (T_d_ > 0)
tbjazic 0:3dd7aeceee65 19 T_d = T_d_;
tbjazic 0:3dd7aeceee65 20 else
tbjazic 0:3dd7aeceee65 21 T_d = 0.1;
tbjazic 0:3dd7aeceee65 22 if (T_I_ > 0)
tbjazic 0:3dd7aeceee65 23 T_I = T_I_;
tbjazic 0:3dd7aeceee65 24 else
tbjazic 0:3dd7aeceee65 25 T_I = 1;
tbjazic 0:3dd7aeceee65 26 K_R = K_R_;
tbjazic 0:3dd7aeceee65 27 }
tbjazic 0:3dd7aeceee65 28
tbjazic 0:3dd7aeceee65 29 void PI::setOutputLimits(double lowerOutputLimit, double upperOutputLimit) {
tbjazic 0:3dd7aeceee65 30 if (upperOutputLimit > lowerOutputLimit) {
tbjazic 0:3dd7aeceee65 31 y_min = lowerOutputLimit;
tbjazic 0:3dd7aeceee65 32 y_max = upperOutputLimit;
tbjazic 0:3dd7aeceee65 33 }
tbjazic 0:3dd7aeceee65 34 }
tbjazic 0:3dd7aeceee65 35
tbjazic 0:3dd7aeceee65 36 void PI::setOperationMode(Mode newOperationMode) {
tbjazic 0:3dd7aeceee65 37 // Bumpless transfer from manual to automatic mode
tbjazic 0:3dd7aeceee65 38 if (operationMode == manual && newOperationMode == automatic) {
tbjazic 0:3dd7aeceee65 39 y = y_p1 = y_manual;
tbjazic 0:3dd7aeceee65 40 u = u_p1 = 0;
tbjazic 0:3dd7aeceee65 41 }
tbjazic 0:3dd7aeceee65 42 // Bumpless transfer from automatic to manual mode
tbjazic 0:3dd7aeceee65 43 else if (operationMode == automatic && newOperationMode == manual) {
tbjazic 0:3dd7aeceee65 44 y_manual = y;
tbjazic 0:3dd7aeceee65 45 }
tbjazic 0:3dd7aeceee65 46 operationMode = newOperationMode;
tbjazic 0:3dd7aeceee65 47 }
tbjazic 0:3dd7aeceee65 48
tbjazic 0:3dd7aeceee65 49 void PI::setOutputManually(double u_C) {
tbjazic 0:3dd7aeceee65 50 y_manual = u_C;
tbjazic 0:3dd7aeceee65 51 }
tbjazic 0:3dd7aeceee65 52
tbjazic 0:3dd7aeceee65 53 double PI::out() {
tbjazic 0:3dd7aeceee65 54 if (operationMode == automatic) {
tbjazic 0:3dd7aeceee65 55 y = y_p1 + K_R * u + K_R * (T_d / T_I - 1) * u_p1;
tbjazic 0:3dd7aeceee65 56 } else if (operationMode == manual) {
tbjazic 0:3dd7aeceee65 57 y = y_manual;
tbjazic 0:3dd7aeceee65 58 }
tbjazic 0:3dd7aeceee65 59
tbjazic 0:3dd7aeceee65 60 if (y > y_max)
tbjazic 0:3dd7aeceee65 61 y = y_max;
tbjazic 0:3dd7aeceee65 62 else if (y < y_min)
tbjazic 0:3dd7aeceee65 63 y = y_min;
tbjazic 0:3dd7aeceee65 64
tbjazic 0:3dd7aeceee65 65 y_p1 = y;
tbjazic 0:3dd7aeceee65 66 u_p1 = u;
tbjazic 0:3dd7aeceee65 67 return y;
tbjazic 0:3dd7aeceee65 68 }
tbjazic 0:3dd7aeceee65 69
tbjazic 0:3dd7aeceee65 70 void PI::in(double u_) {
tbjazic 0:3dd7aeceee65 71 u = u_;
tbjazic 0:3dd7aeceee65 72 }