Flow measurement

Dependencies:   mbed PID FastPWM

Committer:
renemagrit
Date:
Mon May 04 14:38:12 2020 +0000
Revision:
0:638eb51d9082
PID controller for flow measurement system using pressure sensor.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
renemagrit 0:638eb51d9082 1 /*
renemagrit 0:638eb51d9082 2 * Date: march 2020.
renemagrit 0:638eb51d9082 3 * Decription: Bilo je potrebno napraviti sistem PID regulatora ciji je osnovni
renemagrit 0:638eb51d9082 4 zadatak odrzavanja pritiska vrednosti 0 Bara.
renemagrit 0:638eb51d9082 5 Sistem se sastoji iz:
renemagrit 0:638eb51d9082 6 1.Senzora pritiska
renemagrit 0:638eb51d9082 7 2.Step motora koji pogoni elektricnu pumpu
renemagrit 0:638eb51d9082 8 Izlaz PID regulatira je frekvencija obrtanja step motora koji tera pumpu.
renemagrit 0:638eb51d9082 9 Sto se motor brze okrece to pumpa vise kolicine izvlaci.
renemagrit 0:638eb51d9082 10 Na ovaj nacin obezbedjeno je precizno protocno merenje kolicine u ispitivanju
renemagrit 0:638eb51d9082 11 injekotra.
renemagrit 0:638eb51d9082 12 Sistem tokom celokupnog rada zeli da stabilise pritisak od 0 Bari i time
renemagrit 0:638eb51d9082 13 ponisti razliku pritisaka koja se javlja usled odredjene kolicine goriva u
renemagrit 0:638eb51d9082 14 sistemu.
renemagrit 0:638eb51d9082 15
renemagrit 0:638eb51d9082 16 - Dugorocnim testiranjem utvrdjeni su parametri PID kontrolera.
renemagrit 0:638eb51d9082 17 - Senzor pritiska se filtira sa MID7 filterom
renemagrit 0:638eb51d9082 18 - Izmerena kolicina se filtrira sa MID7 filterom
renemagrit 0:638eb51d9082 19 - PID procesuira zahteve svakih 100ms
renemagrit 0:638eb51d9082 20 */
renemagrit 0:638eb51d9082 21 #include "mbed.h"
renemagrit 0:638eb51d9082 22 #include "AsynchSerial.h"
renemagrit 0:638eb51d9082 23 #include "PID.h"
renemagrit 0:638eb51d9082 24 #include "FastPWM.h"
renemagrit 0:638eb51d9082 25
renemagrit 0:638eb51d9082 26 #define RATE 0.1
renemagrit 0:638eb51d9082 27 #define ZERO 2.33
renemagrit 0:638eb51d9082 28 AsynchSerial pc(USBTX, USBRX, 115200);
renemagrit 0:638eb51d9082 29
renemagrit 0:638eb51d9082 30 EventQueue queue;
renemagrit 0:638eb51d9082 31 Ticker tick;
renemagrit 0:638eb51d9082 32
renemagrit 0:638eb51d9082 33 //Kc, Ti, Td, interval
renemagrit 0:638eb51d9082 34 PID controller(2.5, 1, 0.0, RATE);
renemagrit 0:638eb51d9082 35 AnalogIn pv(PA_0);
renemagrit 0:638eb51d9082 36 FastPWM co(PA_1,2);
renemagrit 0:638eb51d9082 37
renemagrit 0:638eb51d9082 38 //mm u opsegu od 0 do 100
renemagrit 0:638eb51d9082 39
renemagrit 0:638eb51d9082 40 float reff;
renemagrit 0:638eb51d9082 41 float value;
renemagrit 0:638eb51d9082 42 float inValue;
renemagrit 0:638eb51d9082 43
renemagrit 0:638eb51d9082 44 float analogInValues[7];
renemagrit 0:638eb51d9082 45 float freqValues[7];
renemagrit 0:638eb51d9082 46 volatile int cntFreq = 0;
renemagrit 0:638eb51d9082 47 int n = 7;
renemagrit 0:638eb51d9082 48 int enable = 0;
renemagrit 0:638eb51d9082 49 int width = 0;
renemagrit 0:638eb51d9082 50
renemagrit 0:638eb51d9082 51 void getData() {
renemagrit 0:638eb51d9082 52 /*Citanje podatka iz Buffera Serijske komunikacije -uz resnje GRESKE citanja*/
renemagrit 0:638eb51d9082 53
renemagrit 0:638eb51d9082 54 unsigned char buffer[20];
renemagrit 0:638eb51d9082 55 int16_t len = pc.read(buffer, sizeof(buffer));
renemagrit 0:638eb51d9082 56
renemagrit 0:638eb51d9082 57 if (len > 0) {
renemagrit 0:638eb51d9082 58
renemagrit 0:638eb51d9082 59 int kom = sscanf((const char *)buffer,"%f",&reff);
renemagrit 0:638eb51d9082 60
renemagrit 0:638eb51d9082 61 if(kom==1){
renemagrit 0:638eb51d9082 62 if(reff > 100.0){
renemagrit 0:638eb51d9082 63 controller.setSetPoint(0);
renemagrit 0:638eb51d9082 64 printf("Greska! Referenca veca od 100 mm");
renemagrit 0:638eb51d9082 65 }else
renemagrit 0:638eb51d9082 66 controller.setSetPoint(reff);
renemagrit 0:638eb51d9082 67 }
renemagrit 0:638eb51d9082 68 }
renemagrit 0:638eb51d9082 69 }
renemagrit 0:638eb51d9082 70
renemagrit 0:638eb51d9082 71 void rxCb() {
renemagrit 0:638eb51d9082 72
renemagrit 0:638eb51d9082 73 queue.call(getData); // can't read data in callback
renemagrit 0:638eb51d9082 74
renemagrit 0:638eb51d9082 75 }
renemagrit 0:638eb51d9082 76 void printuj(void){
renemagrit 0:638eb51d9082 77 freqValues[cntFreq++] = value/2.0;
renemagrit 0:638eb51d9082 78 if(cntFreq == 7){
renemagrit 0:638eb51d9082 79 cntFreq = 0;
renemagrit 0:638eb51d9082 80 for (int i = 0; i < n; i++)
renemagrit 0:638eb51d9082 81 // Last i elements are already in place
renemagrit 0:638eb51d9082 82 for (int j = 0; j < n-i-1; j++)
renemagrit 0:638eb51d9082 83 if (freqValues[j] > freqValues[j+1]){
renemagrit 0:638eb51d9082 84 float temp = freqValues[j];
renemagrit 0:638eb51d9082 85 freqValues[j]=freqValues[j+1];
renemagrit 0:638eb51d9082 86 freqValues[j+1]=temp;
renemagrit 0:638eb51d9082 87 }
renemagrit 0:638eb51d9082 88
renemagrit 0:638eb51d9082 89 printf("Ref: %.1f \n",reff);
renemagrit 0:638eb51d9082 90 printf("Input Analog High: %.1f mm \n", inValue);
renemagrit 0:638eb51d9082 91 printf("F: %.1f Hz\n",freqValues[4]);
renemagrit 0:638eb51d9082 92 printf("Q: %.1f ml\n",freqValues[4]*0.045);
renemagrit 0:638eb51d9082 93
renemagrit 0:638eb51d9082 94 }
renemagrit 0:638eb51d9082 95 }
renemagrit 0:638eb51d9082 96 void setData(void){
renemagrit 0:638eb51d9082 97
renemagrit 0:638eb51d9082 98 queue.call(printuj);
renemagrit 0:638eb51d9082 99
renemagrit 0:638eb51d9082 100 }
renemagrit 0:638eb51d9082 101
renemagrit 0:638eb51d9082 102 int main(){
renemagrit 0:638eb51d9082 103
renemagrit 0:638eb51d9082 104 Thread eventThread;
renemagrit 0:638eb51d9082 105 eventThread.start(callback(&queue, &EventQueue::dispatch_forever));
renemagrit 0:638eb51d9082 106 pc.attach(callback(rxCb), AsynchSerial::RX);
renemagrit 0:638eb51d9082 107 pc.init(); //Serial buffer interrupt
renemagrit 0:638eb51d9082 108 tick.attach(&setData, 0.3);
renemagrit 0:638eb51d9082 109
renemagrit 0:638eb51d9082 110 //Set the period to 1ms = 1kHz
renemagrit 0:638eb51d9082 111 co.pulsewidth_ms(0);
renemagrit 0:638eb51d9082 112 co.prescaler(2);
renemagrit 0:638eb51d9082 113
renemagrit 0:638eb51d9082 114 controller.setInputLimits(-100.0, 100.0);
renemagrit 0:638eb51d9082 115 //Pwm output from 0.0 to 1.0
renemagrit 0:638eb51d9082 116 controller.setOutputLimits(4, 3200);
renemagrit 0:638eb51d9082 117 //If there's a bias.
renemagrit 0:638eb51d9082 118 controller.setBias(0);
renemagrit 0:638eb51d9082 119 controller.setMode(1); //not null value is AUTO MODE
renemagrit 0:638eb51d9082 120 //We want the process variable to be 1.7V
renemagrit 0:638eb51d9082 121 controller.setSetPoint(0.0);
renemagrit 0:638eb51d9082 122
renemagrit 0:638eb51d9082 123 while(1){
renemagrit 0:638eb51d9082 124
renemagrit 0:638eb51d9082 125 for(int i=0;i<n;i++){
renemagrit 0:638eb51d9082 126 analogInValues[i] = pv.read();
renemagrit 0:638eb51d9082 127 wait_ms(10);
renemagrit 0:638eb51d9082 128 }
renemagrit 0:638eb51d9082 129 // sort . . .
renemagrit 0:638eb51d9082 130 for (int i = 0; i < n; i++)
renemagrit 0:638eb51d9082 131 // Last i elements are already in place
renemagrit 0:638eb51d9082 132 for (int j = 0; j < n-i-1; j++)
renemagrit 0:638eb51d9082 133 if (analogInValues[j] > analogInValues[j+1]){
renemagrit 0:638eb51d9082 134 float temp = analogInValues[j];
renemagrit 0:638eb51d9082 135 analogInValues[j]=analogInValues[j+1];
renemagrit 0:638eb51d9082 136 analogInValues[j+1]=temp;
renemagrit 0:638eb51d9082 137 }
renemagrit 0:638eb51d9082 138
renemagrit 0:638eb51d9082 139 //Update the process variable.
renemagrit 0:638eb51d9082 140 //input u mm
renemagrit 0:638eb51d9082 141 inValue = (float)(((ZERO - analogInValues[4] * (float)3.29) * 100.0)/1.59)*(-1.0);
renemagrit 0:638eb51d9082 142 //inValue = (float)(((ZERO - pv.read() * (float)3.29) * 100.0)/1.59);
renemagrit 0:638eb51d9082 143 controller.setProcessValue(inValue);
renemagrit 0:638eb51d9082 144
renemagrit 0:638eb51d9082 145 //Set the new output.
renemagrit 0:638eb51d9082 146 value = controller.compute();
renemagrit 0:638eb51d9082 147
renemagrit 0:638eb51d9082 148 if(value == 0){
renemagrit 0:638eb51d9082 149 enable = 0;
renemagrit 0:638eb51d9082 150 printf("Greska! Value = 0");
renemagrit 0:638eb51d9082 151 }else{
renemagrit 0:638eb51d9082 152 int period = (int)(1.0/value * 1000000);
renemagrit 0:638eb51d9082 153 co.period_us(period);
renemagrit 0:638eb51d9082 154 enable = 1;
renemagrit 0:638eb51d9082 155 }
renemagrit 0:638eb51d9082 156 if(enable == 1){
renemagrit 0:638eb51d9082 157 if(value > 100)
renemagrit 0:638eb51d9082 158 co.pulsewidth_us(25);
renemagrit 0:638eb51d9082 159 else
renemagrit 0:638eb51d9082 160 co.pulsewidth_ms(2);
renemagrit 0:638eb51d9082 161 }else{
renemagrit 0:638eb51d9082 162 co.pulsewidth_us(0);
renemagrit 0:638eb51d9082 163 }
renemagrit 0:638eb51d9082 164 wait_ms(100 - 10*n);
renemagrit 0:638eb51d9082 165
renemagrit 0:638eb51d9082 166 }
renemagrit 0:638eb51d9082 167 }