![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
This program is designed for control a VTOL plant at Mines Faculty - National University of Colombia.
Dependencies: DebouncedIn PID QEI SRF05 TextLCD mbed
Fork of SensoresUltrasonicosSRF05 by
main.cpp
- Committer:
- stevenjigo
- Date:
- 2016-07-30
- Revision:
- 1:ad1952c5a3d7
- Parent:
- 0:92ceb941f65e
File content as of revision 1:ad1952c5a3d7:
/* Universidad Nacional de Colombia - Sede Medellín - Facultad de Minas 2015 - 01 Este programa realizar el Control de un motor Brushless con el cual se busca controlar la posición angular de un brazo con un pivote con la tarjeta Freescale KL25Z Este proyecto se realiza como un PAE con la profesora Ph.D. Eliana Isabel Arango Zuluaga Este proyecto es desarrollado por los estudiantes Steven Jiménez Gómez - Ingeniería Eléctrica Carlos Alberto Arbeláez Giraldo - Ingeniería de Control */ // DEFINICIÓN DE LIBRERÍAS A USAR #include "mbed.h" #include "TextLCD.h" #include "DebouncedIn.h" #include "QEI.h" #include "SRF05.h" #include <math.h> // La librería mbed.h debe agregarse siempre para el funcionamiento del programa // La librería TextLCD.h es la librería para controlar el LCD, en este caso, 16x2 // La librería DebouncedIn.h evita los rebotes debido a la pulsación de botones // La librería QEI.h permite manejar un encoder de cuadratura // La librería US05.h ayuda a leer los datos del sensor de ultrasonido // CONFIGURACIÓN DE LOS PINES A USAR Serial PC(USBTX, USBRX); // tx, rx // Definición del puerto serial con el computador SRF05 US(PTA4, PTA12); // Se define el nombre "US" para nombrar el sensor ultrasonido, el primer pin es la conexión del Trigger y el segundo es el Echo TextLCD LCD(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // La conexión de los pines para la configuración de la pantalla LCD es de la siguiente manera, RS, E, D4-D7 QEI encoder (PTD7, PTD6, NC, 1); // Define los pines de entrada de un encoder de cuadratura, la conexión dependerá del sentido del encoder DebouncedIn Pulsador(PTA17); // Se define la función DebouncedIn dependiendo de la cantidad de botones que se tengan PwmOut PWM(PTD4); // Se define la salida PWM para el control del ESC (Electronic Speed controller) // DEFINICIÓN DE VARIABLES DebouncedIn Biz(PTC0); // Lectura con la libreria antirebote de los botones de mando DebouncedIn Bar(PTC3); DebouncedIn Bce(PTC4); DebouncedIn Bab(PTC5); DebouncedIn Bde(PTC6); DebouncedIn Bre(PTC7); float DtyOp1=5, DtyOp2=5, DtyMax=8.6, DtyMaxStd=8, DtyMin=5, CstPIDMin=0, CstPIDMax=5; float SPMin=15,SPMax=34,KpMin=0,KpMax=10,KiMin=0,KiMax=10,KdMin=0,KdMax=10; float SP=24.4,Kp=0.01,Ki=0.001,Kd=0,ValPID=0; float Alt,Error=0,ErrorAnt=0,DeltaP=0,DeltaI=0,DeltaD=0,AcPID=0; int DelayPID=100; int Modo=1,Psc=1,ModoPID=1,PscPID=1,ModoS=1; // La variable Psc define la posición numérica para el cambio del digito del DtyOp1 en el modo de operación 1. // DEFINICIÓN DE FUNCIONES // Esta función satura el valor de las constantes de tipo float entre los valores Vmax y Vmin float SaturF(float Val, float Min, float Max){ if(Val>Max)Val=Max; if(Val<Min)Val=Min; return Val; } // Esta función limita el valor de las constantes de tipo float entre los valores Vmax y Vmin float LimVarF(float Val, float Min, float Max){ if(Val>Max)Val=Min; if(Val<Min)Val=Max; return Val; } // Esta función limita el valor de las constantes de tipo int entre los valores Vmax y Vmin int LimVarI(int Val, int Min, int Max){ if(Val>Max)Val=Min; if(Val<Min)Val=Max; return Val; } // DEFINICIÓN DE C0MANDOS PARA LCD int DesIz=0x18; // Desplazamiento del cursor hacia la izquierda int DesDe=0x1A; // Desplazamiento del cursor hacia la derecha int W1=0x0C; // Eliminar cursor bajo int C1=0x0F; // Iniciar cursor bajo // INICIO DEL PROGRAMA int main() { LCD.cls(); LCD.locate(0,0); LCD.printf("Control VTOL"); wait(1); LCD.cls(); LCD.locate(0,0); LCD.printf("Seleccione modo: "); LCD.locate(0,1); LCD.printf("1. Lazo abierto"); PWM.period_ms(20); // Definición del periodo de la señal PWM del ESC PWM.write(0.05); // Definición del ciclo de dureza de la señal. while(1) { // Selección del modo de operación ModoOp: if(!Bar){ Modo--; Modo=LimVarI(Modo,1,2); while(!Bar); goto ModoOpc; } if(!Bab){ Modo++; Modo=LimVarI(Modo,1,2); while(!Bab); goto ModoOpc; } if(!Bce){ LCD.cls(); LCD.locate(0,0); if(Modo==1){ LCD.printf("Ciclo de dureza:"); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); //LCD.locate(Psc-1,1); //LCD.writeCommand(C1); Modo=1; while(!Bce); goto ModoOp1; } if(Modo==2){ LCD.printf("Modificar:"); LCD.locate(0,1); LCD.printf("1. Set Point"); Modo=1; while(!Bce); goto MenuPID; } } goto ModoOp; //Estas son las 2 opciones para seleccionar el modo de operación, solo se ejecutarán luego de pulsar Bar o Bab. //Se hace para evitar copiar dentro de cada if el mismo código. ModoOpc: if(Modo==1){ LCD.locate(0,1); LCD.printf("1. Lazo abierto"); } if(Modo==2){ LCD.locate(0,1); LCD.printf("2. Lazo cerrado"); } goto ModoOp; // Modo de operación 1 ModoOp1: if(!Bre){ LCD.cls(); LCD.locate(0,0); LCD.printf("Seleccione modo: "); LCD.locate(0,1); LCD.printf("1. Lazo abierto"); PWM.write(0.05); while(!Bre); goto ModoOp; } if(!Bce){ //LCD.writeCommand(W1); LCD.locate(0,0); LCD.printf(" "); LCD.locate(0,0); if(DtyOp1>5.5)LCD.printf("En operacion"); if(DtyOp1<5.5)LCD.printf("En pausa"); Psc=2; while(!Bce); PWM.write(DtyOp1*0.01); goto OperacionM1; } if(!Bde){ Psc++; Psc=LimVarF(Psc,1,3); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); LCD.locate(Psc-1,1); while(!Bde); } if(!Biz){ Psc--; Psc=LimVarF(Psc,1,3); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); LCD.locate(Psc-1,1); while(!Biz); } if(!Bar){ if(Psc==1){ DtyOp1++; } if(Psc==2){ DtyOp1=DtyOp1+0.1; } if(Psc==3){ DtyOp1=DtyOp1+0.01; } DtyOp1=LimVarF(DtyOp1,DtyMin,DtyMaxStd); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); LCD.locate(Psc-1,1); while(!Bar); } if(!Bab){ if(Psc==1){ DtyOp1--; } if(Psc==2){ DtyOp1=DtyOp1-0.1; } if(Psc==3){ DtyOp1=DtyOp1-0.01; } DtyOp1=LimVarF(DtyOp1,DtyMin,DtyMaxStd); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); LCD.locate(Psc-1,1); while(!Bab); } goto ModoOp1; OperacionM1: Alt=US.read(); PC.printf(" Altura: %.2f ",Alt); PC.printf(" Duty: %.2f \n",DtyOp1); if(!Bde){ Psc++; Psc=LimVarF(Psc,2,3); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); LCD.locate(Psc-1,1); while(!Bde); } if(!Biz){ Psc--; Psc=LimVarF(Psc,2,3); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); LCD.locate(Psc-1,1); while(!Biz); } if(!Bar){ if(Psc==2){ DtyOp1=DtyOp1+0.1; } if(Psc==3){ DtyOp1=DtyOp1+0.01; } DtyOp1=LimVarF(DtyOp1,DtyMin,DtyMax); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); LCD.locate(Psc-1,1); PWM.write(DtyOp1*0.01); while(!Bar); } if(!Bab){ if(Psc==2){ DtyOp1=DtyOp1-0.1; } if(Psc==3){ DtyOp1=DtyOp1-0.01; } DtyOp1=LimVarF(DtyOp1,DtyMin,DtyMax); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); LCD.locate(Psc-1,1); PWM.write(DtyOp1*0.01); while(!Bab); } if(!Bre){ LCD.cls(); LCD.locate(0,0); LCD.printf("Ciclo de dureza:"); LCD.locate(0,1); LCD.printf("%.2f",DtyOp1); if(DtyOp1>7.5){ while(DtyOp1>7.5){ DtyOp1=DtyOp1-DtyOp1*0.01; PWM.write(DtyOp1*0.01); wait_ms(400); } } PWM.write(0.05); while(!Bre); goto ModoOp1; } goto OperacionM1; // Modo de operación 2 MenuPID: if(!Bar){ ModoPID--; ModoPID=LimVarI(ModoPID,1,6); while(!Bar); goto PIDOpc; } if(!Bab){ ModoPID++; ModoPID=LimVarI(ModoPID,1,6); while(!Bab); goto PIDOpc; } if(!Bce){ LCD.cls(); LCD.locate(0,0); if(ModoPID==1){ LCD.printf("1. Set Point"); LCD.locate(0,1); LCD.printf("%.2f",SP); ValPID=SP; CstPIDMin=SPMin; CstPIDMax=SPMax; } if(ModoPID==2){ LCD.printf("2. Proporcional"); LCD.locate(0,1); LCD.printf("%.2f",Kp); ValPID=Kp; CstPIDMin=KpMin; CstPIDMax=KpMax; } if(ModoPID==3){ LCD.printf("3. Integral"); LCD.locate(0,1); LCD.printf("%.2f",Ki); ValPID=Ki; CstPIDMin=KiMin; CstPIDMax=KiMax; } if(ModoPID==4){ LCD.printf("4. Derivativo"); LCD.locate(0,1); LCD.printf("%.2f",Kd); ValPID=Kd; CstPIDMin=KdMin; CstPIDMax=KdMax; } if(ModoPID==5){ LCD.printf("5. Sensor"); LCD.locate(0,1); LCD.printf("1. SRF05"); while(!Bce); goto Sensado; } if(ModoPID==6){ LCD.printf("Iniciando..."); DtyOp2=7; // while(US.read()<SP){ // DtyOp2=DtyOp2+0.2; // PWM.write(DtyOp2*0.01); // wait_ms(1000); // } LCD.cls(); LCD.locate(0,0); if(SP>=10)LCD.printf("Sp=%.1f",SP); if(SP<10)LCD.printf("Sp=%.2f",SP); LCD.locate(8,0); LCD.printf("Kp=%.2f",Kp); LCD.locate(0,1); LCD.printf("Ki=%.2f",Ki); LCD.locate(8,1); LCD.printf("Kd=%.2f",Kd); while(!Bce); goto OperacionM2; } while(!Bce); goto ValPIDOpc; } if(!Bre){ LCD.cls(); LCD.locate(0,0); LCD.printf("Seleccione modo: "); LCD.locate(0,1); LCD.printf("1. Lazo abierto"); while(!Bre); goto ModoOp; } goto MenuPID; //Estas son las 4 opciones para sintonización del PID, solo se ejecutarán luego de pulsar Bar o Bab. //Se hace para evitar copiar dentro de cada if el mismo código. PIDOpc: if(ModoPID==1){ LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("1. Set Point"); } if(ModoPID==2){ LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("2. Proporcional"); } if(ModoPID==3){ LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("3. Integral"); } if(ModoPID==4){ LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("4. Derivativo"); } if(ModoPID==5){ LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("5. Sensado"); } if(ModoPID==6){ LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("Iniciar control"); } goto MenuPID; // Esta programación modifica una variable genérica y luego al sobreescribe sobre la constantes del PID que se haya elegido en MenuPID ValPIDOpc: if(!Bre){ LCD.cls(); LCD.locate(0,0); LCD.printf("Modificar:"); LCD.locate(0,1); if(ModoPID==1)LCD.printf("1. Set Point"); if(ModoPID==2)LCD.printf("2. Proporcional"); if(ModoPID==3)LCD.printf("3. Integral"); if(ModoPID==4)LCD.printf("4. Derivativo"); if(ModoPID==5)LCD.printf("5. Sensor"); while(!Bre); goto MenuPID; } if(!Bce){ LCD.cls(); LCD.locate(0,0); LCD.printf("Modificar:"); LCD.locate(0,1); if(ModoPID==1){ LCD.printf("1. Set Point"); SP=ValPID; } if(ModoPID==2){ LCD.printf("2. Proporcional"); Kp=ValPID; } if(ModoPID==3){ LCD.printf("3. Integral"); Ki=ValPID; } if(ModoPID==4){ LCD.printf("4. Derivativo"); Kd=ValPID; } while(!Bce); goto MenuPID; } if(!Bde){ PscPID++; PscPID=LimVarI(PscPID,1,3); while(!Bde); } if(!Biz){ PscPID--; ValPID=LimVarI(ValPID,1,3); while(!Biz); } if(!Bar){ if(PscPID==1){ ValPID++; } if(PscPID==2){ ValPID=ValPID+0.1; } if(PscPID==3){ ValPID=ValPID+0.01; } ValPID=LimVarF(ValPID,CstPIDMin,CstPIDMax); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",ValPID); LCD.locate(PscPID-1,1); while(!Bar); } if(!Bab){ if(PscPID==1){ ValPID--; } if(PscPID==2){ ValPID=ValPID-0.1; } if(PscPID==3){ ValPID=ValPID-0.01; } ValPID=LimVarF(ValPID,CstPIDMin,CstPIDMax); LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("%.2f",ValPID); LCD.locate(PscPID-1,1); while(!Bab); } goto ValPIDOpc; Sensado: if(!Bar){ ModoS--; ModoS=LimVarI(ModoS,1,2); while(!Bar); goto Sensadoc; } if(!Bab){ ModoS++; ModoS=LimVarI(ModoS,1,2); while(!Bab); goto Sensadoc; } if(!Bce){ LCD.cls(); LCD.locate(0,0); LCD.printf("Modificar:"); LCD.locate(0,1); LCD.printf("1. Set Point"); Modo=1; while(!Bce); goto MenuPID; } goto Sensado; //Estas son las 2 opciones para seleccionar el ModoS de operación, solo se ejecutarán luego de pulsar Bar o Bab. //Se hace para evitar copiar dentro de cada if el mismo código. Sensadoc: if(ModoS==1){ LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("1. SRF05"); } if(ModoS==2){ LCD.locate(0,1); LCD.printf(" "); LCD.locate(0,1); LCD.printf("2. MPU6050"); } goto Sensado; OperacionM2: Alt=US.read(); PC.printf(" Altura: %.2f ",Alt); PC.printf(" Duty: %.2f \n",AcPID); LCD.cls(); LCD.locate(0,0); LCD.printf("%.2f",Alt); Error=SP-Alt; LCD.locate(8,0); LCD.printf("%.2f",Error); DeltaP=Kp*Error; DeltaI=DeltaI+Ki*Error; DeltaD=Kd*(Error-ErrorAnt); AcPID=(DeltaP+DeltaI+DeltaD)*0.05+DtyMaxStd; ErrorAnt=Error; LCD.locate(8,1); LCD.printf("%.2f",AcPID); AcPID=SaturF(AcPID,DtyMin,9); LCD.locate(0,1); LCD.printf("%.2f",AcPID); LCD.locate(0,1); LCD.printf("%.2f",DtyMin); PWM.write(AcPID*0.01); wait_ms(DelayPID); if(!Bre){ LCD.cls(); LCD.locate(0,0); LCD.printf("Modificar:"); LCD.locate(0,1); LCD.printf("1. Set Point"); Modo=1; PWM.write(0.05); while(!Bre); goto MenuPID; } goto OperacionM2; } // Corchete del While } // Corchete del main