Teensy 4.1 6PWM


I’m a member of the University of Michigan Supermileage project team and we aim to create a hyper-efficient electric vehicle. We’re trying to use the simpleFOC code for a Teensy 4.1 to control a 3 phase BLDC electric motor. For our purposes, we’re looking for maximum efficiency, so 6PWM would be the optimal control method to use for us.

I was curious why 6PWM is not supported by SimpleFOC? Is it the case that there aren’t 6 PWM pins where there are 3 pairs of two pins each on their own timers for each of the 3 phases? Thank you for your help.


Welcome to the board. It’s always good do meet anyone from UM. We hope you find what you need here. I have great memories from Ann Arbor :wink:


You mean why SimpleFOC doesn’t support 6PWM on Teensy 4.1? It’s supported on other MCUs. Why specifically Teensy?

It has something to do with the centrally aligned complementary timers required for 6PWM motor control. It is probably best that you get the answers from @Antun_Skuric and @runger . I’m tagging them here so perhaps they could get you a better answer.

You need 6 pins on a 3 / 3N configuration all on the same timer with complementary hardware-controlled center-aligned timers. That’s the short answer.

Why don’t you use a more widely accepted MCU such as one of the STM32 high end H7 which is fully supported? Teensy 4.1 (NXT’s MIMRXT1062 MCU) may get obsolete/end-of-life pretty quickly and has always been more of a niche boutique MCU anyways. Some of the older revisions are already EOL.

Anyway, love to talk more on this topic, however, let’s not get ahead of ourselves here.



Always love to see an alum! While I was waiting for a response from this forum, I was looking into the other boards and starting to question why we used Teensy also. I recently took over in a leadership position on Supermileage, and this is just “the way things always have been”. But it looks like it’s time to change up our MCU!

Thanks for your help. I’m sure I’ll hop back on this forum soon.

We had about a year ago someone from UM asking here very similar questions, and we advised them against Teensy but the answer was, funny enough, “that’s how we do it”, :thinking:

Perhaps It’s time to change? Please look into the high end STM Nucleo H7 boards, or Arduino’s Portenta H7, those are good ones. Moving to STM32 (disclaimer, I got nothing to do with ST Micro) may be a good idea.

Don’t play too much in the snow there, stay warm, hehe.


PS Found it, please check this out. I believe they were able to make 6PWM on teensy work but they promised me they will switch to STM32? They said they were from the Supermileage team so you may know them. Small world.

One argument for STM32H7 MCUs is the ADC alone. Read op on that, you may find some actual mileage in having a wider sensing range.

Would love to se you nerds work on the Portenta, but that is a hefty price increase compared to Teensy and it’s a somewhat new territory

Edit: What I ment was; You can use a 1.3Mhz or faster current sense bandwidth with the 3.6MSPS ADC.

We support 14 MCU types, and there is, I believe no special reason we didn’t get to this on the teensy, other than time :wink:
While 3-PWM is fairly easy to implement, 6-PWM gets a lot more MCU-specific, so we’d have to look into all the different Teensy MCUs, see what the hardware can really do, and implement the driver layer(s). These days this also includes current sensing, a whole extra layer of complexity.

Also keep in mind the original SimpleFOC hardware is 3-PWM.

Of course, if someone were to contribute some teensy PWM code we’d be super happy to look at pull requests :smiley:

1 Like

Hey all,

Thanks for all of the advice! We actually had a STM32 NUCLEO-L432KC lying around, so I was able to get some code uploaded to that and hooked it up to our system this morning. I wasn’t able to get it to run, but I got it to hum/make some noise. We’re using hall sensors for our position sensing, I suspect that I got these phases wrong possibly. We’re trying to implement 6PWM, is this assignment viable for the high and low sides of each phase? I believe I have each phase on the same timer and then the high and low are complementary. Here’s a vid of what we saw this morning, also a snapshot of the NUCLEO-L432KC pinout labeled with the assignments I chose. and also a snapshot of the code that I wrote(copied lol). Any advice on where to go from here?


You got the timers wrong. Try this:

The hall sensors would work on any digital pin, so I’m not touching these.

You don’t seem to have enable so let’s leave the enable out.

Please next time post the code, not pictures, I cannot edit the pictures.

You can rearrange the timer pairs to match your A B and C, as long as you keep the complementary pairs correctly.

TIM1/1 – TIM1/1N
TIM1/2 – TIM1/2N
TIM1/3 – TIM1/3N

All three phases MUST be on the same timer.

and match them with the halls.

Let me know how it goes. Oscilloscope on the pins will tell you if you got the timers correctly.

Also, you may want to get one of the the big Nucleo 64, this small one overheats very easily because they put two MCUs on top of each other. If you flip it you will see the SWD MCU at the bottom. If you let it run for a bit longer you could probably fry a hamburger on top.


yes, I would also use the pins Valentine suggested - so switch phase c to use PA10/PB1

When working with PlatformIO, be sure to add the option

lib_archive = false

to your platformio.ini.
The following can also be helpful:

build_flags = 

Then enable debug output in the setup function:

  while (!Serial) ;


The SERIAL_UART_INSTANCE thing is for many nucleo boards, not sure if it is correct for this one…

1 Like

Hello again. We took your advice and used the pins you suggested, however we’re running into new problems. The motor moves to initialize but it says that the initialization fails because it fails to notice movement. When seeing this, we ran the sensor test and it appears to be getting the hall sensor input just fine (Videos below). If the sensor test is working, why is it failing to recognize movement?

Also, we ran the driver test and got the correct voltages on each phase, so we think that our hardware is working ok.

Here’s a link of the sensor test working and the main function failing to initialize

Also, here’s the code we’re running for the main:

#include <SimpleFOC.h>
#include <Arduino.h>

///////PHASE PINS/////////
int pha_h = D1;
int pha_l = D3;
int phb_h = D0;
int phb_l = D6;
int phc_h = D9;
int phc_l = A6;

/////////HALL SENSOR PINS///////////////////
//TODO: figure out which phase is which sensor
int halla = A4;
int hallb = A3;
int hallc = A2;

int PP = 21;

BLDCDriver6PWM driver = BLDCDriver6PWM(pha_h, pha_l, phb_h, phb_l, phc_h, phc_l);
HallSensor sensor = HallSensor(halla, hallb, hallc, PP);
BLDCMotor motor = BLDCMotor(PP);

void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}

void setup() {

sensor.enableInterrupts(doA, doB, doC);

driver.pwm_frequency = 20000; //Hz
driver.voltage_power_supply = 48;
driver.voltage_limit = 10;


motor.controller = MotionControlType::velocity;


void loop() {
// velocity control loop function
// setting the target velocity or 2rad/s

thanks for your help again.

Q1: Does open velocity (un-sensored) turn the motor OK? Please run in open velocity to make sure the phases are working fine and the voltage is set correctly, then we will build from there.

Q2: What is the driver that you are using? I mean the 3-phase 1/2 bridge.

Let me see the video. I’ll update this post so we don’t end up with a hundred posts.

I’m tagging @runger and @Antun_Skuric if they have any inputs.

Edit1: I don’t see any movement in the sensor test video, am I looking at the right thing? It says 6.18 0.00 and nothing else when you turn by hand. I don’t think your sensors are working. The first column is the angle the second is the velocity and they do not update when you turn by hand. Again am I looking at the correct video? Could be wrong.

You could put a delay in the sensor update loop for sensor test to loop only once every 100 milliseconds, to get a more user-friendly output to debug.


And are you sure about 42 magnets in the rotor ?

I got a similar motor so that’s a large motor, 42 magnets is not that unusual. The hoverboards have between 30 and 40.

My proposal would be to make a small sketch just showing the hall sensor states. If it’s not in the repo, then it would IMO be a neat tool

Agree. Also, my proposal would be they ditch the hall sensors altogether ang get a much better SPI angle sensored motor but in their case that may not be an option. The rules may be governed by the competition bylaws.