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);
}