Main code of our project.
Dependencies: TextLCD mbed PID
main.cpp@11:b6bee52941ea, 2018-10-17 (annotated)
- Committer:
- nicovv44
- Date:
- Wed Oct 17 07:32:12 2018 +0000
- Revision:
- 11:b6bee52941ea
- Parent:
- 9:70bfbd406554
- Child:
- 12:ed2a94c17109
PID frequency OK, but could be tuned better.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nicovv44 | 0:1f66eaf1013d | 1 | #include "mbed.h" |
nicovv44 | 0:1f66eaf1013d | 2 | #include "TextLCD.h" |
nicovv44 | 9:70bfbd406554 | 3 | #include "PID.h" |
nicovv44 | 9:70bfbd406554 | 4 | |
nicovv44 | 11:b6bee52941ea | 5 | #define PIDRATE 0.10 |
nicovv44 | 9:70bfbd406554 | 6 | |
nicovv44 | 9:70bfbd406554 | 7 | //Kc, Ti, Td, interval |
nicovv44 | 11:b6bee52941ea | 8 | PID PIDcontroller1(1.0, 3.0, 0.0, PIDRATE); |
nicovv44 | 0:1f66eaf1013d | 9 | |
nicovv44 | 0:1f66eaf1013d | 10 | TextLCD lcd(D2, D3, D4, D5, D6, D7); // rs, e, d4-d7 |
nicovv44 | 0:1f66eaf1013d | 11 | Serial pc(USBTX, USBRX); // tx, rx |
nicovv44 | 5:e9766e0573d0 | 12 | PwmOut pwmDC(D9); |
nicovv44 | 5:e9766e0573d0 | 13 | PwmOut pwmSY(D13); |
nicovv44 | 5:e9766e0573d0 | 14 | DigitalOut relay1(D8); |
nicovv44 | 5:e9766e0573d0 | 15 | DigitalOut relay2(D14); |
nicovv44 | 5:e9766e0573d0 | 16 | DigitalOut relay3(D11); |
nicovv44 | 5:e9766e0573d0 | 17 | DigitalOut relay4(D12); |
nicovv44 | 0:1f66eaf1013d | 18 | |
nicovv44 | 3:a1b11dfd26f3 | 19 | AnalogIn syncPin(A0); |
nicovv44 | 3:a1b11dfd26f3 | 20 | AnalogIn gridPin(A1); |
nicovv44 | 3:a1b11dfd26f3 | 21 | AnalogIn differentialPin(A2); |
nicovv44 | 5:e9766e0573d0 | 22 | AnalogIn potarDC(A3); |
nicovv44 | 5:e9766e0573d0 | 23 | AnalogIn potarSY(A4); |
nicovv44 | 0:1f66eaf1013d | 24 | |
nicovv44 | 0:1f66eaf1013d | 25 | const float sqrt2 = 1.414213562; |
nicovv44 | 0:1f66eaf1013d | 26 | |
nicovv44 | 0:1f66eaf1013d | 27 | Timeout timeout; |
nicovv44 | 5:e9766e0573d0 | 28 | Ticker tickerPWMDC; |
nicovv44 | 11:b6bee52941ea | 29 | Ticker tickerPID; |
nicovv44 | 0:1f66eaf1013d | 30 | volatile bool looping = false; |
nicovv44 | 4:886ce7eefa6e | 31 | volatile bool synchronized = false; |
nicovv44 | 4:886ce7eefa6e | 32 | volatile bool mainLoop = true; |
nicovv44 | 9:70bfbd406554 | 33 | volatile float PID1Output; |
nicovv44 | 0:1f66eaf1013d | 34 | |
nicovv44 | 0:1f66eaf1013d | 35 | |
nicovv44 | 0:1f66eaf1013d | 36 | // ############################################## |
nicovv44 | 0:1f66eaf1013d | 37 | // ########## PROTOTYPES ######################## |
nicovv44 | 0:1f66eaf1013d | 38 | // ############################################################################# |
nicovv44 | 0:1f66eaf1013d | 39 | void stopLooping(void); |
nicovv44 | 0:1f66eaf1013d | 40 | float getVolageRMS(AnalogIn ana_pin); |
nicovv44 | 0:1f66eaf1013d | 41 | float getVolageReadedMax(AnalogIn ana_pin); |
nicovv44 | 0:1f66eaf1013d | 42 | float getFrequency(AnalogIn ana_pin); |
nicovv44 | 4:886ce7eefa6e | 43 | void displayLCD(float syncRMS, float gridRMS, float syncFreq, float gridFreq); |
nicovv44 | 5:e9766e0573d0 | 44 | void tickerPWMDCfunction(); |
nicovv44 | 9:70bfbd406554 | 45 | void initPID1(); |
nicovv44 | 9:70bfbd406554 | 46 | void tickerPIDfunction(); |
nicovv44 | 0:1f66eaf1013d | 47 | |
nicovv44 | 0:1f66eaf1013d | 48 | |
nicovv44 | 0:1f66eaf1013d | 49 | // ############################################## |
nicovv44 | 0:1f66eaf1013d | 50 | // ########## MAIN ############################## |
nicovv44 | 0:1f66eaf1013d | 51 | // ############################################################################# |
nicovv44 | 0:1f66eaf1013d | 52 | int main() { |
nicovv44 | 3:a1b11dfd26f3 | 53 | float syncRMS, gridRMS, syncFreq, gridFreq; |
nicovv44 | 9:70bfbd406554 | 54 | |
nicovv44 | 9:70bfbd406554 | 55 | //initialise PIDcontroller1 |
nicovv44 | 9:70bfbd406554 | 56 | initPID1(); |
nicovv44 | 0:1f66eaf1013d | 57 | |
nicovv44 | 5:e9766e0573d0 | 58 | relay1 = 1;//Relay off=1, on=0 |
nicovv44 | 5:e9766e0573d0 | 59 | relay2 = 1;//Relay off=1, on=0 |
nicovv44 | 5:e9766e0573d0 | 60 | relay3 = 1;//Relay off=1, on=0 |
nicovv44 | 8:a161b056971c | 61 | relay4 = 0;//Relay off=1, on=0 |
nicovv44 | 5:e9766e0573d0 | 62 | |
nicovv44 | 4:886ce7eefa6e | 63 | while(mainLoop){ |
nicovv44 | 5:e9766e0573d0 | 64 | pwmDC.period(0.001f); |
nicovv44 | 9:70bfbd406554 | 65 | pwmDC.write(1-0.90f); //(1-duty) |
nicovv44 | 8:a161b056971c | 66 | pwmSY.period(0.001f); //(1-duty) |
nicovv44 | 8:a161b056971c | 67 | pwmSY.write(1-0.80f); |
nicovv44 | 8:a161b056971c | 68 | //tickerPWMDC.attach(&tickerPWMDCfunction, 0.1); |
nicovv44 | 3:a1b11dfd26f3 | 69 | |
nicovv44 | 9:70bfbd406554 | 70 | pc.printf("\n\nAccelerating\r\n"); |
nicovv44 | 9:70bfbd406554 | 71 | wait(5);//wait so the motor get steady state |
nicovv44 | 11:b6bee52941ea | 72 | //pwmDC.write(1-0.00f); //(1-duty) |
nicovv44 | 9:70bfbd406554 | 73 | |
nicovv44 | 4:886ce7eefa6e | 74 | //manual synchronisation |
nicovv44 | 4:886ce7eefa6e | 75 | while(!synchronized){ |
nicovv44 | 4:886ce7eefa6e | 76 | //measure and calculate desired value |
nicovv44 | 4:886ce7eefa6e | 77 | syncRMS = getVolageRMS(syncPin); |
nicovv44 | 4:886ce7eefa6e | 78 | gridRMS = getVolageRMS(gridPin); |
nicovv44 | 4:886ce7eefa6e | 79 | syncFreq = getFrequency(syncPin); |
nicovv44 | 4:886ce7eefa6e | 80 | gridFreq = getFrequency(gridPin); |
nicovv44 | 9:70bfbd406554 | 81 | //Update the PID process variable. |
nicovv44 | 11:b6bee52941ea | 82 | PIDcontroller1.setProcessValue(syncFreq); |
nicovv44 | 9:70bfbd406554 | 83 | //Interrupt for a correct PID rate |
nicovv44 | 11:b6bee52941ea | 84 | tickerPID.attach(&tickerPIDfunction, PIDRATE); |
nicovv44 | 4:886ce7eefa6e | 85 | //display values on LCD |
nicovv44 | 4:886ce7eefa6e | 86 | displayLCD(syncRMS, gridRMS, syncFreq, gridFreq); |
nicovv44 | 11:b6bee52941ea | 87 | PID1Output = PIDcontroller1.compute(); |
nicovv44 | 11:b6bee52941ea | 88 | pwmDC.write(1-PID1Output); //(1-duty) |
nicovv44 | 11:b6bee52941ea | 89 | pc.printf("PID1:%f \tfreq:%f \r\n\n", PID1Output, syncFreq); |
nicovv44 | 11:b6bee52941ea | 90 | wait(PIDRATE); |
nicovv44 | 4:886ce7eefa6e | 91 | //voltage and frequency matching |
nicovv44 | 4:886ce7eefa6e | 92 | if(abs(syncRMS-gridRMS)<0.5 && abs(syncFreq-gridFreq)<0.1){ |
nicovv44 | 4:886ce7eefa6e | 93 | pc.printf("voltage and freqency OK\r\n"); |
nicovv44 | 4:886ce7eefa6e | 94 | lcd.locate(0,0);//(col,row) |
nicovv44 | 4:886ce7eefa6e | 95 | lcd.printf("V&f OK"); |
nicovv44 | 4:886ce7eefa6e | 96 | while(!synchronized){//phase matching loop |
nicovv44 | 4:886ce7eefa6e | 97 | //phase matching |
nicovv44 | 7:1f7d87007512 | 98 | if(getVolageReadedMax(differentialPin) < 0.050){ |
nicovv44 | 4:886ce7eefa6e | 99 | pc.printf("SYNCHONIZATION OK\r\n\n"); |
nicovv44 | 4:886ce7eefa6e | 100 | lcd.locate(0,1);//(col,row) |
nicovv44 | 4:886ce7eefa6e | 101 | lcd.printf("SYNC OK "); |
nicovv44 | 5:e9766e0573d0 | 102 | relay1 = 0;//Relay off=1, on=0 // to hear the noise |
nicovv44 | 5:e9766e0573d0 | 103 | relay2 = 0;//Relay off=1, on=0 // to hear the noise |
nicovv44 | 5:e9766e0573d0 | 104 | relay3 = 0;//Relay off=1, on=0 // to hear the noise |
nicovv44 | 8:a161b056971c | 105 | relay4 = 1;//Relay off=1, on=0 // to hear the noise |
nicovv44 | 4:886ce7eefa6e | 106 | synchronized = true; |
nicovv44 | 4:886ce7eefa6e | 107 | mainLoop = false; |
nicovv44 | 4:886ce7eefa6e | 108 | } |
nicovv44 | 4:886ce7eefa6e | 109 | } |
nicovv44 | 4:886ce7eefa6e | 110 | } |
nicovv44 | 4:886ce7eefa6e | 111 | } |
nicovv44 | 1:f31a46c62d10 | 112 | } |
nicovv44 | 1:f31a46c62d10 | 113 | |
nicovv44 | 5:e9766e0573d0 | 114 | |
nicovv44 | 1:f31a46c62d10 | 115 | |
nicovv44 | 3:a1b11dfd26f3 | 116 | |
nicovv44 | 0:1f66eaf1013d | 117 | } |
nicovv44 | 0:1f66eaf1013d | 118 | |
nicovv44 | 0:1f66eaf1013d | 119 | |
nicovv44 | 0:1f66eaf1013d | 120 | |
nicovv44 | 0:1f66eaf1013d | 121 | |
nicovv44 | 0:1f66eaf1013d | 122 | |
nicovv44 | 0:1f66eaf1013d | 123 | |
nicovv44 | 0:1f66eaf1013d | 124 | |
nicovv44 | 0:1f66eaf1013d | 125 | // ############################################## |
nicovv44 | 0:1f66eaf1013d | 126 | // ########## FUNCTIONS ######################### |
nicovv44 | 0:1f66eaf1013d | 127 | // ############################################################################# |
nicovv44 | 0:1f66eaf1013d | 128 | // ISR to stop loping |
nicovv44 | 0:1f66eaf1013d | 129 | void stopLooping(void) { |
nicovv44 | 0:1f66eaf1013d | 130 | looping = false;//looping is volatile bool |
nicovv44 | 0:1f66eaf1013d | 131 | } |
nicovv44 | 0:1f66eaf1013d | 132 | |
nicovv44 | 0:1f66eaf1013d | 133 | // ############################################################################# |
nicovv44 | 5:e9766e0573d0 | 134 | // ISR to update pwmDC with potarDC |
nicovv44 | 5:e9766e0573d0 | 135 | void tickerPWMDCfunction(){ |
nicovv44 | 5:e9766e0573d0 | 136 | float valuePotar1; |
nicovv44 | 5:e9766e0573d0 | 137 | float valuePotar2; |
nicovv44 | 5:e9766e0573d0 | 138 | valuePotar1 = potarDC.read(); |
nicovv44 | 7:1f7d87007512 | 139 | pwmDC.write(1-valuePotar1); |
nicovv44 | 5:e9766e0573d0 | 140 | valuePotar2 = potarSY.read(); |
nicovv44 | 7:1f7d87007512 | 141 | pwmSY.write(1-valuePotar2); |
nicovv44 | 5:e9766e0573d0 | 142 | //lcd.locate(12,0);//(col,row) |
nicovv44 | 5:e9766e0573d0 | 143 | //lcd.printf("%f",valuePotar); |
nicovv44 | 5:e9766e0573d0 | 144 | } |
nicovv44 | 5:e9766e0573d0 | 145 | |
nicovv44 | 9:70bfbd406554 | 146 | |
nicovv44 | 9:70bfbd406554 | 147 | // ############################################################################# |
nicovv44 | 9:70bfbd406554 | 148 | // ISR to update PID |
nicovv44 | 9:70bfbd406554 | 149 | void tickerPIDfunction(){ |
nicovv44 | 9:70bfbd406554 | 150 | PID1Output = PIDcontroller1.compute(); |
nicovv44 | 9:70bfbd406554 | 151 | pwmDC.write(1-PID1Output); //(1-duty) |
nicovv44 | 9:70bfbd406554 | 152 | pc.printf("PID1:%f\r\n\n", PID1Output); |
nicovv44 | 9:70bfbd406554 | 153 | } |
nicovv44 | 9:70bfbd406554 | 154 | |
nicovv44 | 9:70bfbd406554 | 155 | |
nicovv44 | 9:70bfbd406554 | 156 | // ############################################################################# |
nicovv44 | 9:70bfbd406554 | 157 | void initPID1(){ |
nicovv44 | 9:70bfbd406554 | 158 | //Input from 0.0 to 60Hz |
nicovv44 | 9:70bfbd406554 | 159 | PIDcontroller1.setInputLimits(0.0, 50.0); |
nicovv44 | 9:70bfbd406554 | 160 | //Pwm output from 0.0 to 1.0 |
nicovv44 | 9:70bfbd406554 | 161 | PIDcontroller1.setOutputLimits(0.0, 1.0); |
nicovv44 | 9:70bfbd406554 | 162 | //If there's a bias. |
nicovv44 | 11:b6bee52941ea | 163 | PIDcontroller1.setBias(0.70); |
nicovv44 | 9:70bfbd406554 | 164 | PIDcontroller1.setMode(true); |
nicovv44 | 9:70bfbd406554 | 165 | //We want the process variable to be 50Hz |
nicovv44 | 9:70bfbd406554 | 166 | PIDcontroller1.setSetPoint(50);//50Hz |
nicovv44 | 9:70bfbd406554 | 167 | } |
nicovv44 | 9:70bfbd406554 | 168 | |
nicovv44 | 5:e9766e0573d0 | 169 | // ############################################################################# |
nicovv44 | 0:1f66eaf1013d | 170 | float getVolageRMS(AnalogIn ana_pin){ |
nicovv44 | 0:1f66eaf1013d | 171 | float v1;//readed voltage |
nicovv44 | 0:1f66eaf1013d | 172 | float v1Max = 0;//max readed voltage |
nicovv44 | 0:1f66eaf1013d | 173 | float VRMS; //RMS voltage |
nicovv44 | 0:1f66eaf1013d | 174 | looping = true; |
nicovv44 | 1:f31a46c62d10 | 175 | timeout.attach(callback(&stopLooping), 0.020);//T=20ms because f=50Hz |
nicovv44 | 0:1f66eaf1013d | 176 | while(looping){ |
nicovv44 | 0:1f66eaf1013d | 177 | v1 = ana_pin.read()*3.3; |
nicovv44 | 0:1f66eaf1013d | 178 | if(v1 > v1Max){ |
nicovv44 | 0:1f66eaf1013d | 179 | v1Max = v1; |
nicovv44 | 0:1f66eaf1013d | 180 | } |
nicovv44 | 0:1f66eaf1013d | 181 | } |
nicovv44 | 3:a1b11dfd26f3 | 182 | VRMS = (v1Max+0.685)*9.32/sqrt2; |
nicovv44 | 4:886ce7eefa6e | 183 | //pc.printf("VRMS: %f\r\n",VRMS); |
nicovv44 | 0:1f66eaf1013d | 184 | return VRMS; |
nicovv44 | 0:1f66eaf1013d | 185 | } |
nicovv44 | 0:1f66eaf1013d | 186 | |
nicovv44 | 0:1f66eaf1013d | 187 | |
nicovv44 | 0:1f66eaf1013d | 188 | // ############################################################################# |
nicovv44 | 0:1f66eaf1013d | 189 | float getVolageReadedMax(AnalogIn ana_pin){ |
nicovv44 | 0:1f66eaf1013d | 190 | float v1;//readed voltage |
nicovv44 | 0:1f66eaf1013d | 191 | float v1Max = 0;//max readed voltage |
nicovv44 | 0:1f66eaf1013d | 192 | looping = true; |
nicovv44 | 1:f31a46c62d10 | 193 | timeout.attach(callback(&stopLooping), 0.025);//T=25>20ms because f=50Hz |
nicovv44 | 0:1f66eaf1013d | 194 | while(looping){ |
nicovv44 | 0:1f66eaf1013d | 195 | v1 = ana_pin.read()*3.3; |
nicovv44 | 0:1f66eaf1013d | 196 | if(v1 > v1Max){ |
nicovv44 | 0:1f66eaf1013d | 197 | v1Max = v1; |
nicovv44 | 0:1f66eaf1013d | 198 | } |
nicovv44 | 0:1f66eaf1013d | 199 | } |
nicovv44 | 0:1f66eaf1013d | 200 | return v1Max; |
nicovv44 | 0:1f66eaf1013d | 201 | } |
nicovv44 | 0:1f66eaf1013d | 202 | |
nicovv44 | 1:f31a46c62d10 | 203 | |
nicovv44 | 0:1f66eaf1013d | 204 | // ############################################################################# |
nicovv44 | 0:1f66eaf1013d | 205 | float getFrequency(AnalogIn ana_pin){ |
nicovv44 | 0:1f66eaf1013d | 206 | float freq; //frequency |
nicovv44 | 0:1f66eaf1013d | 207 | float maxReadedVoltage;//maximum voltage readed by the ADC |
nicovv44 | 0:1f66eaf1013d | 208 | float readedVoltage;//readed voltage |
nicovv44 | 0:1f66eaf1013d | 209 | int nbrRisingEdge=0;// number of rising edge detected |
nicovv44 | 0:1f66eaf1013d | 210 | float T;//Periode |
nicovv44 | 0:1f66eaf1013d | 211 | Timer timer; |
nicovv44 | 0:1f66eaf1013d | 212 | maxReadedVoltage = getVolageReadedMax(ana_pin); |
nicovv44 | 11:b6bee52941ea | 213 | //pc.printf("maxReadedVoltage: %f\r\n",maxReadedVoltage); |
nicovv44 | 0:1f66eaf1013d | 214 | bool aboveLine = true; |
nicovv44 | 11:b6bee52941ea | 215 | bool allowedClicTimer = false; |
nicovv44 | 1:f31a46c62d10 | 216 | looping = true; |
nicovv44 | 1:f31a46c62d10 | 217 | timeout.attach(callback(&stopLooping), 1);//try to find rising edges during 1sec max |
nicovv44 | 1:f31a46c62d10 | 218 | while(nbrRisingEdge<2 and looping){ |
nicovv44 | 0:1f66eaf1013d | 219 | readedVoltage = ana_pin.read()*3.3; |
nicovv44 | 0:1f66eaf1013d | 220 | if(readedVoltage<(maxReadedVoltage/2)){//rising edge detection ready |
nicovv44 | 0:1f66eaf1013d | 221 | aboveLine = false; |
nicovv44 | 0:1f66eaf1013d | 222 | } |
nicovv44 | 0:1f66eaf1013d | 223 | if((maxReadedVoltage/2)<readedVoltage && aboveLine==false){//rising edge detected |
nicovv44 | 11:b6bee52941ea | 224 | allowedClicTimer = true; |
nicovv44 | 0:1f66eaf1013d | 225 | aboveLine = true; |
nicovv44 | 11:b6bee52941ea | 226 | } |
nicovv44 | 11:b6bee52941ea | 227 | if((maxReadedVoltage*2/3)<readedVoltage && allowedClicTimer==true){//rising edge detected |
nicovv44 | 11:b6bee52941ea | 228 | allowedClicTimer = false; |
nicovv44 | 0:1f66eaf1013d | 229 | if(nbrRisingEdge==0) |
nicovv44 | 0:1f66eaf1013d | 230 | timer.start(); |
nicovv44 | 0:1f66eaf1013d | 231 | if(nbrRisingEdge==1) |
nicovv44 | 0:1f66eaf1013d | 232 | timer.stop(); |
nicovv44 | 0:1f66eaf1013d | 233 | nbrRisingEdge++; |
nicovv44 | 0:1f66eaf1013d | 234 | } |
nicovv44 | 11:b6bee52941ea | 235 | |
nicovv44 | 0:1f66eaf1013d | 236 | } |
nicovv44 | 1:f31a46c62d10 | 237 | if(nbrRisingEdge!=2){ |
nicovv44 | 1:f31a46c62d10 | 238 | lcd.locate(13,1); |
nicovv44 | 1:f31a46c62d10 | 239 | lcd.printf("f!%d",nbrRisingEdge); |
nicovv44 | 1:f31a46c62d10 | 240 | } |
nicovv44 | 0:1f66eaf1013d | 241 | T = timer.read(); |
nicovv44 | 0:1f66eaf1013d | 242 | freq = 1/T; |
nicovv44 | 4:886ce7eefa6e | 243 | //pc.printf("T: %f\r\n",T); |
nicovv44 | 4:886ce7eefa6e | 244 | //pc.printf("freq: %f\r\n\n",freq); |
nicovv44 | 11:b6bee52941ea | 245 | if(looping==false) |
nicovv44 | 11:b6bee52941ea | 246 | freq = 0; |
nicovv44 | 0:1f66eaf1013d | 247 | return freq; |
nicovv44 | 4:886ce7eefa6e | 248 | } |
nicovv44 | 4:886ce7eefa6e | 249 | |
nicovv44 | 4:886ce7eefa6e | 250 | |
nicovv44 | 4:886ce7eefa6e | 251 | // ############################################################################# |
nicovv44 | 4:886ce7eefa6e | 252 | void displayLCD(float syncRMS, float gridRMS, float syncFreq, float gridFreq){ |
nicovv44 | 9:70bfbd406554 | 253 | //lcd.locate(0,0);//(col,row) |
nicovv44 | 9:70bfbd406554 | 254 | //lcd.printf(" "); |
nicovv44 | 9:70bfbd406554 | 255 | lcd.locate(0,1);//(col,row) |
nicovv44 | 9:70bfbd406554 | 256 | lcd.printf(" "); |
nicovv44 | 9:70bfbd406554 | 257 | //lcd.locate(0,0);//(col,row) |
nicovv44 | 9:70bfbd406554 | 258 | //lcd.printf("G:%3.1f@%3.1f", gridRMS, gridFreq); |
nicovv44 | 9:70bfbd406554 | 259 | lcd.locate(0,1);//(col,row) |
nicovv44 | 9:70bfbd406554 | 260 | lcd.printf("S:%3.1f@%3.1f", syncRMS, syncFreq); |
nicovv44 | 9:70bfbd406554 | 261 | |
nicovv44 | 1:f31a46c62d10 | 262 | } |