Inverter mode open loop - owntech-foundation/Tutorials GitHub Wiki
Objective
The goal of this tutorial is to build the base open-loop block of an DC-AC conversion.
This figure shows how the inverter is set from the TWIST board.
This figure shows the bi-polar modulation used in this example
Required hardware
- TWIST
v_1_1_2
or later - PC 64-bits (windows or linux)
- DC power supply (48 V, 2 A)
- Resistive load
- Oscilloscope or multimeter
Required software
- Git
- Visual Studio Code with PlatformIO (see Blinky tutorial)
- OwnPlot (see SerialPlot tutorial)
Create the project
-
We save our progress by committing our work.
-
In the side menu, click on the Source Control button, which will open a new menu.
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.
- Click on the
+
button on the right side of themain.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 for the
buck-3
tutorial
Step-by-step implementation
- Define the variables
In src/main.cpp
, in the section USER VARIABLE DECLARATIONS
, add the direction variable below. It will be used to create the sine wave.
//--------------USER VARIABLES DECLARATIONS----------------------
static int8_t direction=1; //stores the direction of the waveform
- Configure the hardware peripherals
In src/main.cpp
, in the setup_hardware()
function, paste the code below. It initializes the inverter mode by setting a full bridge buck. In this example, the legs will be complementary, to set the bipolar modulation. This is done with the function hwConfig.initFullBridgeBuckMode()
.
void setup_hardware(){
hwConfig.setBoardVersion(TWIST_v_1_1_2);
hwConfig.initFullBridgeBuckModeCenterAligned(bipolar);
hwConfig.setNgndOff();
dataAcquisition.enableTwistDefaultChannels();
console_init();
}
- Configure the software scheduling
In src/main.cpp
, in the function setup_software()
, initialize all the scheduling functions. The data acquisition will be started here. This function also starts the control task along with the communication and application tasks.
Due to its time criticity, the control task has a precise period and with a higher priority over 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();
}
- Loop communication task
In the communication task you will change the commands to update the duty cycle
. You will also add a new mode to it, the INVERTERMODE
.
Find the enum serial_interface_menu_mode
. Add the following code to declare a new mode called INVERTERMODE.
enum serial_interface_menu_mode //LIST OF POSSIBLE MODES FOR THE OWNTECH CONVERTER
{
IDLEMODE =0,
SERIALMODE,
POWERMODE,
INVERTERMODE
};
In src/main.cpp
, in the function loop_communication_task()
, add the following code. This code listens to the Serial port. Depending on the character it has received, it switches between IDLEMODE, POWERMODE and INVERTERMODE.
In INVERTERMODE, it implements a gradual step change to the duty cycle that creates a triangular waveform.
void loop_communication_task()
{
received_serial_char = console_getchar();
switch (received_serial_char) {
case 'h':
//----------SERIAL INTERFACE MENU-----------------------
printk(" ________________________________________\n");
printk("| Communication task Tutorial |\n");
printk("| ------- MENU --------- |\n");
printk("| press i : idle mode |\n");
printk("| press s : serial mode |\n");
printk("| press p : power mode on |\n");
printk("| press u : duty cycle up by 0.01 |\n");
printk("| press d : duty cycle down by 0.01 |\n");
printk("| press v : inverter mode on |\n");
printk("|________________________________________|\n\n");
//------------------------------------------------------
break;
case 'i':
printk("idle mode\n");
mode = IDLEMODE;
break;
case 's':
printk("serial mode on!\n");
mode = SERIALMODE;
break;
case 'p':
printk("power mode on!\n");
mode = POWERMODE;
pwm_enable = true;
break;
case 'u':
printk("Duty Cycle UP: %f\n", duty_cycle);
duty_cycle = duty_cycle + duty_cycle_step;
break;
case 'd':
printk("Duty Cycle DOWN: %f\n", duty_cycle);
duty_cycle = duty_cycle - duty_cycle_step;
break;
case 'v':
printk("inverter mode on!");
mode = INVERTERMODE;
break;
default:
break;
}
}
- Loop application task
This application task will print all the variables of the system.
In src/main.cpp
, in the function loop_application_task()
, add the following code. The IDLEMODE
stops the power flow and turns the LED1 off. The POWERMODE
turns the LED1 is ON and activates the manual duty cycle mode. The INVERTERMODE
turns on the inverter mode with a fixed frequency and toggles the LED.
void loop_application_task()
{
if(mode==IDLEMODE) {
hwConfig.setLedOff();
}else if(mode==POWERMODE) {
hwConfig.setLedOn();
}else if(mode==INVERTERMODE) {
hwConfig.setLedToggle();
}
printk("%f:", duty_cycle);
printk("%f:", Vhigh_value);
printk("%f:", V1_low_value);
printk("%f:", V2_low_value);
printk("%f:", ihigh_value);
printk("%f:", i1_low_value);
printk("%f\n", i2_low_value);
scheduling.suspendCurrentTaskMs(100);
}
- Loop control task
The control task will have the purpose of turning the power conversion on or off and sending the duty cycle to the power block.
In src/main.cpp
, in the function loop_control_task()
, add the following code. It states that if the IDLEMODE
is on, the power conversion stops. If POWERMODE
is on, then the power conversion resumes, the duty cycle can be set by hand and is sent to power hardware. If INVERTERMODE
is on, the power converter will output a sine wave form with a fixed frequency.
void loop_control_task()
{
meas_data = dataAcquisition.getLatest(V_HIGH);
if(meas_data!=NO_VALUE) Vhigh_value = meas_data;
meas_data = dataAcquisition.getLatest(V1_LOW);
if(meas_data!=NO_VALUE) V1_low_value = meas_data;
meas_data = dataAcquisition.getLatest(V2_LOW);
if(meas_data!=NO_VALUE) V2_low_value= meas_data;
meas_data = dataAcquisition.getLatest(I_HIGH);
if(meas_data!=NO_VALUE) ihigh_value = meas_data;
meas_data = dataAcquisition.getLatest(I1_LOW);
if(meas_data!=NO_VALUE) i1_low_value = meas_data;
meas_data = dataAcquisition.getLatest(I2_LOW);
if(meas_data!=NO_VALUE) i2_low_value = meas_data;
if(mode==IDLEMODE) {
pwm_enable = false;
hwConfig.setFullBridgeBuckOff();
}else if(mode==POWERMODE || mode==INVERTERMODE) {
if(!pwm_enable) {
pwm_enable = true;
hwConfig.setFullBridgeBuckOn();
}
if(mode==INVERTERMODE){
if(direction < 0 && duty_cycle < 0.1) direction = 1;
if(direction > 0 && duty_cycle > 0.9) direction = -1;
duty_cycle = duty_cycle + direction*duty_cycle_step;
}
hwConfig.setFullBridgeBuckDutyCycle(duty_cycle);
}
}
- Connect hardware
Now we will connect your TWIST board to the power supply and to the PC via the STLink.
- Connect the pins Vhigh and GND of the TWIST to the DC power supply (set its current limitation at 1 A).
- Connect the pins VLow1, Vlow2 and GND of the TWIST to a resistive load.
- Connect the micro-JTAG connector of the SPIN to the PC thanks to the STLinkV3.
- Switch ON the DC power supply. Choose a voltage between 0 and 48 V.
-
Build and Upload (+ ).
-
In the bottom toolbar, click on the Serial Monitor icon . Select it and press the
h
key. Press thep
button, you should see some data show on the terminal:
Expected outputs
- Press the
i
key to switch to IDLEMODE: disables the power flow, stops printingduty_cycle
and turns the LED1 OFF. - Press the
p
key to switch to POWERMODE: enables the power flow, printduty_cycle
and turns the LED1 ON. - Press the
u
key to increase theduty_cycle
. - Press the
d
key to decrease theduty_cycle
. - Press the
v
key to switch to INVERTERMODE: enables the sine wave form
You can measure the output voltage thanks to an oscilloscope or a multimeter.
OwnPlot Visualization
- First kill the Serial Monitor by clicking on the trash button on the right hand side of the window as shown in the image below.
- Launch OwnPlot. In Port tab, choose the STLinkV3. Click on the
Closed
button to open the port.
:warning: The Port might have a different name depending on your operating system.
- In OwnPlot, Settings tab, set the
# of channels
to 7.
- In OwnPlot, in the Chart tab, change the same of the datasets as shown below:
- In OwnPlot, in the Send tab, add the commands below by typing the command name and its associated character.
- When you click on the
Inverter
button the converter will output a sine wave form.
- In OwnPlot, click on the
Idle
button corresponding to thei
command to switch to IDLEMODE and turn the LED1 OFF.
That’s it!
To go a little further
- How would you change the frequency of the triangular waveform?
- How would you create a sinusoidal waveform?
- How can you create a square waveform?
- How can you set the offset and the gain?
- How can you close the loop and drive the single phase AC?
That’s it!
Contributors
- 2021.11.04: Romain Delpoux, Loic Queval, Adrien Prévost
- 2021.11.07: Luiz Villa, Antoine Boche
- 2022.01.24: Luiz Villa, Loic Queval
- 2022.02.01: Luiz Villa
- 2022.03.13: Luiz Villa
- 2022.04.19: Luiz Villa
- 2022.06.23: Luiz Villa, Olivier Chevilley