// t: Time, passed from PSIM by value // delt: Time step, passed from PSIM by value // in: input array, passed from PSIM by reference // out: output array, sent back to PSIM (Note: the values of out[*] can // be modified in PSIM) // The maximum length of the input and output array "in" and "out" is 30. // Las entradas del sistema son // in[0]= Ref; Referencia, posición angular en radianes // in[1]= y(t); Variable a controlar, Posición angular // in[2]= fs; Frecuencia de muestreo, fm en Hz #include "dll.h" #include // Coeficientes del controlador Deadbeat: #define p1 0.5515 #define p2 0.4420 #define p3 0.0065 #define q0 0.2751 #define q1 -0.3003 #define q2 0.0252 #define q3 -0.000018635 // Aqui se implementa una estrategia de control deadbeat para el control // de posición angular de un motor de CC. La fm = 2,5 Hz y Tm = 0,4 seg. void __declspec(dllexport) simuser (double t, double delt, double *in, double *out) { static double y=0; // Variable controlada static double ref; static double ek = 0; // Error actual. static double ekm1 = 0; // Error anterior. static double ekm2 = 0; static double ekm3 = 0; static double uk = 0; // Acc. de control actual. static double ukm1 = 0; // Acc. de control anterior. static double ukm2 = 0; // Acc. de control anterior. static double ukm3 = 0; // Acc. de control anterior. static double Tm; // Periodo de muestreo static double muestra=0; static double update=0; Tm = 1/in[2]; // Variables enteras static int contador=0, Ncont, calculo_u, muestreo, direccion = 1; // Se calcula el numero de conteos en un periodo: Valor máximo del contador Ncont=Tm/delt; muestra = 0; update = 0; if (calculo_u==1) { calculo_u=0; ref = in[0]; /*********************************************************************************/ /* Se calcula el error de posición */ /*********************************************************************************/ ek = ref - y; /*********************************************************************************/ /* Calculo del controlador deadbeat */ /*********************************************************************************/ // u(k)=p1*u(k-1) + p2*u(k-2) + p3*u(k-3) + q0*e(k) + q1*e(k-1) + q2*e(k-2) + q3*e(k-3); uk = p1*ukm1 + p2*ukm2 + p3*ukm3 + q0*ek + q1*ekm1 + q2*ekm2 + q3*ekm3; // Almacena variables anteriores para el proximo periodo. ukm3 = ukm2; ukm2 = ukm1; ukm1 = uk; ekm3 = ekm2; ekm2 = ekm1; ekm1 = ek; //Para lazo abierto //uk = ref; out[0] = uk; update = 1; out[6] = update; } //termina el calculo de la estrategia de control //**********************************************************// // Incrementamos o decrementamos el contador segun corresponda contador = contador + direccion; if (contador < 0) { direccion=1; muestreo=0; muestra=0; update=0; } if (contador == Ncont/2) { direccion=-1; muestreo=1; muestra=1; update=0; } if(muestreo==1) { muestreo=0; // Se realiza el muestreo de la variable controlada y = in[1]; // Se activa el flag de la rutina de interrupción de control calculo_u=1; } // Se envían variables internas a las salidas out[1] = ref; out[2] = y; out[3] = ek; out[4] = muestra*1000; out[5] = contador; } BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { switch(fdwReason) { case DLL_PROCESS_ATTACH: { break; } case DLL_PROCESS_DETACH: { break; } case DLL_THREAD_ATTACH: { break; } case DLL_THREAD_DETACH: { break; } } /* Return TRUE on success, FALSE on failure */ return TRUE; }