Skip to content

Boost Converter

This examples demonstrates the Hardware-in-the-Loop simulation of a boost converter circuit designed to operate at a 80 kHz switching frequency.

alt text

alt text

alt text

Modeling

The following circuit is modeled using this tutorial: FPGA-based Real-time Simulation of a Boost Converter

Boost Converter Schematic

The end result is a Vivado IP block (boost_ip) that is ready to be integrated into a Vivado project.

FPGA Block Diagram

Image title Image title

A multiplexer selects the switch gate signal from an internal 0 kHz PWM generator, a digital input pin and static values. The gate input, output voltage and output current are connected to the Data Acquisition System (DAQ) and the Analog Output IPs.

AXI GPIO IP blocks are used as a simple way to implement configuration registers to tune the model from the jupyter notebook.

Hardware Setup

Outputs A0 (inductor current), A1 (PWM input readback) and A3 (capacitor voltage) are connected to an oscilloscope. The A2 port outputs the same signal as A3 and will be used in the closed loop control.

alt text alt text

alt text

Jupyter Notebook

The supplied Jupyter notebook is used to configure and interract with the model. It can be used to configure IO voltage levels, chose between internal and external gate signals and capture data through the DAQ.

IO Configuration
from noa import NoaOverlay
import noa
from pynq import PL

import logging
logging.basicConfig(level=logging.INFO)

# Work around overlay cache bug
PL.reset()

ol = NoaOverlay("bitstreams/boost_converter.bit", ip_names={'iic': 'mod_iic_0',  'daq_dma': 'daq_dma_0'})
from noa import Scale, Digital0, Direction, Voltage

# 0 to 3.3V outputs
ol.A0.setup(Scale.PLUS_MINUS_5V0, user_gain=3.3/10, user_offset=1.65)
ol.A1.setup(Scale.PLUS_MINUS_5V0, user_gain=3.3/10, user_offset=1.65)
ol.A2.setup(Scale.PLUS_MINUS_5V0, user_gain=3.3/10, user_offset=1.65)
ol.A3.setup(Scale.PLUS_MINUS_5V0, user_gain=3.3/10, user_offset=1.65)
ol.enable_analog_outputs()

ol.setup_digital_module(Digital0, direction=Direction.INPUT, voltage=Voltage.D3V3)
Model Configuration (Internal PWM)
from enum import IntEnum

class PwmSel(IntEnum):
    One = 1
    Zero = 0
    Internal = 2
    External = 3


def set_duty_cycle(d):
    fsim = 40e6
    fpwm = 80e3

    total_counts = fsim / fpwm
    duty_counts = round(total_counts * d)
    ol.axi_gpio_0.channel1.write(duty_counts, -1)

def set_vin(v):
    norm = round(v * (1<<22) / 100)
    ol.axi_gpio_0.channel2.write(norm, -1)

def set_pwm(sel: PwmSel):
    ol.pwm_sel.channel1.write(sel, -1)
set_pwm(PwmSel.Internal)
set_duty_cycle(0.5)
set_vin(100)
Data Acquisition
from noa import TriggerKind
import time

ol.daq_0.setup_data(window_size=10000, decimation=0, delay=1, dtype=np.int32)
ol.daq_0.trigger(TriggerKind.Immediate, threshold=10, hysteresis=0)
data = ol.daq_0.read()
from matplotlib import pyplot as plt
import numpy as np

fig, axs = plt.subplots(3, 1, figsize=(8, 6), sharex=True)

a = 0
b = len(data[0])

axs[0].plot(data[3][a:b], label="pwm")
axs[0].legend(loc="upper right")

axs[1].plot(data[0][a:b] * (4.0 / (1 << 22)), label="iL")
axs[1].legend(loc="upper right")
axs[1].set_ylabel("iL [A]")

axs[2].plot(data[1][a:b] * (100.0 / (1 << 22)), label="vC")
axs[2].legend(loc="upper right")
axs[2].set_ylabel("vC [V]")

plt.tight_layout()
plt.show()

alt text

Closed Loop Control (STM32)

The provided STM32CubeIDE project targets the Nucleo G47RE developpment board connected to the arch 1 through the Nucleo Interface Board. An SMA cable connects the A2 analog output (capacitor voltage) to the IN4 pin of the interface board. Using the Jupyter notebook, the model is configured to use the external gate input, which corresponds to the STM32's hrtim1_cha1 pin.

Model Configuration (External PWM)
set_pwm(PwmSel.External)

alt text

The microcontroller implements a simple PI controller that runs once for every period of its 80 kHz PWM output. Its target output voltage and PI coefficients can be set through a prompt on its VCP serial interface.

VCP
Noa PI Controller. Run 'help' to list commands.
>>get Kp
Kp = 0.4593
>>get Vout
Vout = 175.00
>>get Ki
Ki = 1.8566999
>>set Ki 1
Ki= 1.00