practice for PID control
Dependencies: PID QEI USBDevice mbed
main.cpp
- Committer:
- NT32
- Date:
- 2014-05-02
- Revision:
- 4:adf167473520
- Parent:
- 3:e9aeee8b41e4
- Child:
- 5:f668eb3ee52a
File content as of revision 4:adf167473520:
#include "mbed.h" #include "USBSerial.h" #include "QEI.h" #include "PID.h" #include "SDFileSystem.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); 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 initialize(); 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}; int main() { uint8_t i = 0; int epls[2] = {0, 0}; float rps = 0; //IO,DAconverter and PID parameters configuretion. initialize(); //this block is the demonstration of PID control until BOOT switch is pushed. while(SW == 1) { //this block is the outputs DAC data and revolution per second of motor. 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); } //led is blinked to display the loop of PID control. i++; gled = i; //calculate rps. 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(); //send a command to change output of voltage. cs = 0; spi.write(dac.command); cs = 1; wait(PIDRATE); } pidsetup(); i = 0; rps = 0; epls[0] = 0; timer.reset(); timer.start(); vcom.printf("%d,%d,%f\n" , timer.read_ms(), dac.bit.D, rps); i = 0; while(1) { if(SW == 0) { timer.stop(); pidsetup(); timer.reset(); timer.start(); vcom.printf("%d,%d,%f\n" , timer.read_ms(), dac.bit.D, 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; if(i == 10) { vcom.printf("%d,%d,%f\n" , timer.read_ms(), dac.bit.D, rps); i = 0; } wait(PIDRATE); } } void initialize() { 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); } 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]); controller.setBias(200); //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]); controller.setInputLimits(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]); controller.setOutputLimits(0, 4095); //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"); vcom.printf("\033[%d;%dH", 0, 0); vcom.printf("Make a logfile by name of the \" hoge.csv \"\n"); vcom.printf("Push the boot switch to start PID control."); while(SW == 1){}; wait(0.1); while(SW == 0){}; vcom.printf("\033[2J"); vcom.printf("\033[%d;%dH", 0, 0); //PID mode controller.setMode(AUTO_MODE); }