On this page
A short guide to choosing PWM pins for your application
When it comes to choosing pins for your application, there are a few things to consider. The most important thing is to make sure that the pins you choose are compatible with the hardware you are using. Make sure to check that your microcontroller family and SimpleFOC supports the necessary PWM generation, position sensor and current sensing technique. You can find this info in our docs here.
Once you are sure that you microcontroller is apt to the application, it is time to consider which pins to use. There are three main questions:
- Which pins to use for PWM generation?
- Which pins to use for the position sensor?
- Which pins to use for current sensing?
In this guide we will focus on the first question: Which pins to use for PWM generation?
The answer to these questions depends on the microcontroller you are using and the hardware you have. Here is the list of microcontroller families supported by SimpleFOC and the PWM generation modes supported by each of them:
MCU | 2 PWM mode | 4 PWM mode | 3 PWM mode | 6 PWM mode | PWM frequency config | PWM center align | Timer-ADC sync |
---|---|---|---|---|---|---|---|
Arduino AVR (8-bit) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ (4kHz or 32kHz) | ✔️ | ❌ |
Arduino DUE | ✔️ | ✔️ | ✔️ | ❌ | ✔️ | ❌ | ❌ |
stm32 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
esp32 MCPWM | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
esp32 LEDC | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
esp8266 | ✔️ | ✔️ | ✔️ | ❌ | ✔️ | ❌ | ❌ |
samd21/51 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ (2/3/4PWM) ✔️ (6PWM) | ❌ |
teensy3 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ (2/3/4PWM) ✔️ (6PWM) | ❌ |
teensy4 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌(2/3/4PWM) ✔️ (6PWM) ✔️(3PWM forced) | ❌(2/3/4PWM) ✔️(6PWM) ✔️(3PWM aligned) |
Raspberry Pi Pico | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ (2/3/4PWM) ✔️ (6PWM) | ❌ |
Portenta H7 | ✔️ | ✔️ | ✔️ | ❌ | ✔️ | ❌ | ❌ |
nRF52 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ (2/3/4PWM) ✔️ (6PWM) | ❌ |
Renesas (UNO R4 Minima) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ (2/3/4PWM) ✔️ (6PWM) | ❌ |
What is important to see is that all the supported families can be used with 2/3/4PWM modes. However, not all the architectures support 6PWM mode. Additionally, the PWM frequency can be configured for all the supported architectures, but for Arduino AVR boards, the frequency can be set to either 4kHz or 32kHz.
Another important factor when it comes to choosing the PWM pins is to try to use the PWM pins that belong to the same timer. This is important because the PWM signals generated by the pins that belong to the same timer will have the same frequency and phase. This is important for the FOC algorithm to work properly. The rule of thumb:
- For 2PWM mode, try using only one timer.
- For 3PWM mode, try using only one timer.
- For 4PWM mode, try using only one timer if possible, if not use one timer per phase (so two timers).
- For 6PWM mode, try using only one timer if possible, if not use one timer per phase (so three timers).
BEWARE: PWM center alignment
SimpleFOC does synchronise (center-align) the PWM signals generated by different timers in some cases (as shown on the table above), but it is always better to use the pins that belong to the same timer.
BEWARE: Timer-ADC sync - low-side current sensing
Timer and ADC synchronisation, required for low-side current sensing is only avaliable for certain families of microcontrollers: stm32, esp32 (
MCPWM
based) and Teesny 4.
The information about the timers associated with the pins is sometimes hard to obtain, especially for less experienced users. So in the next few sections we will provide some information on how to find the PWM pins for some of the most popular microcontroller families.
Arduino AVR boards
For Arduino AVR boards (UNO, MEGA, Nano, Leonardo, …), the PWM pins are usually marked with a ~
sign. These pins are the ones that can generate PWM signals. If you are writing an application with 2PWM,3PWM or 4PWM modes, you can use any of the PWM pins. The PWM timers are mutually synchronised so you do not have to worry about this info.
However if you are using 6PWM mode, you will have to use the pins that belong to the same timer. The pins that belong to the same timer are:
Arudno UNO/Nano/Pro mini Atmega328P
Timer | pins |
---|---|
TIM0 | 5 ,6 |
TIM1 | 9 ,10 |
TIM2 | 3 ,11 |
Arudno Leonardo Atmega32u4
Timer | pins |
---|---|
TIM0 | 3 ,11 |
TIM1 | 9 ,10 |
TIM3 | 5 |
TIM4 | 6 , 13 |
Arudno MEGA Atmega2560
Timer | pins |
---|---|
TIM0 | 13 ,4 |
TIM1 | 12 ,11 |
TIM2 | 10 ,9 |
TIM3 | 5 ,3 ,2 |
TIM4 | 8 ,7 ,6 |
TIM5 | 44 ,45 ,46 |
So if using one of these boards with 6PWM make sure to use the High/Low pair of pins that belong to the same timer. So in that case atmega328P
and atmega32u4
have to use all of their PWM pins to generate 6PWM signals (atmega32u4
cannot use the pin 5
as it is alone on the timer TIM3
). Also, atmega2560
has enough pins to run two 6PWM drivers using only one timer.
ESP32 boards
Esp32 boards have two PWM generation modules: LEDC
and MCPWM
. The LEDC
module is used for generating PWM signals for LEDs, but it can also be used for motor control. The MCPWM
module is specifically designed for motor control. Even though LEDC
is far less flexible than MCPWM
, it still enables running all drivers supported by the SimpleFOClibrary. However, with LEDC
you will not be able to use low-side current sensing, as the timers cannot bve synced with the ADCs.
MCPWM module
So when using esp32 boards that have MCPWM
module (ex. esp32
and esp32s3
) you can use any of the pins for any form of PWM generation. This module allows the esp32 to be very flexible and allows for any pin to be used in PWM mode as well as to be associated to any timer. Typically, esp32 boards have 2 MCPWM
independent modules allowing to instantiate:
- 4 instances of 2PWM mode drivers
- 4 instances of 3PWM mode drivers
- 2 instances of 4PWM mode drivers
- 2 instances of 6PWM mode drivers
This association of the appropriate timer and chanel for your applications will be done automatically by the SimpleFOC.
ESP32 SoC | has MCPWM |
---|---|
ESP32 | ✔️ |
ESP32-S2 | ❌ |
ESP32-S3 | ✔️ |
ESP32-C3 | ❌ |
All the esp32 architecture that have the MCPWM
will by default use MCPWM
for motor control.
LEDC module
However, if using the boards that only support the LEDC
module (ex. esp32s2
and esp32c3
), you will not be able to use it for most of the motor control modes. The LEDC
module is not as flexible as the MCPWM
module and it is not recommended for motor control applications. You will still be able to use 2PWM, 3PWM, 4PWM and 6PWM modes. LEDC
timers usually have 8 channels and different boards have different number of channels and timers available. All the pins can be used for PWM generation, but first 8 pins are associated with the first timer, the next 8 pins with the second timer and so on.
Here is the list of the number of channels available for different esp32 chips, taken from the esp32 technical reference manual:
ESP32 SoC | Number of LEDC channels |
---|---|
ESP32 | 16 |
ESP32-S2 | 8 |
ESP32-S3 | 8 |
ESP32-C3 | 6 |
If the user wants to force using the LEDC
driver for the boards that support MCPRM
he has to set the SIMPLEFOC_ESP32_USELEDC
.
STM32 boards
Stm32 is the most powerful family of microcontrollers supported by SimpleFOC, at least in terms of motor control capabilities. SimpleFOC supports most of the STM32 boards and all of them can be used in 6PWM mode. Additionally from the release v2.3.3 the SimpleFOC library synchronises the PWM signals generated by different timers by default. Therefore for all the use cases except 6PWM generation, the user does not have to worry about the timers associated with the pins, however it is still recommended to use the pins that belong to the same timers.
When it comes to 6PWM mode, the user has two choices:
- Use the pins that belong to the same timer. This is the recommended as all stm32 boards have timers typically
TIM1
andTIM8
that are desigened for this applications and allow for the best performance. - Use one timer per phase. This is also a goof solution, especially if the pins necessary to use the advanced timers are not available. However, in this case the application uses 2 or 3 timers instead of 1 which might reduce the capacity of the microcontroller to do other tasks in parallel.
Once you provide the SimpleFOC driver object with a set of pins, the library will automatically associate the pins with the appropriate timers and channels and find the best combination for motor control. If the pins are not compatible with the motor control mode you are trying to use, the library will throw as error.
Finding the pins that belong to the same timer is not an easy task, especially for less experienced users. Therefore, we’ve created a website that enables a realtively easy navigation of the pins and timers for the most popular stm32 boards.
As a rule of thumb, most of the stm32 boards have following pins that belong to the advanced timer TIM1
:
PA8
- channel1
PA9
- channel2
PA10
- channel3
PB13
- inverted channel1N
PB14
- inverted channel2N
PB15
- inverted channel3N
So this is the combination of pins that is preferred for 6PWM mode.
Teensy boards
Teensy boards are very powerful and have a lot of timers that can be used for PWM generation. The SimpleFOC library supports all the Teensy3 and Teensy4 boards and all of them can be used in 6PWM mode.
Here is the table taken from teensy docs listing the PWM pins of different teensy families:
Board | PWM Capable Pins |
---|---|
Teensy 4.1 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 22, 23, 24, 25, 28, 29, 33, 36, 37, 42, 43, 44, 45, 46, 47, 51, 54 |
Teensy 4.0 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 22, 23, 24, 25, 28, 29, 33, 34, 35, 36, 37, 38, 39 |
Teensy 3.6 | 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 16, 17, 20, 21, 22, 23, 29, 30, 35, 36, 37, 38 |
Teensy 3.5 | 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 20, 21, 22, 23, 29, 30, 35, 36, 37, 38 |
Teensy 3.2 & 3.1 | 3, 4, 5, 6, 9, 10, 20, 21, 22, 23, 25, 32 |
Teensy LC | 3, 4, 6, 9, 10, 16, 17, 20, 22, 23 |
Teensy 3.0 | 3, 4, 5, 6, 9, 10, 20, 21, 22, 23 |
SimpleFOC does not synchronise the PWM signals generated by different timers for Teensy boards, so it is recommended to use the pins that belong to the same timer.
Teensy3
So when using Teensy3 boards, it is recommended (not a hard constraint) to use the pins that belong to the same timer. The pins that belong to the same timer are listed in the tables below.
Tensy 3.6
Timer | pins |
---|---|
FTM0 | 5, 6, 9, 10, 20, 21, 22, 23 |
FTM1 | 3, 4 |
FTM2 | 29, 30 |
FTM3 | 2, 7, 8, 14, 35, 36, 37, 38 |
TPM1 | 16, 17 |
Teensy 3.5
Timer | pins |
---|---|
FTM0 | 5, 6, 9, 10, 20, 21, 22, 23 |
FTM1 | 3, 4 |
FTM2 | 29, 30 |
FTM3 | 2, 7, 8, 14, 35, 36, 37, 38 |
Teensy 3.2 & 3.1
Timer | pins |
---|---|
FTM0 | 5, 6, 9, 10, 20, 21, 22, 23 |
FTM1 | 3, 4 |
FTM2 | 25, 32 |
Teensy LC
Timer | pins |
---|---|
FTM0 | 6, 9, 10, 20, 22, 23 |
FTM1 | 16, 17 |
FTM2 | 3, 4 |
Teensy 3.0
Timer | pins |
---|---|
FTM0 | 5, 6, 9, 10, 20, 21, 22, 23 |
FTM1 | 3, 4 |
All Teensy3 boards can be used in 6PWM mode on timer FTM0
, and the ones that have FTM3
have the possibility to use 6PWM mode on FTM3
as well. SimpleFOC does not allow for other combinations of timers for 6PWM mode, at least till the release v2.3.3
Teensy4
When using Teensy4 boards, it is recommended (not a hard constraint) to use the pins that belong to the same timer. The pins that belong to the same timer are listed in the tables below.
Tensy 4.1
Timer | submodule | pins |
---|---|---|
FlexPWM1 | 0 | 1, 44, 45 |
FlexPWM1 | 1 | 0, 42, 43 |
FlexPWM1 | 2 | 24, 46, 47 |
FlexPWM1 | 3 | 7, 8, 25 |
FlexPWM2 | 0 | 4, 33 |
FlexPWM2 | 1 | 5 |
FlexPWM2 | 2 | 6, 9 |
FlexPWM2 | 3 | 36, 37 |
FlexPWM3 | 0 | 54 |
FlexPWM3 | 1 | 28, 29 |
FlexPWM3 | 3 | 51 |
FlexPWM4 | 0 | 22 |
FlexPWM4 | 1 | 23 |
FlexPWM4 | 2 | 2, 3 |
QuadTimer1 | 0 | 10 |
QuadTimer1 | 1 | 12 |
QuadTimer1 | 2 | 11 |
QuadTimer2 | 0 | 13 |
QuadTimer3 | 0 | 19 |
QuadTimer3 | 1 | 18 |
QuadTimer3 | 2 | 14 |
QuadTimer3 | 3 | 15 |
Teensy 4.0
Timer | submodule | pins |
---|---|---|
FlexPWM1 | 0 | 1, 36, 37 |
FlexPWM1 | 1 | 0, 34, 35 |
FlexPWM1 | 2 | 24, 38, 39 |
FlexPWM1 | 3 | 7, 8, 25 |
FlexPWM2 | 0 | 4, 33 |
FlexPWM2 | 1 | 5 |
FlexPWM2 | 2 | 6, 9 |
FlexPWM3 | 1 | 28, 29 |
FlexPWM4 | 0 | 22 |
FlexPWM4 | 1 | 23 |
FlexPWM4 | 2 | 2, 3 |
QuadTimer1 | 0 | 10 |
QuadTimer1 | 1 | 12 |
QuadTimer1 | 2 | 11 |
QuadTimer2 | 0 | 13 |
QuadTimer3 | 0 | 19 |
QuadTimer3 | 1 | 18 |
QuadTimer3 | 2 | 14 |
QuadTimer3 | 3 | 15 |
Teensy4 has a combination of two timer types FlexPWM
and QuadTimer
. For 2PWM, 3PWM and 4PWM modes you can use any of the pins listed above, even if they belong to a combination of QuadTimer
and FlexTimer
channels. However, for best results, it is recommended to use the pins that belong to the same timer, or at least one timer per phase. Especially since SimpleFOC library, as of release v2.3.3 does not by default synchronise the PWM signals generated by different timers for 2PWM, 3PWM and 4PWM modes. Additionally, the generated PWM signals are not center-aligned either.
SimpleFOC, by default, does the center-alignment and timer sync only for 6PWM drivers. If you want to force the center-aligned 3PWM mode on Teensy4, you can set the SIMPLEFOC_TEENSY4_FORCE_CENTER_ALIGNED_3PWM
flag. This will force the center-aligned 3PWM mode and sync the timers if using multiple ones. However, both of these modes require using FlexPWM
timers and cannot be used with QuadTimer
timers.
6PWM
SimpleFOC as of the release v2.3.3 allows for 6PWM mode only on FlexPWM
timers. The pins that belong to QuadTimer
timers are not supported for 6PWM. Additionally, SimpleFOC requires to use one submodule per phase of the 6PWM mode, if that is not the case, SimpleFOC will show an error. In order to use the 6PWM, for each phase, chose the pins A
and B
from the same time and submodule. The pin X
is not used in the 6PWM mode.
Center-aligned 3PWM
If you want to force the center-aligned 3PWM mode on Teensy4, you can set the SIMPLEFOC_TEENSY4_FORCE_CENTER_ALIGNED_3PWM
flag. For this mode you can use any of the pins A
, B
or X
that belong to any the FlexPWM
timers. SimpleFOC will automatically sync the timers if using multiple ones. If application allows it, it is recommended to use channels A
and B
of timers and avoid X
. Additionally, if the flag is set and you try to use a QuadTimer
timer, SimpleFOC will show an error.
Here is the table showing the pins A
, B
and X
for each timer and submodule.
Teensy 4.1
FlexTimer | submodule | A | B | X |
---|---|---|---|---|
FlexPWM1 | 0 | 45 | 44 | 1 |
FlexPWM1 | 1 | 43 | 42 | 0 |
FlexPWM1 | 2 | 47 | 46 | 24 |
FlexPWM1 | 3 | 8 | 7 | 25 |
FlexPWM2 | 0 | 4 | 33 | - |
FlexPWM2 | 1 | 5 | - | - |
FlexPWM2 | 2 | 6 | 9 | - |
FlexPWM2 | 3 | 36 | 37 | - |
FlexPWM3 | 0 | 54 | - | - |
FlexPWM3 | 1 | 29 | 28 | - |
FlexPWM3 | 3 | - | 51 | - |
FlexPWM4 | 0 | 22 | - | - |
FlexPWM4 | 1 | 23 | - | - |
FlexPWM4 | 2 | 2 | 3 | - |
Teensy 4.0
FlexTimer | submodule | A | B | X |
---|---|---|---|---|
FlexPWM1 | 0 | 37 | 36 | 1 |
FlexPWM1 | 1 | 35 | 34 | 0 |
FlexPWM1 | 2 | 39 | 38 | 24 |
FlexPWM1 | 3 | 8 | 7 | 25 |
FlexPWM2 | 0 | 4 | 33 | - |
FlexPWM2 | 1 | 5 | - | - |
FlexPWM2 | 2 | 6 | 9 | - |
FlexPWM3 | 1 | 29 | 28 | - |
FlexPWM4 | 0 | 22 | - | - |
FlexPWM4 | 1 | 23 | - | - |
FlexPWM4 | 2 | 2 | 3 | - |