Buck 1 Open loop PWM - owntech-foundation/Tutorials GitHub Wiki

Objective

The goal of this tutorial is to use the O2 as a buck converter in open-loop. We will control the duty cycle via the keyboard.

image

Converter on Buck mode: in red are the currents and the black arrows are the voltages

We will start from the Serial Plot tutorial.

Required hardware

  • O2 v_1_1_2
  • STLinkV3
  • PC 64-bits (windows or linux)
  • DC power supply (48 V, 2 A)
  • Oscilloscope or multimeter

Required software

  • Git
  • Visual Studio Code with PlatformIO (see Blinky tutorial)
  • SerialPlot (see SerialPlot tutorial)

Create the project

  1. We save our progress by committing our work. In the side menu, click on the Source Control button, Which will open a new menu source_control_button. You can see that the only changes on your code are located at the main.cpp file. We are going to commit these changes as to keep track of our progress.

  2. Click on the + button on the right side of the main.cpp file to "stage" the changes. You can add a comment to explain what these changes are useful for. It is good practice to describe your changes when you commit them in git. Click on the + Commit button. Your work has now been committed. We can come back to it later if necessary.

staged_changes_ownplot_tutorial

Step-by-step implementation

  1. Define the variables

In src/main.cpp, in the section USER VARIABLE DECLARATIONS, add the variables below. The initial duty cycle is 0.5. The duty cycle steps are set to 0.05. A boolean indicates the state of the PWM (ON or OFF). A variable will also define the period of the control task.

//--------------USER VARIABLES DECLARATIONS----------------------

static float32_t duty_cycle = 0.5; //[-] duty cycle (comm task)
static float32_t duty_cycle_step = 0.05; //[-] duty cycle step (comm task)
static bool pwm_enable = false; //[bool] state of the PWM (ctrl task)
static uint32_t control_task_period = 50; //[us] period of the control task
  1. Configure the hardware peripherals

In src/main.cpp, in the setup_hardware() function, paste the code below. It initializes the buck mode. The O2 converter has two legs which can be operated independently or interleaved. In this example, the legs will be interleaved, which means both will share the total current flowing through the power converter. Both legs are set to work on buck mode. This is done with the function hwConfig.initInterleavedBuckMode().

void setup_hardware(){
    hwConfig.setBoardVersion(O2_v_1_1_2); 
    hwConfig.initInterleavedBuckMode();  
    console_init();
}
  1. Configure the software scheduling

In src/main.cpp, in the function setup_software(), paste the code below. It starts the control task, the communication task and the application task. Due to its time criticity, the control task has a precise period and not a priority as the others.

void setup_software()
{
    application_task_number =  scheduling.defineAsynchronousTask(loop_application_task);
    communication_task_number = scheduling.defineAsynchronousTask(loop_communication_task);
    scheduling.defineUninterruptibleSynchronousTask(&loop_control_task, control_task_period);

    scheduling.startAsynchronousTask(application_task_number);
    scheduling.startAsynchronousTask(communication_task_number);
    scheduling.startUninterruptibleSynchronousTask();

}
  1. Loop communication task

In the communication task, in comparison to the SerialPlot tutorial, we change the commands to update the duty cycle instead of the counter variable. We also add a new mode, called POWERMODE.

In src/main.cpp, in the list enum serial_interface_menu_mode, declare a new mode called POWERMODE.

enum serial_interface_menu_mode //LIST OF POSSIBLE MODES FOR THE OWNTECH CONVERTER
{
    IDLEMODE =0,
    SERIALMODE,
    POWERMODE
};

In src/main.cpp, in the function loop_communication_task(), paste the following code. This code listens to the serial port. Depending on the character it has received, it switches between IDLEMODE, SERIAL and POWERMODE. In POWERMODE, the PWM is enabled thus activating the power conversion.

void loop_communication_task()
{
    received_serial_char = console_getchar();
    switch (received_serial_char) {
        case 'h':
            //----------SERIAL INTERFACE MENU-----------------------
	        printk(" ________________________________________\n");
            printk("|     ------- MENU ---------             |\n");
            printk("|     press i : idle mode                |\n");
            printk("|     press s : serial mode              |\n");
            printk("|     press p : power mode               |\n");
            printk("|     press u : duty cycle UP            |\n");
            printk("|     press d : duty cycle DOWN          |\n");
            printk("|________________________________________|\n\n");
            //------------------------------------------------------

            break;
        case 'i':
            printk("idle mode\n");
            mode = IDLEMODE;
            break;
        case 's':
            printk("serial mode\n");
            mode = SERIALMODE;
            break;
        case 'p':
            printk("power mode\n");
            mode = POWERMODE;
            break;
        case 'u':
            printk("duty cycle UP: %f\n", duty_cycle);
            duty_cycle = duty_cycle + duty_cycle_step;
            if(duty_cycle>1.0) duty_cycle = 1.0;
            break;
        case 'd':
            printk("duty cycle DOWN: %f\n", duty_cycle);
            duty_cycle = duty_cycle - duty_cycle_step;
            if(duty_cycle<0.0) duty_cycle = 0.0;
            break;
        default:
            break;
    }
}
  1. Loop application task

The application task will print the value of duty cycle.

In src/main.cpp, in the function loop_application_task(), paste the following code. The IDLEMODE stops the power flow, the transmission of data and turns the LED1 off. The SERIALMODE only turns on the LED1. The POWERMODE turns the LED1 is ON and prints the values of duty_cycle on the Serial Monitor.

void loop_application_task()
{
    if(mode==IDLEMODE) {
        hwConfig.setLedOff();
    }else if(mode==SERIALMODE || mode==POWERMODE) {
        hwConfig.setLedOn();
        printk("%f \n", duty_cycle);
    }        
    scheduling.suspendCurrentTaskMs(100);    
}
  1. Loop control task

The control task will turn on/off the power conversion and send the duty cycle to the power converter.

In src/main.cpp, in the function loop_control_task(), paste the following code. It states that if either the IDLEMODE or SERIALMODE are on, the power conversion stops. If POWERMODE is on, then the power conversion resumes and the duty cycle is sent to the drivers and to the power hardware.

void loop_control_task()
{
    if(mode==IDLEMODE || mode==SERIALMODE) 
    {
        pwm_enable = false;
        hwConfig.setInterleavedOff();
    }
    else if(mode==POWERMODE) 
    {
        if(!pwm_enable) {
            pwm_enable = true;
            hwConfig.setInterleavedOn();
        }

        //Sends the PWM to the switches
	hwConfig.setInterleavedDutyCycle(duty_cycle);
    }
}
  1. Connect hardware

Now we will connect OwnTech’s O2 to the power supply and to the PC.

  • :warning: Make sure that the jumper JP4 is open.
  • Connect the USB power supply cable. The LED2 of the O2 should be ON.
  • Connect the pins Vhigh and GND of the O2 to the DC power supply (set its current limitation at 1 A).
  • Connect the micro-JTAG connector of the O2 to the PC thanks to the STLinkV3.
  • Switch ON the DC power supply. Choose a voltage between 0 and 48 V.

image

  1. Build and Upload (build_icon+ flash_icon).

  2. In the bottom toolbar, click on the Serial Monitor icon serial_icon. Select it and press the h key. Press the p key, you should see the current value of duty cycle on the Serial Monitor. Remember to click on the open button in SerialPlot to liberate the serial interface.

Expected outputs

  • Press the i key to switch to IDLEMODE: disables the power conversion, stops printing duty_cycle and turns the LED1 OFF.
  • Press the s key to switch to SERIALMODE: disables the power conversion, prints the duty_cycle and turns the LED1 ON.
  • Press the p key to switch to POWERMODE: enables the power conversion, prints duty_cycle and turns the LED1 ON.
  • Press the u key to increase the duty_cycle.
  • Press the d key to decrease the duty_cycle.

buck1_serial

You can measure the DC output voltage thanks to an oscilloscope or a multimeter.

That’s it!

Contributors

  • 2021.11.04: Romain Delpoux, Loïc Quéval, Adrien Prévost
  • 2021.11.07: Luiz Villa, Antoine Boche
  • 2022.01.24: Luiz Villa, Loïc Quéval
  • 2022.02.01: Luiz Villa
  • 2022.03.13: Luiz Villa
  • 2022.06.23: Loïc Quéval