![](/media/cache/profiles/120532733_400144924305128_6529880340165909933_n.jpg.50x50_q85.jpg)
Flow measurement
Dependencies: mbed PID FastPWM
main.cpp@0:638eb51d9082, 2020-05-04 (annotated)
- 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?
User | Revision | Line number | New 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 | } |