Makoto Kobayashi / Mbed 2 deprecated Kikaikougaku_Jikken_mecolab

Dependencies:   PID QEI mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //include header file
00002 #include "mbed.h"
00003 #include "QEI.h"
00004 #include "PID.h"
00005 #include "setting.h"
00006 
00007 //define
00008 #define PULSE_PER_REVOLUTION 200
00009 #define PID_RATE 10     //wait **ms. If you change this value, response will be slightly different.
00010 #define GEAR_RATIO 2
00011 
00012 #define KP_SCALE 10
00013 #define TI_SCALE 20
00014 
00015 //IO pin setting
00016 DigitalOut led1(LED1);      //mbed LED outputs
00017 DigitalOut led2(LED2);
00018 DigitalOut led3(LED3);
00019 DigitalOut led4(LED4);
00020 DigitalIn dip1(p5);         //DIP switch inputs
00021 DigitalIn dip2(p6);
00022 DigitalIn dip3(p7);
00023 DigitalIn dip4(p8);
00024 DigitalIn startsw(p9);      //push switch input
00025 DigitalOut buzzer(p18);     //buzzer output
00026 AnalogIn volume(p20);       //potentiometer input
00027 PwmOut pwm(p25);            //pwm output to a motordriver
00028 
00029 //other setting
00030 Serial pc(USBTX, USBRX);        //set serial communication with PC
00031 QEI encoder(p30, p29, NC, PULSE_PER_REVOLUTION, QEI::X2_ENCODING);      //QEI setting (See QEI.cpp)
00032 Timer timer;                //mbed timer setting (See mbed description)
00033 
00034 //structure of experimentation result
00035 typedef struct{
00036     unsigned short t;
00037     short rpm;
00038 } result;
00039 
00040 //prototype declaration
00041 int Init();
00042 int DipLed();
00043 int GetDipValue();
00044 int SW();
00045 int Buzzer(int buzvar);
00046 
00047 //main function
00048 int main() {
00049     Buzzer(2);  //ring buzzer after pushing a reset button
00050     LocalFileSystem local("local");     //set mbed root directory as "local"
00051     Init();     //initialize
00052     int flag = 0;       //variable of operation mode
00053     result exp[(int)(15*1000/PID_RATE+1)] = {};     //variable for experimentation result
00054     
00055     while(1){       //main loop
00056         Init();     //initialize
00057         for(int i = 0; i <= 15*1000/PID_RATE; i++){     //initialize result structure
00058             exp[i].t = 0;
00059             exp[i].rpm = 0;
00060         }
00061         SW();       //wait for startswitch push
00062         flag = GetDipValue();       //read DIP switch value
00063         DipLed();       //make mbed LED shine
00064         Buzzer(1);      //ring buzzer mode 1
00065         
00066         switch (flag){
00067             /*********************mode 0**********************/
00068             case 0:         //mode 0: nothing
00069                 break;
00070             /*********************mode 1**********************/
00071             case 1:{        //mode 1: manually operated mode
00072                 float vol = 0;      //variable of potentiometer
00073                 float rpm = 0;      //variable of rpm
00074                 float t = 0;        //variable of time
00075                 int i1 = 0;         //variable of loop count
00076                 encoder.reset();
00077                 timer.reset();
00078                 timer.start();
00079                 while(1){
00080                     vol = 1 - volume;       //min position(max input(H))<-----potentiometer=====>(min input(L))max position
00081                     pwm = vol;
00082                     if(i1 >= 20){           //show duty ratio and rpm in PC every sec
00083                         t = timer.read();
00084                         rpm = (float)encoder.getPulses() / 2 / PULSE_PER_REVOLUTION * 60 / t * GEAR_RATIO;  //reduction ratio 1/2
00085                         pc.printf("Duty Ratio = %.3f , %6d RPM\n", vol, (int)rpm);
00086                         encoder.reset();
00087                         i1 = 0;
00088                         timer.reset();
00089                     }
00090                     wait_ms(50);
00091                     i1++;
00092                 }
00093                 break;
00094             }
00095             /*********************mode 2**********************/
00096             case 2:{        //mode 2: step input
00097                 float dt = 0, tnow = 0, tpre = 0;
00098                 exp[0].t = 0;
00099                 exp[0].rpm = 0;
00100                 encoder.reset();
00101                 timer.reset();
00102                 timer.start();
00103                 pwm = 1;        //duty ratio 1
00104                 for(int i = 0; i < 15*1000/PID_RATE; i++){      //variable assignment in every PID_RATE
00105                     wait_ms(PID_RATE);
00106                     tpre = tnow;
00107                     tnow = timer.read();
00108                     exp[i+1].t = (unsigned short)(tnow * 1000);
00109                     dt = tnow - tpre;
00110                     exp[i+1].rpm = (short)((float)encoder.getPulses() / 2 / PULSE_PER_REVOLUTION * 60 / dt * GEAR_RATIO);
00111                     encoder.reset();
00112                 }
00113                 for(int i = 100; i >= 0; i--){      //stopping motor slowly
00114                     pwm = (float)i / 100;
00115                     wait_ms(20);
00116                 }
00117                 pwm = 0;
00118                 wait(1);
00119                 FILE * fp = fopen("/local/exp2.csv","w");
00120                 if(fp == NULL){
00121                     Buzzer(-1);
00122                     break;
00123                 }
00124                 fprintf(fp,"Time , RPM\n");
00125                 for(int i = 0; i <= 15*1000/PID_RATE; i++){     //output results
00126                     fprintf(fp,"%f , %d\n", (float)exp[i].t / 1000.0, exp[i].rpm);
00127                 }
00128                 fclose(fp);
00129                 Buzzer(4);      //ring finish buzzer
00130                 break;
00131             }
00132             /*********************mode 3**********************/
00133             case 3:{        //mode 3: PID control
00134                 float kp = 0, ti = 0, td = 0, max_rpm = 0, target_rpm = 0, reduction = 0, dt = 0, tnow = 0, tpre = 0, rpmnow = 0;
00135                 encoder.reset();
00136                 timer.reset();
00137                 
00138                 kp = KP / KP_SCALE;        //substitute from setting.h
00139                 ti = TI * TI_SCALE;
00140                 td = TD;
00141                 max_rpm = MAX_RPM;
00142                 target_rpm = TARGET_RPM;
00143                 
00144                 PID pid(kp, ti, td, PID_RATE);      //PID setting (see PID.cpp)
00145                 pid.setInputLimits(0.0, max_rpm);
00146                 pid.setOutputLimits(0.0, 1.0);
00147                 pid.setMode(AUTO_MODE);
00148                 pid.setSetPoint(target_rpm);
00149                 
00150                 exp[0].t = 0;
00151                 exp[0].rpm = 0;
00152                 timer.start();      //count start
00153                 for(int i = 0; i < 15*1000/PID_RATE; i++){      //PID control loop(15 seconds)
00154                     tpre = tnow;
00155                     tnow = timer.read();
00156                     exp[i+1].t = (unsigned short)(tnow * 1000);
00157                     dt = tnow - tpre;
00158                     rpmnow = (float)encoder.getPulses() / 2 / PULSE_PER_REVOLUTION * 60 / dt * GEAR_RATIO;
00159                     exp[i+1].rpm = (short)rpmnow;
00160                     pid.setProcessValue(rpmnow);
00161                     pwm = pid.compute();
00162                     encoder.reset();
00163                     wait_ms(PID_RATE);
00164                 }
00165                 reduction = pwm.read();     //stopping slowly loop
00166                 for(int i = 0; i <= 100; i++){
00167                     pwm = pwm.read() - reduction / 100;
00168                     wait_ms(20);
00169                 }
00170                 pwm = 0;
00171                 FILE *fp = fopen("/local/exp3.csv","w");
00172                 if(fp == NULL){
00173                     Buzzer(-1);
00174                     break;
00175                 }
00176                 fprintf(fp,", kp = %.6f  ti = %.6f  td = %.6f\n", (float)KP, (float)TI, (float)TD);
00177                 fprintf(fp,"Time , RPM\n");
00178                 for(int i = 0; i <= 15*1000/PID_RATE; i++){     //output results
00179                     fprintf(fp,"%f , %d\n", (float)exp[i].t / 1000.0, exp[i].rpm);
00180                 }
00181                 fclose(fp);
00182                 Buzzer(5);      //ring finish buzzer
00183                 break;
00184             }
00185             /*********************default**********************/
00186             default:
00187                 break;
00188         }
00189     }
00190 }
00191 
00192 int Init(){     //initialize function
00193     pwm = 0;
00194     led1 = 0;
00195     led2 = 0;
00196     led3 = 0;
00197     led4 = 0;
00198     buzzer = 0;
00199     pc.baud(9600);
00200     encoder.reset();
00201     timer.reset();
00202     pwm.period_us(25);
00203     DipLed();
00204     return 0;
00205 }
00206 
00207 int DipLed(){       //LED flash function
00208     if(dip1 == 1) led1 = 1; else led1 = 0;
00209     if(dip2 == 1) led2 = 1; else led2 = 0;
00210     if(dip3 == 1) led3 = 1; else led3 = 0;
00211     if(dip4 == 1) led4 = 1; else led4 = 0;
00212     return 0;
00213 }
00214 
00215 int GetDipValue(){      //DIP switch function
00216     int Dip1 = dip1, Dip2 = dip2, Dip3 = dip3, Dip4 = dip4;
00217     if(Dip1 == 0){
00218         if(Dip2 == 0){
00219             if(Dip3 == 0){
00220                 if(Dip4 == 0) return 0; else return 1;
00221             }else{
00222                 if(Dip4 == 0) return 2; else return 3;
00223             }
00224         }else{
00225             if(Dip3 == 0){
00226                 if(Dip4 == 0) return 4; else return 5;
00227             }else{
00228                 if(Dip4 == 0) return 6; else return 7;
00229             }
00230         }
00231     }else{
00232         if(Dip2 == 0){
00233             if(Dip3 == 0){
00234                 if(Dip4 == 0) return 8; else return 9;
00235             }else{
00236                 if(Dip4 == 0) return 10; else return 11;
00237             }
00238         }else{
00239             if(Dip3 == 0){
00240                 if(Dip4 == 0) return 12; else return 13;
00241             }else{
00242                 if(Dip4 == 0) return 14; else return 15;
00243             }
00244         }
00245     }
00246 }
00247 
00248 int SW(){       //startswitch function
00249     int i = 0, j = 0;
00250     while(i < 3){
00251         if(startsw == 1) i++;
00252         else i = 0;
00253         DipLed();
00254         wait_ms(5);
00255     }
00256     while(j < 3){
00257         if(startsw == 0) j++;
00258         else j = 0;
00259         DipLed();
00260         wait_ms(5);
00261     }
00262     return 0;
00263 }
00264 
00265 int Buzzer(int buzvar){     //ringing buzzer function
00266     switch (buzvar){
00267         case -3:        //error * - -
00268             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1);
00269             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00270             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00271             break;
00272         case -2:        //error * - - -
00273             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1);
00274             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00275             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00276             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00277             break;
00278         case -1:        //error * - - - -
00279             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1);
00280             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00281             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00282             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00283             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00284             break;
00285         case 0:         //no sound
00286             buzzer = 0;
00287             break;
00288         case 1:         //*
00289             buzzer = 1; wait(0.1); buzzer = 0;
00290             break;
00291         case 2:         //* *
00292             buzzer = 1; wait(0.1); buzzer = 0; wait(0.05);
00293             buzzer = 1; wait(0.1); buzzer = 0;
00294             break;
00295         case 3:         //-
00296             buzzer = 1; wait(0.3); buzzer = 0;
00297             break;
00298         case 4:         //- -
00299             buzzer = 1; wait(0.3); buzzer = 0; wait(0.3);
00300             buzzer = 1; wait(0.3); buzzer = 0;
00301             break;
00302         case 5:         //---
00303             buzzer = 1; wait(0.9); buzzer = 0;
00304             break;
00305         case 6:         //* * *  * * *  * * *  *
00306             for(int i = 0; i < 3; i++){
00307                 for(int j = 0; j < 3; j++){
00308                     buzzer = 1; wait(0.1); buzzer = 0; wait(0.1);
00309                 }
00310                 wait(0.2);
00311             }
00312             buzzer = 1; wait(0.1); buzzer = 0;
00313             break;
00314         case 7:         // **-* ** -* ** *** ****
00315             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00316             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00317             buzzer = 1; wait(0.3); buzzer = 0; wait(0.1); 
00318             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00319             wait(0.2);
00320             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00321             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00322             wait(0.2);
00323             buzzer = 1; wait(0.3); buzzer = 0; wait(0.1); 
00324             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00325             wait(0.2);
00326             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00327             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00328             wait(0.2);
00329             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00330             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00331             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00332             wait(0.2);
00333             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00334             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00335             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00336             buzzer = 1; wait(0.1); buzzer = 0;
00337             break;
00338         case 8:         // *-*** -*- --*
00339             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1);
00340             buzzer = 1; wait(0.3); buzzer = 0; wait(0.1);
00341             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00342             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00343             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00344             wait(0.2);
00345             buzzer = 1; wait(0.3); buzzer = 0; wait(0.1); 
00346             buzzer = 1; wait(0.1); buzzer = 0; wait(0.1); 
00347             buzzer = 1; wait(0.3); buzzer = 0; wait(0.1); 
00348             wait(0.2);
00349             buzzer = 1; wait(0.3); buzzer = 0; wait(0.1); 
00350             buzzer = 1; wait(0.3); buzzer = 0; wait(0.1); 
00351             buzzer = 1; wait(0.1); buzzer = 0;
00352             break;
00353         default:        //no sound
00354             buzzer = 0;
00355             break;
00356     }
00357     return 0;
00358 }