Estoy haciendo una fuente de corriente para cargar baterías, basado en un regulador Buck, y controlado con un PIC con un PID digital.
El esquema es el siguiente:
La frecuencia del PWM del PIC es de 31KHz, con 10 bit de resolución. El problema que tengo, que no regula bien la corriente, si pongo en corto la salida (con R11=1ohm y R8=6k8) regula a una corriente de 1A, si coloco una lampara de 12v y 21w, regula a 0.5A, y si pongo una lampara de 12v y 5w, regula a 0.2A, la consigna la tengo puesta para que regule a 310mA.
Pienso que el problema viene por el sensado de corriente, pues si lo configuro para que funcione como un regulador de voltaje a 7v (levanto R7 del operacional y lo conecto a través de un divisor de voltaje en la salida) ese valor se mantiene constante con diferentes cargas.
Para el código del pic me baso en la an258 de microchip:
https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en012103Y el código que uso es el siguiente:
unsigned int outPID, currSENS, currAJUSTE;
signed short long Ik_old, ek_old;
/*
Main application
*/
void main(void) {
// initialize the device
SYSTEM_Initialize();
EPWM1_Initialize();
Ik_old = Ki;
ek_old = 0;
while (1) {
IO_RB5_Toggle();
currAJUSTE = 500;
currSENS = ADC_GetConversion(10);//Leo corriente con el ADC
outPID = salidaControlPID(currSENS, currAJUSTE, & Ik_old, & ek_old);
EPWM1_LoadDutyValue(outPID);//Actualizo PWM
}
}
Y la función del PID:
#include <xc.h>
#include "pid.h"
#define Kp 100
#define Ki 10
#define Kd 5
unsigned int salidaControlPID(unsigned int ADC, unsigned int Consigna, signed short long * Ik_old, signed short long * ek_old){
signed short long CV;//Control variable, valor del pwm.
signed short long Pk, Ik, Dk;
signed short long eK;//Salida comparador de error
signed short long SP;//Set Point o consigna
signed short long PVk;//Present Variable, es la lectura del ADC
SP = (signed short long)Consigna;
PVk = (signed short long)ADC;
eK = SP - PVk;//Calculo del error.
Pk = Kp * eK;//Calculo de la parte proporcional.
Ik = *(Ik_old) + Ki*eK;//Calculo de la parte integral. Ik_old es el estado anterior de Ik.
*(Ik_old) = Ik;//Salvamos la parte integral.
Dk = Kd * (*(ek_old) - eK);//Calculo de la parte derivativa.
*(ek_old) = eK;//Salvamos el error.
CV = (Pk + Ik + Dk);
if(CV > 1023)
CV = 1023;
if(CV < 0)
CV = 0;
return (unsigned int)CV;
}
Variando las constantes Kp, Ki y Kd no veo diferencia en cuanto a que la corriente se mantenga en el valor deseado (310mA), por lo que pienso que es un problema hardware ¿Alguna idea?
Saludos!!!