Andreas Steffen / Mbed 2 deprecated PIservo

Dependencies:   mbed

main.cpp

Committer:
Reignbow
Date:
2013-03-04
Revision:
5:bf2ed3846087
Parent:
4:c38f7e4e8fda

File content as of revision 5:bf2ed3846087:

/* PIservo
 implement a PI controller with USB serial gain setting to stabilize dipole trap power.
 Two analog inputs (control and sensor), one analog output (to RF VCA).

20120806 Andreas Steffen
*/


#include "mbed.h"

DigitalOut adcCS(p8);
DigitalOut dacCS(p14);
DigitalOut cyc(p10);
AnalogOut vca(p18);
SPI adc(p5,p6,p7); //talk to ad7921 on SSP1
SPI dac(p11,p12,p13); //talk to ad5551 on SSP0
Serial pc(USBTX, USBRX);


Ticker commTick;
Ticker limTick;

// PI variables
int pGain = 7000;
int iGain = 12000; 
int ctl=0;
int pd=0;
int err=0;
int out = 0;
int integrator = 0; //the building up integrator value

//control variables
int monitor = 0; //echo to serial?
int testDAC = 0; //stops PI, just 0-5V jumps on output


extern "C" void mbed_reset(); 


void serialComm(){
    char c;
    int i;
    
    if (monitor) {
        pc.printf("Measuring ctl=%i and pd=%i, err=%i, integrator= %i, out=%i\n",ctl,pd,err,integrator,out);
    }
    
    if (pc.readable()) { 
        c = pc.getc();
        pc.scanf("%i", &i);
        switch (c) {
            case 'p':
                pGain = i;   
                pc.printf("Changed p gain to %i.\n",pGain);
                break;
            case 'i':
                iGain = i;   
                pc.printf("Changed i gain to %i.\n",iGain);
                if (i==0)
                    integrator = 0;
                break;
            case 'm':
                monitor = i;
                break;
            case 't':
                testDAC = i;
                pc.printf("Turning on test mode... outputting 0-5 V on DAC\n");
                break;
            case 'z':
                mbed_reset();
                break;
            default:
                pc.printf("Command not understood.\n",iGain);
                pc.printf("Read %c and %i.\n",c,i);
                break;
        }
    }
}


void limitIntegrator() {
    if(integrator < -(1<<14)/iGain) {
        integrator = -(1<<14)/iGain;
    }
    if(integrator > (1<<14)/iGain) {
        integrator = (1<<14)/iGain;
    }
}

int main() {
    pc.printf("mbed restarted!\n");
    
    adc.format(16,2);
    adc.frequency(5e6); 
    dac.format(14,2);
    dac.frequency(20e6); 
    
    commTick.attach(&serialComm,1); //check serial every  second  
    //limTick.attach_us(&limitIntegrator,500); //check integrator overflow every 500 us  
    cyc = 0;    

    while(1) {
        cyc = cyc^1; //toggle debug pin
        
        while (testDAC) {
            dacCS = 1;
            dacCS = 0;
            LPC_SSP0->DR = 0x3FFF;
            wait_us(1000);
            dacCS = 1;
            dacCS = 0;
            LPC_SSP0->DR = 0;
            wait_us(1000);
        } 
        
        //stagger read and output
        //The SPI read takes a long time, so start it by writing to the data
        //register, do sth. else (write new output), then get the value 
        //and start the read from the other channel
       
       //begin SPI transfer
        adcCS = 0;
        LPC_SSP1->DR = 3<<13; //select ch 1
        
        //write to DAC  
        err = ctl - pd;   
        integrator += err;          
        dacCS = 0;
        // if control is very low (probably 0V), no output and no integrator
        // otherwise integrator overflows from stray light!
        if (ctl < 20) { 
            err = 0;    
            integrator = 0;
        }
        out = ( (err * pGain  + integrator)>>12 ) & 0x3FFF;
        LPC_SSP0->DR = out;
                
        //read SPI transfer results
        while(LPC_SSP1->SR & 0x10) {} //check for busy p 10   
        pd =  LPC_SSP1->DR & 0xFFF; //last 12 bits are data    
        wait_us(1);  //delay necessary for unknown reason    
        adcCS = 1;
        while(LPC_SSP0->SR & 0x10) {}
        dacCS = 1; 
          

        
        //begin transfer from other channel
        adcCS = 0;
        LPC_SSP1->DR = 1; //select ch 0
        
        //write to DAC
        err = ctl-pd;   
        integrator += err*iGain;                   
        dacCS = 0;
        // if control is very low (probably 0V), no output and no integrator
        // otherwise integrator overflows from stray light!
        if (ctl < 20) { 
            err = 0;    
            integrator = 0;
        }
        out = ( (err * pGain  + integrator)>>12 ) & 0x3FFF;
        LPC_SSP0->DR = out; 
              
        //read SPI transfer results
        while(LPC_SSP1->SR & 0x10) {}        
        ctl = LPC_SSP1->DR & 0xFFF; //last 12 bits are data  
        wait_us(1);  //delay necessary for unknown reason    
        adcCS = 1;    
        while(LPC_SSP0->SR & 0x10) {}
        dacCS = 1;     
        
        
      
    }
}