Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions OWNVERTER/BLDC_hall_sensor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ Here is a detailed explanation of the six sectors and the switching sequence for

The six sectors are determined based on the Hall effect sensor outputs, which change as the rotor rotates. The Hall sensors provide three signals (H1, H2, H3), which can be interpreted as a 3-bit binary code. Each unique combination of these signals corresponds to one of the six sectors.

In code this is done with :
In code, this is done with:

``` hall_state = hall1_value + 2 * hall2_value + 4 * hall3_value; ```

Note that this should be adapted depending on the way phases and hall effect sensors are connected to the inverter. It might be necessary to permute the hall
values to run the motor correctly.

### Controling the motor
### Controlling the motor

In each sequence we supply only two windings using two legs of the ownverter.
Then if for example we supply phase A and B, the associate phase to phase voltage will
In each sequence we supply only two windings using two legs of the OWNVERTER.
Then, for example, if we supply phase A and B, the associated phase-to-phase voltage will
be:

$U_{AB} = (2.\textsf{duty\\\_cycle} - 1). U_{dc}$

In this example duty_cycle can be increased or lowered by pressing `u` and `d` in the serial monitor.
In this example, duty_cycle can be increased or lowered by pressing `u` and `d` in the serial monitor.
It should directly affect motor speed.

### Commutation Sequence
Expand Down
40 changes: 20 additions & 20 deletions OWNVERTER/FOC_hall_sensor/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
# Field Oriented Control with hall Sensors.
# Field Oriented Control with Hall sensors

## Introduction.

This example show how to regulate the torque in a Permanent Magnet Synchonous Machine
This example shows how to regulate the torque in a Permanent Magnet Synchronous Machine
(PMSM) using a Field Oriented Control (FOC) algorithm.

The FOC is well adapted to PMSM with sinusoïdal back-emf (electro
motive forces). The FOC algorithm generate smooth torque value.
The FOC is well adapted to PMSM with sinusoidal back-EMF (electromotive
forces). The FOC algorithm generates smooth torque values.
The current regulators (Proportional-Integral) are in the _"dq"_ frame where values
should be constant during steady state operation.

To apply this technique we should have an acquisition of a continuous angle value [0, 2π[.
But for _"cost"_ reasons or integrations with other algorithms (BLDC), some motor have
But for _"cost"_ reasons or integrations with other algorithms (BLDC), some motors have
only 3 discrete hall sensors value to indicate the rotor position.

In this case we use a PLL (Phased-Lock-Loop) filter to _"build"_ a contiuous equivalent
In this case we use a PLL (phase-locked loop) filter to _"build"_ a continuous equivalent
angle from the 3 discrete signals.

![](Images/foc_hall_scheme.png)

## Import libraries to use it.

This example use some software components which are in the owntech `control_library`.
then you must import it by inserting the following line in the `platformio.ini` file.
This example uses some software components which are in the OwnTech `control_library`.
Then you must import it by inserting the following line in the `platformio.ini` file.

```ini
lib_deps=
Expand All @@ -32,7 +32,7 @@ lib_deps=

## How the _"sector"_ table is built.

According _"dq"_ transformation, the formula of the back emf should be :
According to the _"dq"_ transformation, the formula of the back EMF should be:

$E_{u} = - K_{fem}.\omega .sin(\theta)$

Expand All @@ -44,15 +44,15 @@ Where $\theta$ is the _"electric"_ angle and $\omega$ is the _"electric"_ pulsat

For simplicity reasons we assume that the value $K_{fem}.\omega = 1$.

Then the hall sensors must be synchronised with the hall sensors as the following:
Then the Hall sensors must be synchronized with the back-EMF as follows:

![](Images/bemf_and_hall.png)

According these assumptions, we define a variable `hall_index` which is computed as:

$hall_{index} = Hall_u . 2^0+ Hall_v . 2^1 + Hall_w . 2^2$

We also define a `sector` variable which evolve like a quantification of a continuous
We also define a `sector` variable which evolves like a quantification of a continuous
angle value, then we can make a lookup table between these two variables.

![](Images/sector_and_hall_idx.png)
Expand All @@ -66,24 +66,24 @@ angle value, then we can make a lookup table between these two variables.
| 4 | 5 |
| 5 | 1 |

## Use this example
## Use this example

- Wire the motor hall effect sensors and power phase. The colors of the hall effect sensors should match the color of the power phase.
- Flash the example to the OwnVerter board.
- Wire the motor Hall effect sensors and power phases. The colors of the Hall effect sensors should match the color of the power phases.
- Flash the example to the OWNVERTER board.
- In the serial terminal press `p` to start the motor.
- At that point, there is no torque reference as `Iq_ref` is equal to `0`
- Increase the torque reference by pressing `u`. The torque reference is incremented by `0.1A`
- At that point, there is no torque reference as `Iq_ref` is equal to `0`.
- Increase the torque reference by pressing `u`. The torque reference is incremented by `0.1 A`.
- Increase the torque reference until the motor starts spinning.
- Stop the motor by pressing `i`
- You can retrieve live record by pressing `r`. It will download a data_record containing all declared scope values.
- Stop the motor by pressing `i`.
- You can retrieve a live record by pressing `r`. It will download a data record containing all declared scope values.
- By default the recording is triggered by entering `power mode` (by pressing `p`).
- Alternatively you can press `q` to trigger manually the recording at a different instant, or to reset the trigger
- Plot the values by clicking `Plot recording` in `OwnTech` platformio actions.
- Plot the values by clicking `Plot recording` in `OwnTech` PlatformIO actions.
- Live data records can also be plotted using OwnPlot by pressing `m`. This way, the recording will be sent as an infinite loop to OwnPlot.

| Control state | Comment |
| --- | --- |
| 0 | In this state, the controller is calculating the current offset |
| 1 | In this state, the controller is idle |
| 2 | In this state, the controller is in power mode |
| 3 | In this state, the controller is in error mode. The error mode is entered by repetedely (repedely being defined by `error_counter`) fulfilling the following condition : `I1_Low` going beyond the bounds `[-AC_CURRENT_LIMIT;+AC_CURRENT_LIMIT]`, `I2_Low` going beyond the bounds `[-AC_CURRENT_LIMIT;+AC_CURRENT_LIMIT]` or `I_High` exceding `DC_CURRENT_LIMIT` |
| 3 | In this state, the controller is in error mode. The error mode is entered by repeatedly (as defined by `error_counter`) fulfilling the following condition: `I1_Low` going beyond the bounds `[-AC_CURRENT_LIMIT;+AC_CURRENT_LIMIT]`, `I2_Low` going beyond the bounds `[-AC_CURRENT_LIMIT;+AC_CURRENT_LIMIT]` or `I_High` exceeding `DC_CURRENT_LIMIT` |
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
Welcome to the OwnTech examples repository.

Here you can find ready to be used example for [SPIN](https://github.com/owntech-foundation/SPIN) and [TWIST](https://github.com/owntech-foundation/TWIST).
Here you can find ready-to-use examples for [SPIN](https://github.com/owntech-foundation/SPIN), [TWIST](https://github.com/owntech-foundation/TWIST), and OWNVERTER.

# Examples for TWIST

- DC DC topology examples
- Basic examples
- [Open Loop PWM](TWIST/Basic/Open-Loop_PWM/README.md)

- DC-DC topology examples
- [Buck voltage mode](TWIST/DC_DC/buck_voltage_mode/README.md)
- [Buck current mode](TWIST/DC_DC/buck_current_mode/README.md)
- [Boost voltage mode](TWIST/DC_DC/boost_voltage_mode/README.md)
- [Interleaved Buck](TWIST/DC_DC/interleaved/README.md)
- [Current ripple measure in buck voltage mode](TWIST/DC_DC/current_ripple_measurement/README.md)
- [Independent](TWIST/DC_DC/independent/README.md)
- [Simple scope example](TWIST/DC_DC/scope_simple_example/README.md)
- [Current ripple measurement in buck voltage mode](TWIST/DC_DC/current_ripple_measurement/README.md)

- Microgrid examples
- [AC client server](TWIST/Microgrid/AC_client_server/README.md)
- [AC peer to peer](TWIST/Microgrid/AC_peer_to_peer/README.md)
- [DC client server](TWIST/Microgrid/DC_client_server/README.md)
- [DC droop](TWIST/Microgrid/DC_droop/README.md)

- DC AC topology examples
- DC-AC topology examples
- [Grid forming](TWIST/DC_AC/grid_forming/README.md)
- [Grid following](TWIST/DC_AC/grid_following/README.md)

- Communication examples
- [CAN Communication](TWIST/Communication/CAN/README.md)
- [Python Communication Protocol](TWIST/Communication/python_comm_library/README.md)

# Examples for OWNVERTER

- Motor control examples
- [BLDC motor with hall sensor](OWNVERTER/BLDC_hall_sensor/README.md)
- [Motor control using FOC and hall sensors](OWNVERTER/FOC_hall_sensor/README.md)

# Examples for SPIN

- ADC use examples
- [Software trigerred ADC](SPIN/ADC/adc_software_trigger/README.md)
- [HRTIM trigerred ADC](SPIN/ADC/adc_hrtim_trigger/README.md)
- [Software triggered ADC](SPIN/ADC/adc_software_trigger/README.md)
- [HRTIM triggered ADC](SPIN/ADC/adc_hrtim_trigger/README.md)

- DAC use examples
- [Signal generation](SPIN/DAC/signal_generation/README.md)
Expand All @@ -34,6 +49,7 @@ Here you can find ready to be used example for [SPIN](https://github.com/owntech
- [Blinky](SPIN/LED/blinky/README.md)

- PWM use examples
- [PWM burst mode control](SPIN/PWM/burst_mode/README.md)
- [PWM duty cycle control](SPIN/PWM/duty_cycle_setting/README.md)
- [PWM phase shift control](SPIN/PWM/phase_shift/README.md)
- [Multiple PWM operation](SPIN/PWM/multiple_pwm/README.md)
Expand Down
36 changes: 18 additions & 18 deletions SPIN/ADC/adc_hrtim_trigger/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Triggering measure from ADC via HRTIM trigger

An ADC, or Analog-to-Digital Converter, is a crucial component in modern electronics that converts continuous analog signals into discrete digital data. In simpler terms, it takes real-world phenomena, like sound or temperature, and turns them into numbers that a computer can understand and process. This conversion is essential for various applications, in power electronics it allows us to get real-time measures from the circuit like voltage and current.
An ADC, or Analog-to-Digital Converter, is a crucial component in modern electronics that converts continuous analog signals into discrete digital data. In simpler terms, it takes real-world phenomena, like sound or temperature, and turns them into numbers that a computer can understand and process. This conversion is essential for various applications, in power electronics it allows us to get real-time measurements from the circuit like voltage and current.

The spin uses the stm32G4 MCU, which has a high resolution timer (HRTIM) which can produce high resolution PWM. This example will show you how to use the HRTIM in order to trigger the measures.
The SPIN uses the STM32G4 MCU, which has a high-resolution timer (HRTIM) which can produce high-resolution PWM. This example will show you how to use the HRTIM in order to trigger the measurements.

## Hardware setup and requirements

![Schematic](Image/schema.png)
*figure 1*

You will need :
You will need:

- 1 SPIN
- A usb-c cable to supply power to the spin, and also upload the code from computer
- A signal generator to create a waveform to measure it from ADC, it can be sinewave, triangle wave...etc. This signal must between **0V and 2.048V**
- A USB-C cable to supply power to the SPIN, and also upload the code from a computer
- A signal generator to create a waveform to measure it from the ADC, it can be a sine wave, triangle wave...etc. This signal must be between **0 V and 2.048 V**

There is a total of 8 possible pins from where you can get synchronous analog measurements :

Expand All @@ -33,14 +33,14 @@ In this example we connect the signal generator to pin `35`, and a `GND` pin.

## Software setup

The HRTIM has 6 different timer (A,B,C,D,E,F) but you can choose up to two of them to trigger the measures. In this example we'll show you how you can use one of them **the timer A**.
The HRTIM has 6 different timers (A, B, C, D, E, F) but you can choose up to two of them to trigger the measurements. In this example we'll show you how you can use one of them: **timer A**.

On the picture below, you can see the waveform of the timer A pwm, the carrier, the duty cycle and the colored zone represents the timing where the measures is triggered.
In the picture below, you can see the waveform of the timer A PWM, the carrier, the duty cycle and the colored zone represents the timing where the measurement is triggered.

![trigger_waveform](Image/Hrtim_trigger.png)
*figure 2*

The measure is triggered with the same frequency as the switching frequency, the measure is done around the trough of the carrier on the positive slope. We will explain here which functions to call to setup the ADC trigger.
The measurement is triggered with the same frequency as the switching frequency; the measurement is done around the trough of the carrier on the positive slope. We will explain here which functions to call to set up the ADC trigger.

First of all, we start by initializing the PWMA :

Expand All @@ -52,7 +52,7 @@ First of all, we start by initializing the PWMA :

spin.pwm.initUnit(PWMA); // timer initialization
```
The function `setAdcEdgeTrigger` allows us to choose where we want to trigger the measures : on the positive slope `EdgeTrigger_up` of the carrier like in fig.2, or the negative slope `EdgeTrigger_down` of the carrier.
The function `setAdcEdgeTrigger` allows us to choose where we want to trigger the measurements: on the positive slope `EdgeTrigger_up` of the carrier like in fig.2, or the negative slope `EdgeTrigger_down` of the carrier.

After the initialization of the PWM, we can link it to a trigger :

Expand All @@ -62,21 +62,21 @@ After the initialization of the PWM, we can link it to a trigger :
spin.pwm.enableAdcTrigger(PWMA); // enable the trigger
```
We are linking PWMA to a trigger, here `ADC_2`.
There is two ADCs that support synchronous data acquisition : `ADC_1` and `ADC_2`.
There are two ADCs that support synchronous data acquisition: `ADC_1` and `ADC_2`.

`setAdcTriggerInstant` will set the moment when we trigger a measure with a parameter between 0 (corresponding to the trough of the carrier)and 1 (corresponding to the crest of the carrier). Here we took 0.06, so we'll get the data around the trough of the carrier (as we have seen on fig.2)
`setAdcTriggerInstant` will set the moment when we trigger a measurement with a parameter between 0 (corresponding to the trough of the carrier) and 1 (corresponding to the crest of the carrier). Here we took 0.06, so we'll get the data around the trough of the carrier (as we have seen on fig.2)

And finally, we set the `ADC2` to be triggered by the PWM `TRIG_PWM`.

```cpp
spin.adc.configureTriggerSource(ADC_2, TRIG_PWM); // ADC 2 configured to be triggered by the PWM
```
We use the 5th channel of the adc, which is the gpio `35` on the spin (also numbered as C4). To enable the acquisition from this pin, we use the function `enableAcquisition`:
We use the 5th channel of the ADC, which is the GPIO `35` on the SPIN (also numbered as C4). To enable the acquisition from this pin, we use the function `enableAcquisition`:

```cpp
spin.data.enableAcquisition(35, ADC_2); // Enable acquisition for ADC2, for channel 5 (localized in GPIO C4 / pin number 35)
```
When are now set, we must be sure that there is a critical task defined and active, and make sure that `PWMA` is active because it is now the ADC trigger source.
When everything is now set, we must be sure that there is a critical task defined and active, and make sure that `PWMA` is active because it is now the ADC trigger source.

```cpp
spin.pwm.startDualOutput(PWMA);
Expand All @@ -88,7 +88,7 @@ You can also use `ADC_1` to get a second independent trigger event, for instance
we can bind `PWMC`to `ADC_1`.
Below, we reproduce the same step but by using the `ADC1` channel 2 localized on pin `30` (PA1).

start PWMC :
Start PWMC:

```cpp
spin.pwm.setFrequency(200000); // Set frequency of pwm
Expand All @@ -98,14 +98,14 @@ start PWMC :

spin.pwm.initUnit(PWMC); // timer initialization
```
link `ADC_1` to `PWMC` :
Link `ADC_1` to `PWMC`:

```cpp
spin.pwm.setAdcTrigger(PWMC, ADC_1); // PWMA is linked to ADCTRIG_1
spin.pwm.setAdcTriggerInstant(PWMC, 0.06); // set the trigger instant
spin.pwm.enableAdcTrigger(PWMC); // enable the trigger
```
then set `ADC1` channel 2 to be triggered by the PWM :
Then set `ADC1` channel 2 to be triggered by the PWM:

```cpp
spin.adc.configureTriggerSource(ADC_1, TRIG_PWM); // ADC 1 configured to be triggered by the PWM
Expand All @@ -114,6 +114,6 @@ then set `ADC1` channel 2 to be triggered by the PWM :

## Expected results

The analog value measured from the adc is stored inside the variable `adc_value`, which is printed in the serial monitor every 100ms you can then watch the measured on [ownplot](https://github.com/owntech-foundation/OwnPlot).
The analog value measured from the ADC is stored inside the variable `adc_value`, which is printed in the serial monitor every 100 ms. You can then watch the measurements on [OwnPlot](https://github.com/owntech-foundation/OwnPlot).

If everything went correctly, you should observe the same waveform on ownplot that you generate via the signal generator.
If everything went correctly, you should observe the same waveform on OwnPlot that you generate via the signal generator.
Loading