Main code of our project.

Dependencies:   TextLCD mbed PID

main.cpp

Committer:
nicovv44
Date:
2018-10-24
Revision:
15:e1a76426fb6a
Parent:
14:3f7e54ee1211

File content as of revision 15:e1a76426fb6a:

#include "mbed.h"
#include "TextLCD.h"
#include "PID.h"

#define PIDRATE 0.2
 
//Kc, Ti, Td, interval
PID PIDcontroller1(2.9, 1.0, 0.0, PIDRATE);//frequency PID
PID PIDcontroller2(0.4, 1.0, 0.0, PIDRATE);//amplitude PID

TextLCD             lcd(D2, D3, D4, D5, D6, D7); // rs, e, d4-d7
Serial              pc(USBTX, USBRX); // tx, rx
PwmOut              pwmDC(D9);
PwmOut              pwmSY(D13);
DigitalOut          relay1(D8);
DigitalOut          relay2(D14);
DigitalOut          relay3(D11);
DigitalOut          relay4(D12);

DigitalIn           userButton(USER_BUTTON);

AnalogIn            syncPin(A0);
AnalogIn            gridPin(A1);
AnalogIn            differentialPin(A2);
AnalogIn            potarDC(A3);
AnalogIn            potarSY(A4);
AnalogIn            currentPin(A5);

const float         sqrt2 = 1.414213562;

Timeout             timeout;
Ticker              tickerPWMDC;
Ticker              tickerPID;
volatile bool       looping = false;
volatile bool       synchronized = false;
volatile bool       mainLoop = true;
volatile float      PID1Output;
volatile float      PID2Output;


// ##############################################
// ########## PROTOTYPES ########################
// #############################################################################
void stopLooping(void);
float getVolageRMS(AnalogIn ana_pin);
float getVolageReadedMax(AnalogIn ana_pin);
float getFrequency(AnalogIn ana_pin);
void displayLCD(float syncRMS, float gridRMS, float syncFreq, float gridFreq);
void tickerPWMDCfunction();
void initPID1();
void initPID2();
void tickerPIDfunction();
float getPhaseAngle(AnalogIn voltage_pin, AnalogIn current_pin);


// ##############################################
// ########## MAIN ##############################
// #############################################################################
int main() {
    float syncRMS, gridRMS, syncFreq, gridFreq;
    
    relay1 = 1;//Relay off=1, on=0
    relay2 = 1;//Relay off=1, on=0
    relay3 = 1;//Relay off=1, on=0
    relay4 = 0;//Relay off=1, on=0

    //initialise PIDcontrollers
    initPID1();
    initPID2();
    
    
    
    
    while(mainLoop){
        pwmDC.period(0.0002f);
        pwmDC.write(1-0.00f); //(1-duty)
        pwmSY.period(0.0002f); 
        pwmSY.write(1-0.00f); //(1-duty)
        
        while(userButton==1){;}
        
        pwmDC.write(1-0.900f); //(1-duty)
        pwmSY.write(1-0.80f); //(1-duty)
        //tickerPWMDC.attach(&tickerPWMDCfunction, 0.1);
        
        //pc.printf("\n\nAccelerating\r\n");
        lcd.printf("ACCELERATING");
        wait(5);//wait so the motor get steady state
        //pwmDC.write(1-0.00f); //(1-duty)
        
        //manual synchronisation
        while(!synchronized){
            //measure and calculate desired value
            syncRMS = getVolageRMS(syncPin);
            gridRMS = getVolageRMS(gridPin);
            syncFreq = getFrequency(syncPin);
            gridFreq = getFrequency(gridPin);
            //Update the PID process variable.
            PIDcontroller1.setProcessValue(syncFreq);
            PIDcontroller2.setProcessValue(syncRMS);
            //Interrupt for a correct PID rate
            //tickerPID.attach(&tickerPIDfunction, PIDRATE);
            //display values on LCD
            displayLCD(syncRMS, gridRMS, syncFreq, gridFreq);
            //update PID values
            PID1Output = PIDcontroller1.compute();
            PID2Output = PIDcontroller2.compute();
            //drive PWMs with PID values
            pwmDC.write(1-PID1Output); //(1-duty)
            pwmSY.write(1-PID2Output); //(1-duty)
            pc.printf("PID1:%f \t syncFreq:%f \r\n", PID1Output, syncFreq);
            pc.printf("PID2:%f \t syncRMS:%f \r\n\n", PID2Output, syncRMS);
            wait(PIDRATE);
            //voltage and frequency matching
            if(abs(syncRMS-gridRMS)<0.5 && abs(syncFreq-gridFreq)<0.1){
                //pc.printf("voltage and freqency OK\r\n");
                lcd.locate(11,0);//(col,row)
                lcd.printf("V&fOK");
                while(!synchronized){//phase matching loop
                    //measure and calculate desired value
                    syncRMS = getVolageRMS(syncPin);
                    gridRMS = getVolageRMS(gridPin);
                    syncFreq = getFrequency(syncPin);
                    gridFreq = getFrequency(gridPin);
                    //display values on LCD
                    displayLCD(syncRMS, gridRMS, syncFreq, gridFreq);
                    //phase matching
                    if(getVolageReadedMax(differentialPin) < 0.050){
                        //pc.printf("SYNCHONIZATION OK\r\n\n");
                        lcd.locate(12,1);//(col,row)
                        lcd.printf("SYNC");
                        relay1 = 0;//Relay off=1, on=0 // to hear the noise
                        relay2 = 0;//Relay off=1, on=0 // to hear the noise
                        relay3 = 0;//Relay off=1, on=0 // to hear the noise
                        relay4 = 1;//Relay off=1, on=0 // to hear the noise
                        pwmDC.write(1-0.00f); //(1-duty)
                        pwmSY.write(1-0.00f); //(1-duty)
                        synchronized = true;
                        mainLoop = false;
                    }
                }
            }
        }
        while(true)
        getPhaseAngle(currentPin, gridPin);
    }
}







// ##############################################
// ########## FUNCTIONS #########################
// #############################################################################
// ISR to stop loping
void stopLooping(void) {
    looping = false;//looping is volatile bool
}

// #############################################################################
// ISR to update pwmDC with potarDC
void tickerPWMDCfunction(){
    float valuePotar1;
    float valuePotar2;
    valuePotar1 = potarDC.read();
    pwmDC.write(1-valuePotar1);
    valuePotar2 = potarSY.read();
    pwmSY.write(1-valuePotar2);
    //lcd.locate(12,0);//(col,row)
    //lcd.printf("%f",valuePotar);
}


// #############################################################################
// ISR to update PID
void tickerPIDfunction(){
    PID1Output = PIDcontroller1.compute();
    pwmDC.write(1-PID1Output); //(1-duty)
    pc.printf("PID1:%f\r\n\n", PID1Output);
}


// #############################################################################
void initPID1(){
    //Input 
    PIDcontroller1.setInputLimits(0.0, 100.0);
    //Pwm output from 0.0 to 1.0
    PIDcontroller1.setOutputLimits(0.0, 1.0);
    //If there's a bias.
    PIDcontroller1.setBias(0.70);
    PIDcontroller1.setMode(true);
    //We want the process variable to be 50Hz
    PIDcontroller1.setSetPoint(50);//50Hz
}

// #############################################################################
void initPID2(){
    //Input 
    PIDcontroller2.setInputLimits(0.0, 25.0);
    //Pwm output from 0.0 to 1.0
    PIDcontroller2.setOutputLimits(0.0, 1.0);
    //If there's a bias.
    PIDcontroller2.setBias(0.70);
    PIDcontroller2.setMode(true);
    //We want the process variable to be 50Hz
    PIDcontroller2.setSetPoint(getVolageRMS(gridPin));
}

// #############################################################################
float getVolageRMS(AnalogIn ana_pin){
    float v1;//readed voltage
    float v1Max = 0;//max readed voltage
    float VRMS; //RMS voltage
    looping = true;
    timeout.attach(callback(&stopLooping), 0.020);//T=20ms because f=50Hz
    while(looping){
        v1 = ana_pin.read()*3.3;
        if(v1 > v1Max){
            v1Max = v1;
        }
    }
    VRMS = (v1Max+0.685)*9.32/sqrt2;
    //pc.printf("VRMS: %f\r\n",VRMS);
    return VRMS;
}


// #############################################################################
float getVolageReadedMax(AnalogIn ana_pin){
    float v1;//readed voltage
    float v1Max = 0;//max readed voltage
    looping = true;
    timeout.attach(callback(&stopLooping), 0.025);//T=25>20ms because f=50Hz
    while(looping){
        v1 = ana_pin.read()*3.3;
        if(v1 > v1Max){
            v1Max = v1;
        }
    }
    return v1Max;
}


// #############################################################################
float getFrequency(AnalogIn ana_pin){
    float   freq; //frequency
    float   maxReadedVoltage;//maximum voltage readed by the ADC
    float   readedVoltage;//readed voltage
    int     nbrRisingEdge=0;// number of rising edge detected
    float   T;//Periode
    Timer   timer;
    maxReadedVoltage = getVolageReadedMax(ana_pin);
    //pc.printf("maxReadedVoltage: %f\r\n",maxReadedVoltage);
    bool aboveLine = true;
    bool allowedClicTimer = false;
    looping = true;
    timeout.attach(callback(&stopLooping), 1);//try to find rising edges during 1sec max
    while(nbrRisingEdge<2 and looping){
        readedVoltage = ana_pin.read()*3.3;
        if(readedVoltage<(maxReadedVoltage/2)){//rising edge detection ready
            aboveLine = false;
        }
        if((maxReadedVoltage/2)<readedVoltage && aboveLine==false){//rising edge detected
            allowedClicTimer = true;
            aboveLine = true;
        }
        if((maxReadedVoltage*2/3)<readedVoltage && allowedClicTimer==true){//rising edge detected
            allowedClicTimer = false;
            if(nbrRisingEdge==0)
                timer.start();
            if(nbrRisingEdge==1)
                timer.stop();
            nbrRisingEdge++;
        }
        
    }
    if(nbrRisingEdge!=2){
        lcd.locate(13,1);
        lcd.printf("f!%d",nbrRisingEdge);
    }
    T = timer.read();
    freq = 1/T;
    //pc.printf("T: %f\r\n",T);
    //pc.printf("freq: %f\r\n\n",freq);
    if(looping==false)
    freq = 0;
    return freq;
}


// #############################################################################
void displayLCD(float syncRMS, float gridRMS, float syncFreq, float gridFreq){
    lcd.locate(0,0);//(col,row)
    lcd.printf("                ");
    lcd.locate(0,1);//(col,row)
    lcd.printf("                ");
    lcd.locate(0,0);//(col,row)
    lcd.printf("G:%3.1f@%3.1f", gridRMS, gridFreq);
    lcd.locate(0,1);//(col,row)
    lcd.printf("S:%3.1f@%3.1f", syncRMS, syncFreq);
    
}


// #############################################################################
float getPhaseAngle(AnalogIn voltage_pin, AnalogIn current_pin){
    bool searchingInstant = true;
    Timer   timer1;
    float voltageValue;
    //float   maxReadedVoltageVoltage, maxReadedVoltageCurrent;//maximum voltage readed by the ADC
    //maxReadedVoltageVoltage = getVolageReadedMax(voltage_pin);
    //maxReadedVoltageCurrent= getVolageReadedMax(current_pin);
    //pc.printf("maxReadedVoltageVoltage: %f \t maxReadedVoltageCurrent: %f\r\n", maxReadedVoltageVoltage, maxReadedVoltageCurrent);
    while(searchingInstant){
        voltageValue = voltage_pin.read();
        //pc.printf("voltageValue voltage:%f\n\r",voltageValue);
        if(voltageValue < 0.50){
            timer1.start();
            searchingInstant = false;
        }
    }
    searchingInstant = true;
    while(searchingInstant){
        voltageValue = current_pin.read();
        //pc.printf("voltageValue current:%f\n\r",voltageValue);
        if(voltageValue < 0.050){
            timer1.stop();
            searchingInstant = false;
        }
    }
    pc.printf("phaseAngle:%f\n\r",timer1.read()*180/0.020);
    return 0;
}