BLHELI_M, JESC and Bluejay - Betaflight RPM filtering explained

Most of you will probably know what BLHELI_S is - the de-facto standard firmware for most brushless-whoop ESC’s and generally most ESC’s we use in the quadcopter hobby nowadays.

Apart from BLHELI_S there is also BLHELI_32 - the 32 bit version of BLHELI which provides bidirectional DSHOT and ESC telemetry out of the box, but is only available on a small subset of ESC’s and up until now only very few of the AIO boards that we commonly use with brushless whoops and toothpicks come with BLHELI_32 ESC’s.

There is also KISS ESC firmware, but since this is kind of its own eco-system and not really commonly used for micros and whoops anyway (at least I have no experience with it at all), I am not going to discuss it here.

One other important difference between BLHELI_32 and BLHELI_S is, that BLHELI_S is open source. To use BLHELI_32, ESC manufacturers need to pay a licence fee to the developer and the source is closed.

BLHELI_32 has one killer feature - bidirectional DSHOT. Basically allowing the ESC to communicate back to the flight-controller. Among the data being sent back to the flight-controller, the speed with which each of the motors is spinning, is probably the most important one, since it allows for RPM filtering to work.

And this is where JESC, BLHELI_M and Bluejay come into play - they all back-ported bidirectional DSHOT to BLHELI_S ESC’s, their approaches being slightly different, but the end-result being the same: enabling RPM filtering.

Table of content

RPM filtering

RPM filtering uses the motors RPM to efficiently filter noise from the gyro signal. This is a super efficient way of filtering and allows to reduce the amount of filtering that has to be done by the flight controller in software. RPM filtering thus improves performance and response times of the quadcopter. It also greatly improves prop wash, allows the motors to run cooler and generally is a feature that you really want to have enabled.

I was personally from the first times I tried RPM filtering on one of my bigger BLHELI_32 rigs and was super excited when I realized that I can also have it on basically all of my BLHELI_S setups, including my whoops.

What is noise?

In an perfect world, the gyro would only give us data about the movement of the quad, which is then fed into the PID controller which decides if the quad moved enough according to our stick inputs. Unfortunately the gyro does not provide us with a clean signal of just those movements. We have a lot of undesired data in the gyro signals - this is considered noise. There are multiple sources of noise:

  • Vibrations from the motors
  • unbalanced props
  • Wind blowing against the quadcopter
  • Vibrations due to frame resonance
  • Crashing into stuff, clipping branches

Some of this noise is easier to filter than other, some of it is even impossible to filter. For a long time flight controller software only had a single filter, a cutoff filter that would simply attenuate all frequencies above a certain threshold. Over the time filters got more complex and sophisticated and thus better in targeting certain source of noise and removing it from the gyro data adding the least amount of latency possible.

Each filtering step ads latency, the more complex the filter is and the higher the bandwidth it has to work on, the higher the latency is. So filtering is always a trade off between a clean signal and latency. Generally speaking you want as little filtering as possible to get the most responsive feeling quad.

One of those targeted filters is the RPM filter - it has one purpose: remove the noise that is coming in through the rotation of motors, and it is very efficient at that.

How does RPM filtering work?

The ESC transfers eRPM (electrical RPM) via bidrectional DSHOT back to the flight controller. This happens for each motor. The flight controller calculates the real RPM based on the eRPM and the pole count of the motor.

RPM = eRPM / poles / 2

That is why you have to set the (correct) pole count when enabling bidirectional DSHOT. Pole count is simply the amount of magnets in the bell of the motor. Most bigger motors have 14 magnets and most micro and whoop motors have 12. But you should definitely count them yourself or check the product description for this crucial bit of information - otherwise you risk your motors to run hot and RPM filtering not working properly.

The next step is to calculate the motors current frequency, based on the RPM:

f = RPM / 60

Once the flight controller knows the current RPM frequency of the motor it can calculate the harmonics. Harmonics are multiples of the calculated base (or fundamental) frequency. Each harmonic has a lower amplitude than its predecessor.

Example: The motor is spinning with 4500 RPM, The base frequency is at 75Hz this is our fundamental - the first harmonic. The second harmonic is at double that, so 150Hz and the third at tripple the base frequency, so 225Hz.

The filters themselves are notch filters. For each harmonic there are three notch filters per motor, on each axis (yaw, roll and pitch). This means with the default settings (three harmonics), we have 3 (harmonics) x 4 (motors) x 3 (axis) = 36 notch filters in total. Those filters are very narrow, since we know exactly where the center frequencies we are trying to eliminate are, and thus are adding very little latency to filtering in general.

A notch filter attenuates a certain range of frequencies. The highest attenuation being at its center frequency and is getting less and less to the sides of it, depending on the Q of the notch filter:

The image shows a notch filter placed at 75Hz - you can see that the attenuation is the highest at the center frequency, and gets lower the further away we move from the center frequency on both sides. How wide this bandwidth is depends on the Q. Lower Q means higher bandwidth, higher Q lower bandwidth.


RCGroups user and BetaFlight developer JoeLucid (Thorsten Laux) saw the potential of RPM filtering, implemented it into BetaFlight and found a way to back-port bidirectional DSHOT to BLHELI_S. This is done via a telemetry plugin and a slightly modified version of BLHELI_S. He called it JESC.

Apart from the telemetry plugin, JESC also provides the BLHELI_S firmware with different PWM update frequencies - you can even use those free of charge - and I would highly recommend to do so - especially on whoops, to increase your flight time of up to 30%.

The paid part of JESC is the telemetry plugin, allowing for bidirectional DSHOT - and thus enabling RPM filtering - on basically all BLHELI_S ESC’s. This also works very well on the AIO boards that we like to use with brushless whoops and toothpicks.


Around the same time that JESC was being developed, RCGroups user JazzMac came out with a firmware that also allows for bidirectional DSHOT on BLHELI_S ESC’s. This firmware simply references as “Jazz Maverick firmware”.

In his github repository you would find the matching firmware for your ESC and use the BLHELI_S configurator to flash this firmware - In comparison JESC came with a modified version of the BLHELI_S configurator, that allows you to chose the firmware version from within the configurator and it basically does all the work for you.

This is where BLHELI_M comes into play. BLHELI_M is now basically the official name of the “Jazz Maverick firmware” which now also has its own configurator, thus making flashing super easy.

BLHELI_M also provides a couple of features that JESC does not, namely CE (Commutation enhancement) and ESC FF (Feed Forward). Although I am not entirely sure what those features do - you would need to dig through the RCGroups post to find that out (if you do so, please let me know).

Accoridng to betaflight wiki there is only one version (16.73) that you should be using of BLHELI_M, stating that the later versions are not up to par and can result in hot motors.

One very cool thing about BLHELI_M is, that it allows changing PWM frequencies without the need to re-flash the firmware.


This one is the latest open source project aiming at providing bidirectional DSHOT and maintaining and improving BLEHLI_S. From all options, I think this one is the cleanest in regards to code: it is open source, properly maintained on github and there is an actual Readme explaining the settings.

Using it is also pretty straight forward: download the configurator and flash the ESC’s as you would do with the classic BLHELI_S configurator.

This project also aims at cleaning up the BLHELI_S codebase itself, thus simplifying firmware generation in general. Something you will appreciate a lot after looking at the original BLHELI_S source code.

Bluejay also allows for melodies to be played, similar to the startup melodies you might know from BlHeli_32 ESCs.


Firmware Open Source Telemetry MCU PWM update frequency
BLHELI_S Yes No 24kHz
JESC Partially Yes (Paid) L, H 24kHz, 48kHz, 96kHz
BLHELI_M Yes Yes L, H 24kHz, 48kHz, 96kHz
Bluejay Yes Yes L, H 24kHz, 48kHz, 96kHz

MCU is the supported ESC MCU - they come in two flavors, L and H. Initially JESC only supported the H MCU’s, but there is now also a free preview version available enabling ESC telemetry on the L MCU’s too.

L actually refers to the EFM8BB1 MCU and H to the EFM8BB2 MCU. They are both 8 Bit micro-controllers manufactured by Silabs. The BB2 is the newer version with significantly improved specs: 4 times the RAM, twice the flash size and double the clock. Most newly released BLHELI_S ESC’s use the BB2 MCU.

BlHeli vs. JESC, BlHeli_M and Bluejay

The main difference between BlHeli and all other alternative firmwares is, that BlHeli does not officially support RPM filtering. There are a couple of versions that actually do support it. Those are actually early versions of BlHeli_M.

JESC vs. Bluejay

The major difference between JESC and Bluejay is, that the RPM filtering part of JESC is closed source. Bluejay is fully open source and new features are welcome.. You also do not pay a license fee for Bluejay. To tell how exactly they implement their functionality is difficult to say since we can not look at the JESC source code.



Due to the nature of BLHELI_M being open source and thus available for free, I have now seen a couple of flight-controllers and RTF copters being flashed with it out of the box, allowing for RPM filtering without you having to do anything. So you might even be using RPM filtering right now and don’t even know it.

I am expecting to see Bluejay in the wild soon too, if it is simply for the fact that it is open source and well documented.

I have been personally using JESC on all quads that did not come with bidirectional DSHOT per default and used BLHELI_M when it was already flashed from the manufacturer. Now I will started using Bluejay instead of JESC, simply because it is open source and I quite like the project and the developer seems very involved and easy going.

Which should you use?

I have a feeling that JESC is better tested than BLEHLI_M, I also like its simplicity - you just flash it and are good to go. The website explains very well how to set it up and troubleshoot it, you basically have everything in one place. And all this convenience is it worth for me to pay a little bit for it (It’s basically one dollar per ESC if you buy a pack of 20 licenses).

On the other hand BLHELI_M has been catching up and thanks to its configurator, flashing is now easier than ever. Also if you want to have some extra features to play around with, you can definitely have that with BLHELI_M. What I don’t really like is that the BLHELI_M documentation basically happens in multiple threads on RCGroups and you have to dig through those to find out what the features actually do and to generally keep up to date - on the other hand, it is completely free, so this might be worth it to some to go through those inconveniences.

Bluejay is in my opinion the best maintained one. The maintainer is very open to suggestions, answers quickly on issues and seems to generally be a nice guy to talk to. But when it comes to firmware, this one is not yet ready for prime time, as the developer states himself. The firmware is currently at version 0.10.

I would not recommend to run it on the rigs you really “depend” on, but I would highly encourage you to give the firmware a shot and report any findings back to the project.

I am pretty sure that Bluejay will soon replace BLHELI_M on the quads that come pre-flashed with an alternative firmware, but only time will tell.

In conclusion: Go with JESC if you want something tried and tested. Go with BLHELI_M if you want it for free. And go for Bluejay to be on the bleeding edge, and want to be able to say: “I used it before it was cool.”.

Betaflight Setup

After deciding for one RPM enabled firmware and flashing it to your ESC’s the only thing left is to set it up in Betaflight. The base setup is pretty straight forward. On the “Configuration” tab enable bidirectional DSHOT. In the Motor poles field, adjust the value to your actual motor poles. You can do this by counting the magnets of your motor or read up the value in the specs of your motor. Make sure that your motor protocol is set to some version of DSHOT, I like to go with DSHOT300 - with higher versions I have experienced strange behavior on whoops.


First of all we need to ensure that the CPU load is low enough. This can be quickly done via looking at the CPU load in the Betaflight status bar. Make sure this value is way below 50%. If this is not the case, decrease the PID loop and disable all sensors that you do not need. I usually run my rigs with a PID loop of 4k/4k.

To get a more detailed view, go to the CLI and type “tasks”. Make sure that the line with Gyro/PID tells you a value that is very close to your actual set PID looptime. In this case I have set a PID loop frequency of 4k - so this checks out. Also the max load is at 69% - so we are good here.

In this screenshot on the other hand the PID loop frequency is set to 8k on the same setup and you can see, that although the although the Gyro/PID line shows us a value that is very close to the set loop frequency the max load is at 127%. This is not good and will result in errors. On setups with SPI receiver it is very likely that the receiver will start to fail since the load is simply too high.

To fix a high load, disable all sensors that you do not need. Next lower the loop time. I like to set my looptime to 4k and use DSHOT300 - this are the least problematic settings for me.

After you have verified that the load is in an acceptable area, switch to the “Motors” tab. Without having props on, plug in a battery and spin up the motors (don’t spin them up to high without a load, just high enough that they all turn without issues) - you should now see RPM values below each motor. Also check that the error rate is low - usually it should stay at 0%. A high error rate might also be an indicator of a too high load.

That is basically it - you have RPM filtering set up.

Now it is time to take your quad for a spin - the effects of the RPM filter should be noticeable immediately.

Further configuration

After RPM filters have been enabled you can start relaxing the rest of your filters. In the “PID Tuning” tab find the “Filter Settings” section. Start by moving the filter sliders to the right - after each step check that your quadcopter is flying as you would expect and the motors do not get hot. The sliders can be moved the furthest when expert mode is enabled in the configurator.

Removing too much filtering can result in the quadcopter to spin up and fly to the moon, I recommend having one finger on the disarm switch when finding the proper slider positions. I always like to move both sliders at the same time.

On most of my setups I am able to move both sliders to at least 1.5, disabling a lot of filtering.

In most cases you can also disable the second dynamic notch filter by setting “Dynamic Notch Width Percent” to zero. I personally always like to keep the first dynamic notch filter active.

If you want some good settings to start out with on different types of setups, I can highly recommend the UAV Tech’s presets.


Chris is a Vienna based software developer. In his spare time he enjoys reviewing tech gear, ripping quads of all sizes and making stuff.

Learn more about Chris, the gear he uses and follow him on social media:

Show more comments