practice for PID control
Dependencies: PID QEI USBDevice mbed
main.cpp
- Committer:
- NT32
- Date:
- 2014-04-15
- Revision:
- 0:b2973a157cb6
- Child:
- 1:6d5c35b995fb
File content as of revision 0:b2973a157cb6:
#include "mbed.h" #include "USBSerial.h" #include "QEI.h" #include "PID.h" #define PIDRATE 0.01 #define CW 0x01 #define CCW 0x02 #define STOP 0x03 #define FREE 0x00 #define kc 2.8 #define ti 16.0 #define td 0.0 USBSerial vcom; SPI spi(P0_21, NC, P1_20); DigitalOut cs(P1_23); //Ticker flip; Timer timer; PID controller(kc, ti, td, PIDRATE); QEI wheel (P1_15, P0_19, NC, 1, QEI::X4_ENCODING); BusOut gled(P0_8, P0_9); BusOut mdrv(P1_27, P1_26); DigitalIn SW(P0_1); void pidsetup(); union MCP4922 { uint16_t command; struct { //DAC data bits uint16_t D :12; //Output power down control bit uint8_t SHDN:1; //Outout gain select bit uint8_t GA :1; //Vref input buffer Control bit uint8_t BUF :1; //DACa or DACb select bit uint8_t AB :1; }bit; }; union MCP4922 dac = {0xF7F}; //void tick() //{ // static int tcnt, efpls; // int epls; // float etmppls; // tcnt++; // if(SW == 0) // { // wheel.reset(); // } // if(tcnt == 40) // { // tcnt = 0; // epls = wheel.getPulses(); // etmppls = (float)(epls - efpls); // efpls = epls; // vcom.printf("\033[%d;%dH", 0, 0); // vcom.printf("count :%9d\n", epls); // vcom.printf("rev/sec:%3.6f\n", (etmppls / 3600)); // vcom.printf("DAC.bit:%09d\n", dac.bit.D); // } //// cs = 0; //// spi.write(dac.command); //// cs = 1; //} int main() { uint8_t i = 0; int epls[2] = {0, 0}; float rps = 0; // flip.attach(tick, (PIDRATE / 2)); SW.mode(PullUp); mdrv = CW; cs = 1; dac.bit.AB = 0; dac.bit.BUF = 1; dac.bit.GA = 1; dac.bit.SHDN = 1; dac.bit.D = 0; spi.format(16,0); spi.frequency(20000000); cs = 0; spi.write(dac.command); cs = 1; //Revolution per second input from 0.0 to 50.0rev/sec controller.setInputLimits(0.0, 30.0); //DAC output from 0.0 to 4096.0 controller.setOutputLimits(0.0, 4095.0); //If there's a bias. controller.setBias(1000.0); controller.setMode(AUTO_MODE); //We want the process variable to be 12rev/sec controller.setSetPoint(12.0); while(SW == 1) { if(i == 100) { i = 0; vcom.printf("\033[%d;%dH", 0, 0); vcom.printf("DAC.d :%012d\n", dac.bit.D); vcom.printf("rps :%12.4f", rps); } i++; gled = i; epls[1] = wheel.getPulses(); rps = ((float)(epls[1] - epls[0]) / PIDRATE) / 3600; epls[0] = epls[1]; controller.setProcessValue(rps); dac.bit.D = (int)controller.compute(); cs = 0; spi.write(dac.command); cs = 1; wait(PIDRATE); } pidsetup(); i = 0; rps = 0; epls[0] = 0; timer.reset(); timer.start(); while(1) { if(SW == 0) { timer.stop(); pidsetup(); timer.reset(); timer.start(); } if(i == 10) { vcom.printf("%d,%d\n" , timer.read_ms(), dac.bit.D); i = 0; } i++; gled = i; epls[1] = wheel.getPulses(); rps = ((float)(epls[1] - epls[0]) / PIDRATE) / 3600; epls[0] = epls[1]; controller.setProcessValue(rps); dac.bit.D = (int)controller.compute(); cs = 0; spi.write(dac.command); cs = 1; wait(PIDRATE); } } void pidsetup() { char str[64] = {'\0'}, *erstr; float tmp[3]; dac.bit.D = 0; cs = 0; spi.write(dac.command); cs = 1; controller.reset(); vcom.printf("\033[2J"); vcom.printf("\033[%d;%dH", 0, 0); //Output bias vcom.printf("Input the bias for the controller output\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[0] = strtof(str, &erstr); controller.setBias(tmp[0]); vcom.printf("Output bias : %15f\n", tmp[0]); //Input limits vcom.printf("Input the minimum inputlimit\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[0] = strtof(str, &erstr); vcom.printf("Minimum input limit : %15f\n", tmp[0]); vcom.printf("Input the maximum inputlimit\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[1] = strtof(str, &erstr); vcom.printf("Maximum input limit : %15f\n", tmp[1]); controller.setInputLimits(tmp[0], tmp[1]); //Output limits vcom.printf("Input the minimum outputlimit\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[0] = strtof(str, &erstr); vcom.printf("Minimum output limit : %15f\n", tmp[0]); vcom.printf("Input the maximum outputlimit\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[1] = strtof(str, &erstr); vcom.printf("Maximum output limit : %15f\n", tmp[1]); controller.setOutputLimits(tmp[0], tmp[1]); //Setpoint vcom.printf("Input the setpoint\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[0] = strtof(str, &erstr); controller.setSetPoint(tmp[0]); vcom.printf("Setpoint : %15f\n", tmp[0]); //tuning parameter vcom.printf("Input the proportional gain\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[0] = strtof(str, &erstr); vcom.printf("proportional gain : %15f\n", tmp[0]); vcom.printf("Input the integral gain\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[1] = strtof(str, &erstr); vcom.printf("integral gain : %15f\n", tmp[1]); vcom.printf("Input the derivative gain\n"); vcom.printf("within 15 figures.\n"); vcom.scanf("%s", str); tmp[2] = strtof(str, &erstr); vcom.printf("derivative gain : %15f\n", tmp[2]); controller.setTunings(tmp[0], tmp[1], tmp[2]); //interval // vcom.printf("Input the interval seconds\n"); // vcom.printf("within 15 figures.\n"); // vcom.scanf("%s", str); // tmp[0] = strtof(str, &erstr); controller.setInterval(PIDRATE); vcom.printf("\033[2J"); //PID mode controller.setMode(AUTO_MODE); }