This program makes a PID control and the values por control action are entered by matrix keypad 4x4 interface.
Dependencies: FPointer TextLCD keypad mbed
main.cpp
00001 //Programa para hacer control PID simple, ingresa parámetros con teclado 4x4. Imprime resultados en LCD 16x2 00002 00003 #include "mbed.h" 00004 #include "TextLCD.h" 00005 #include"keypad.h" //Librería del teclado 4x4 00006 #include"FPointer.h" //Librería complementaria para libreria keypad 00007 00008 TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7 00009 Keypad keypad(PTA2,PTD4,PTD3,PTD7,PTA13,PTD5,PTD0,PTD2); //Entradas del teclado 00010 00011 AnalogIn Vin(PTB0); //Voltaje de alimentación 00012 AnalogOut Vout(PTE30); //Marcar la salida analógica 00013 00014 //ASIGNACION DE VARIABLES 00015 Timer t; 00016 int cero; 00017 int flag; 00018 int q; 00019 int k; 00020 int C1=0x0E; //configurar el lcd para mostrar el guin bajo 00021 int C2=0x0C; //configurar el lcd para QUITAR el guion bajo 00022 float sp=0; //set point 00023 float kp=0; //ganancia proporcional 00024 float ki=0; //ganancia integral 00025 float kd=0; //ganancia derivativa 00026 int ind=0; //vector de caracteres. 00027 float err, med, yr, ap, ai, ad, err_v, cycle; //Variable de control PID 00028 float pid; 00029 00030 //MATRIZ DEL TECLADO 00031 float Keytable[] = {1,2,3,11, 00032 4,5,6,12, 00033 7,8,9,13, 00034 0,0,0,0}; 00035 00036 //Se crea una función que incremente los valores 00037 void increment(int j){ 00038 if(j==0){ 00039 if (q!=1 && sp<10){ 00040 sp=ind; 00041 q=1; 00042 } 00043 else{ 00044 sp=10*sp+ind; 00045 } 00046 if(sp>999)sp=999; 00047 lcd.locate(3,0); lcd.printf(" "); 00048 lcd.locate(3,0); lcd.printf("%.0f",sp); 00049 00050 } 00051 else if(j==1){ 00052 if (q!=1 && kp<10){ 00053 kp=ind; 00054 q=1; 00055 } 00056 else{ 00057 kp=10*kp+ind; 00058 } 00059 if(kp>999)kp=999; 00060 lcd.locate(11,0); lcd.printf(" "); 00061 lcd.locate(11,0); lcd.printf("%.0f",kp); 00062 } 00063 else if(j==2){ 00064 if (q!=1 && ki<10){ 00065 ki=ind; 00066 q=1; 00067 } 00068 else{ 00069 ki=10*ki+ind; 00070 } 00071 if(ki>999)ki=999; 00072 lcd.locate(3,1); lcd.printf(" "); 00073 lcd.locate(3,1); lcd.printf("%.0f",ki); 00074 } 00075 else{ 00076 if (q!=1 && kd<10){ 00077 kd=ind; 00078 q=1; 00079 } 00080 else{ 00081 kd=10*kd+ind; 00082 } 00083 if(kd>999)kd=999; 00084 lcd.locate(11,1); lcd.printf(" "); 00085 lcd.locate(11,1); lcd.printf("%.0f",kd); 00086 } 00087 ind=0; cero=0; 00088 } 00089 00090 uint32_t cbAfterInput(uint32_t index) { 00091 ind=Keytable[index]; 00092 cero=index; 00093 return 0; 00094 } 00095 00096 void def_posicion(int j){ 00097 if (j==0){ 00098 lcd.locate(3,0); lcd.printf("%.0f",sp); 00099 lcd.locate(3,0); 00100 } 00101 else if(j==1){ 00102 lcd.locate(11,0); lcd.printf("%.0f",kp); 00103 lcd.locate(11,0); 00104 } 00105 else if (j==2){ 00106 lcd.locate(3,1); lcd.printf("%.0f",ki); 00107 lcd.locate(3,1); 00108 } 00109 else { 00110 lcd.locate(11,1); lcd.printf("%.0f",kd); 00111 lcd.locate(11,1); 00112 } 00113 } 00114 00115 //Dado que hay parámetros que no varía en el display en esta parte del código, se crea una función que los mantenga. 00116 void star_patch1(void){ 00117 lcd.cls(); 00118 lcd.locate(8,0); 00119 lcd.printf("Kp=%.0f",kp); 00120 lcd.locate(0,1); 00121 lcd.printf("Ki=%.0f",ki); 00122 lcd.locate(8,1); 00123 lcd.printf("Kd=%.0f",kd); 00124 lcd.writeCommand(C1); //cursor se vea y sea intermitente 00125 lcd.locate(0,0); 00126 lcd.printf("Sp=%.0f",sp); 00127 } 00128 00129 void star_patch2(void){ // uso nuevamente función que imprime los caracteres que no van a variar en el display 00130 lcd.writeCommand(C2); 00131 lcd.cls(); 00132 lcd.printf("Iniciamos el PID |m|"); 00133 wait(2); 00134 lcd.cls(); 00135 lcd.printf("Er%=f",err); 00136 lcd.locate(8,0); lcd.printf("Me=%.0f",med); 00137 lcd.locate(0,1); lcd.printf("Sp=%.0f",sp); 00138 lcd.locate(8,1); lcd.printf("Co=%.0f",pid); 00139 wait(3); 00140 } 00141 00142 int main(){ 00143 ini: 00144 ind=0; 00145 star_patch1(); 00146 keypad.CallAfterInput(&cbAfterInput); 00147 keypad.Start(); 00148 ini1: 00149 if(ind==12){ 00150 if (k<3) k++; 00151 else k=0; 00152 def_posicion(k); 00153 ind=0; 00154 q=0; 00155 } 00156 if(ind==13){ 00157 ind=0; 00158 goto PID; 00159 } 00160 if(ind==11){ 00161 if (k==0){ 00162 sp=0; 00163 lcd.locate(3,0); lcd.printf(" "); 00164 lcd.locate(3,0); lcd.printf("%.0f",sp); 00165 } 00166 else if(k==1){ 00167 kp=0; 00168 lcd.locate(11,0); lcd.printf(" "); 00169 lcd.locate(11,0); lcd.printf("%.0f",kp); 00170 } 00171 else if (k==2){ 00172 ki=0; 00173 lcd.locate(3,1); lcd.printf(" "); 00174 lcd.locate(3,1); lcd.printf("%.0f",ki); 00175 } 00176 else { 00177 kd=0; 00178 lcd.locate(11,1); lcd.printf(" "); 00179 lcd.locate(11,1); lcd.printf("%.0f",kd); 00180 } 00181 q=0; ind=0; 00182 } 00183 if (ind!=0 && ind!=12 && ind!=13 && ind!=11 || cero==13 ){ 00184 increment(k); 00185 } 00186 goto ini1; 00187 00188 PID: 00189 star_patch2(); 00190 00191 while (1){ 00192 00193 med=Vin.read()*1000; 00194 err =sp-med; 00195 ap = kp*err; 00196 ai =(ki*0.001*err)+ai; //calculo de la integral del error 00197 // VERIFICAMOS QUE LA ACCION INTEGRAL NO SEA MUY GRANDE!!! 00198 if(ai>0.5){ 00199 ai=0.5; 00200 } 00201 ad = kd*(err-err_v); //calculo de la accion derivativa 00202 pid =(ap+ai+ad); 00203 00204 //MOSTRAMOS LAS VARIABLES 00205 if (pid > 999)pid=1000; 00206 if (pid<0)pid=0; 00207 00208 00209 Vout.write(pid/1000); 00210 if(flag==0){ 00211 t.start(); 00212 flag=1; 00213 } 00214 if (t>0.3){ 00215 lcd.locate(3,0); 00216 lcd.printf(" "); 00217 lcd.locate(3,0); 00218 lcd.printf("%.0f",err); 00219 lcd.locate(11,0); 00220 lcd.printf(" "); 00221 lcd.locate(11,0); 00222 lcd.printf("%.0f",med); 00223 lcd.locate(3,1); 00224 lcd.printf(" "); 00225 lcd.locate(3,1); 00226 lcd.printf("%.0f",sp); 00227 lcd.locate(11,1); 00228 lcd.printf(" "); 00229 lcd.locate(11,1); 00230 lcd.printf("%.2f ",pid/1000); 00231 t.reset(); 00232 flag=0; 00233 wait(.3); 00234 } 00235 00236 //ACTUALIZACION DE LAS VARIABLES 00237 err_v = err; 00238 if(ind==13)goto ini; 00239 } 00240 }
Generated on Thu Jul 14 2022 21:59:51 by 1.7.2