Documentación técnica para la implementación de un convertidor DC-DC Buck (Step-down) utilizando control digital PID en lazo cerrado. El sistema migra de una simulación HIL (Hardware-in-the-Loop) en MATLAB a una ejecución standalone en microcontrolador AVR (Arduino).
1. Lista de Materiales, Bill of Materials (BOM)
| Componente | Especificación Crítica | Función |
|---|---|---|
| MCU | ATmega328p (Nano/Uno) | Controlador Digital (PID Discreto) |
| MOSFET | IRFZ44N / IRF540 | Conmutación de Potencia |
| Gate Driver | IR2110 / TC4420 | Interfaz TTL 5V a Gate 12V. Esencial para f > 20kHz. |
| Inductor | 100 µH (Núcleo Ferrita) | Isat > 2.5A. Evitar bobinas de señal SMD. |
| Capacitor | 33 µF (Low ESR) | Filtrado de rizado de salida. |
El algoritmo PID utiliza una referencia interna de 2.5V. Para obtener 5V en la salida, es obligatorio implementar un divisor de tensión 2:1 (Resistencias 10kΩ/10kΩ) en el pin de lectura (A0).
2. Migración: Simulación vs. Hardware Real
El código base original estaba diseñado como «esclavo» de Simulink. Para el despliegue físico, se modificó la arquitectura de software para eliminar la dependencia del puerto Serial y activar la lectura ADC directa.
Versión A: Simulación (HIL)
El Arduino espera datos de MATLAB para actuar. No funciona solo.
DVout = recepcion(); // Lee valor virtual
u = PID(DVout);
Serial.write(u); // Devuelve dato a PC
}
Versión B: Standalone (Real)
Operación autónoma con lectura de sensores y Anti-Windup activo.
y = analogRead(A0) * (5.0/1023.0);
u = PID(y);
// Actúa sobre el MOSFET
pwmWrite(9, u * 255);
3. Firmware Implementado (C++)
Código fuente optimizado para despliegue en campo. Se corrigió el error de saturación integral (Windup) que causaba inestabilidad en la versión de simulación.
// Firmware Control Buck PID - v1.0 Release #include <pwm.h> const int PIN_SENSOR = A0; // Entrada Divisor (Vout/2) const int PIN_PWM = 9; // Salida Gate Driver // Constantes PID (L=100uH, C=33uF) float Kp = 0.272253; float Ti = 0.0015285; float Ts = 20e-6; // 50kHz Loop // Variables PID float u = 0.0, u_1 = 0.0; float e = 0.0, e_1 = 0.0; float q0, q1; float Vref = 2.5; // Target (2.5V leídos = 5.0V reales) void setup() { // Coeficientes Tustin q0 = Kp * (1 + (Ts / (2 * Ti))); q1 = -Kp * (1 - (Ts / (2 * Ti))); // Configurar PWM Asíncrono InitTimersSafe(); SetPinFrequencySafe(PIN_PWM, 50000); pinMode(PIN_PWM, OUTPUT); } void loop() { // 1. Lectura ADC y Normalización float y_medida = analogRead(PIN_SENSOR) * (5.0 / 1023.0); // 2. PID Discreto e = Vref - y_medida; u = u_1 + q0 * e + q1 * e_1; // 3. Saturación y Anti-Windup (Crítico) if (u > 0.95) u = 0.95; if (u < 0.00) u = 0.00; // 4. Actualización Estados u_1 = u; e_1 = e; // 5. Actuación pwmWrite(PIN_PWM, (int)(u * 255)); // Estabilización de Ciclo delayMicroseconds(10); }






