Sully's BBSHD Programming (for people that like pedaling)

Jon Sully

15 Minutes

How to program a Bafang BBSHD to ride WITH the motor!

(For those that read my blog for other reasons, this is an article pertaining to configuring very specific parameters for a DIY electric bike conversion system)

Where to start…

There’s a lot of content available when it comes to the Bafang BBSHD. It’s been around seven or eight years now, thousands of people have programmed it hundreds of thousands of times, lots of videos, articles, and podcasts have been made about it. It’s a lot. This is my contribution to the mix. They’re still selling BBSHD’s new here in mid-2023 and it’s better late than never, right? I haven’t seen this style of programming suggested anywhere in all these years of history, so hopefully it sheds light on a new way of riding the BBSHD that someone hasn’t considered yet.

Context

Probably the biggest missing component of all the other guides to BBSHD programming that’ve popped up over the years: the context. Here’s mine.

I’m a commuter and around-town'er. My goal is to get to work and not be sweaty. Warm is okay; sweating for twenty minutes post-arrival while my body slowly cools down is not. I’m also a bigger guy. I was a college football lineman and I’m 6'3", 245lbs. Thick, if you’d be so gracious. When I’m just going around town, be it alone or with cargo or with my wife on the back, I want to enjoy the breeze, not huff and puff. My goal is to replace a vehicle with a bike, not to replace an internal-combustion engine with my thighs. These can be different things!

My vehicle is a Yuba Mundo Lux/v5. It’s an absolute workhorse of a cargo bike. It’s also huge. My goal when I bought the bike remains today: use it as a commuter when going to the office and around-town otherwise — to try and (without being overly extreme) use it as my car. Not for any particular reason other than that bikes are fun, breezes are lovely, and time outdoors (not in a car) is relaxing. Cars are stressful. Traffic is stressful. Bikes are joy.

Before I converted the bike, my focus was on keeping my power output very low while still getting to work. This resulted in a 40-45 minute ride. The path contains one longer, low-grade hill and two very short, moderate grade hills. Now, I live in Ohio… nothing’s particularly hilly. That said, when you’re trying to keep your output very low (to avoid getting sweaty) on a rig this heavy, you end up climbing hills ridiculously slow. I likely ended up getting sweaty just from staying under the summer sunshine so long. (300+lbs rig-weight ✖️ incline gradient) ➗ under-100 watts of power 🟰 SLOW. This simply wouldn’t work.

For added context, I’ve been a road cyclist for several years. A Clydesdale, sure, but a road cyclist nonetheless. I like spinning. When my legs are turning between 85-95rpm, my body is happy. That’s not to say I don’t like outputting power, rather to say that I try to keep my body efficiency high by keeping my cadence up in whatever gear best accommodates both high cadence and power for that moment. Slow cadences are the enemy.

So… enter the Bafang BBSHD. A powerhouse with totally unrealistic tuning out of the box. Tuned how I like it my commute is now 22 minutes, 15-20mph the whole way, breezy, and very low human effort. Nice!

Goal

Along with the context of who I am, my riding style, my bike, my route, and my preferences, let me explain clearly what my goal is with an electric motor on my cargo bike:

I want the motor to help me get to my ‘happy cadence’ (spinning) in whatever gear I’m in, then, once there, help me stay at that cadence… regardless of how much power I’m putting into the pedals.

Ideally the motor shouldn’t care about actual road-speed (miles per hour) or how much torque I’m physically pushing into the pedals at any given cadence. It should see that the cadence is below my ‘happy’ threshold (let’s say 85-95rpm) and kick in with a lot of power (gradually, though) to help me get that cadence up to my happy cadence. Once there, it should only add or sustain enough wattage to keep my cadence up at that happy cadence level.

For examples’ sake, remember that when we’re cruising along at a good cadence and shift up to the next gear, our cadence suddenly slows down. This makes sense mechanically, but the motor should detect that cadence drop and add a lot of power to get the cadence back up to spinning speed. This is similar to a road cyclist — once you upshift you want to get your legs back to spinning efficiency but you have to add some power to get there. Similarly, while cruising/spinning along, if you begin an incline, your cadence will naturally drop with your speed. Unless you down-shift, the incline gradient will match the cadence decay — the steeper the hill, the faster your cadence will fall. This too should kick the motor in to help you keep your cadence up.

Focusing entirely on spinning means that, similar to an acoustic bike, my actual top road-speed (mph) is dictated by what gear I’m in, not by the PAS level or other motor configuration. The motor’s job is to keep me spinning. My job is to spin and choose how fast I want to go based on which gear we’re spinning in.

I should also note that just because I’m spinning at 85-95rpm doesn’t mean I’m actually putting in much actual power. I can only hope to describe this as the amount of effort my upper thighs are outputting vs. the motion of my feet circling along with the cranks. I always want my feet and legs circling with the cranks. I don’t always activate my thighs very much to put actual power down into those circling motions.

Finally, I should note that my strongest preference in programming this motor is to avoid ghost pedaling. I do not like ghost pedaling. I want my turns of the crank to be mechanically connected to the cassette and drivetrain at all times. Aside from helping me stay connected to the motions and vibrations coming through the bike, it’s a matter of control and effort. This is why none of the existing BBSHD programming configurations I’ve found before have worked for me. I understand that the BBSHD is capable of spinning at 140-160rpm. I don’t want that.

Method

Where many folks have used a stair-case approach to both power and “speed%” and Kepler used a “full power, modulated speed%” approach, I’ve instead gone for a “locked speed%, modulated power” approach. This begins with the understanding that the “speed%” value controls the maximum motor speed, not road speed. In other words, it controls the maximum cadence the motor will spin to, not the maximum miles-per-hour the bike is going. The latter is only controlled by the global “maximum speed”/“speed limit” (depending on which config tool you use). So essentially the idea here is to keep speed% locked to a value that falls within my happy cadence, then set power pretty high since the motor output will be highly governed by the cadence and a high power limit will almost never be hit. Plus, when we up-shift and the motor kicks in to help us reach our happy cadence again, we do want quite a bit of power available for that.

Ultimately this means I could have a single PAS level: Power = 100% and Speed = 50% (assuming that 50% “Speed%” = 85rpm on the crank). Frankly that would likely work fine for the majority of riding time. Seriously, that could be it. Done. One single PAS level that you never have to futz with!

But there’s one other variable at play in practice: battery voltage. Since an electric motor’s top speed (in RPM) varies with battery voltage and battery voltages steadily (but slowly) fall with use, we probably want a few PAS levels that increase the speed% just slightly to compensate for decaying battery voltage. Hold that thought.

So after quite a bit of testing, I found that my preferred motor speed% on a 80% full battery is right at 50%. That’s the motor speed that matches my happy cadence / spinning speed. When I set the speed% to 50% and go for a ride I can spin along with the motor, never get out-cadenced (ghost pedaling), and always be connected to the drive-train myself, even though the motor might be doing most of the actual work (it might be pushing the torque through the chain, not me). 50% 🤯! That was a surprise to me. The BBSHD can really spin if you let it. For throttle users or mountain bikers, I bet that’s great. Some napkin math means 100% Speed% would be.. 170rpm on a mostly-full battery! Talk about ghost pedaling. That motor would be spinning way faster than you.

So ultimately we just need to set PAS tiers according to cadence, each with the same current limit, using very small steps in speed% to accommodate falling battery voltage. This means that the PAS level selector actually turns into a ‘preferred cadence’ selector! Unless you have a small, quick-draining battery, you’ll likely be able select a single PAS level when you get on the bike and leave it unchanged the entire ride! Super easy.

Settings

Tl;dr: “Dear BBSHD: help me get to, and stay at, my road-cycling style ‘spinning’ cadence (85-90ish rpm), and don’t spin faster than me; I want to stay mechanically connected to the drivetrain. Also, even if I’m spinning with you, I may not be adding much/any torque. That’s your job ☺️”

P.S. It was developed only within the last couple of years so you won’t find this mentioned in the older BBSHD content or guides, but there’s a web-based BBSHD configuration tool now, and it’s great. Mac, Windows, doesn’t matter. Just need to be using Edge or Chrome: https://devnotes.kymatica.com/BafangWebConfig/BafangWebCfg.html

Basic Screen

As noted above, the idea here is to limit by cadence, not power, so you’ll see the Speed% start at 49 and walk up in tiny steps. On the Current limit side, I use 77% just as a reasonable limiter for component wear and longevity. 77% current tends to mean that my peak power moments are in the 800-900 watt range, which I think is about as high as I want my cassette and chain to take. Feel free to set your current limit to 100% if you’d like. It won’t change most of the riding experience, just how quickly the motor gets you to your ‘happy cadence’ before it lets off (and how much peak power it puts into your chain).

Also as noted above, I’m targeting 50% speed for my ‘happy cadence’ then working upwards to combat battery decay as the battery energy gets used. I actually start at 49% for the rare case that I’m riding a 100% full battery and 50% is actually too fast of a cadence. This is rare. I typically get on the bike with an 80% full battery and set/leave the PAS level to 2. If the battery is getting lower (or I just want a faster cadence that day) I’ll switch to 3 or 4, but I should emphasize that switching PAS levels is rare. This is intended to be a ‘set it and forget it’ system.

Though your experience may vary with your particular system, I estimate that a single percentage difference here (e.g. speed% from 50 to 51) represents roughly 2 cadence rpm. So my 2% steps here should loosely represent 4-ish rpm cadence jumps. This works well for me!

Finally, I did go ahead and use all the PAS levels (1-8) but the reality is that unless I’m riding my battery all the way to 0% charge, I never use PAS 7, 8, or 9. It’s just very rare for me to ride my battery to that depth of discharge. I usually charge to 80% then put it back on the charger (days later) when it’s at about 30-40%.

PAS Screen

NOTE: I have a 500c display that can set a speed limit of 99, so you may hard-code that value if you are using a different display.

Start Current % being 2 and Slow-Start Mode being 4 makes for a really nice power ramp-up when the power comes in for the first time. I’ve ridden with Slow-Start Mode being 3 for plenty of time as well. I think both 3 and 4 are great, smooth-kick-in, options. Highly recommend either for city / casual riding. Setting Startup Degree to 10 in conjunction with this means that the motor won’t start until almost one half turn of the pedals. This works well for me as I often start from a complete stop by pressing down on a single pedal while I stand up into the saddle, then start pedaling. I don’t want the motor kicking in on my first shove-off!

Current Decay and Keep Current are the most important pieces for this tune. The idea is that the Speed% on the Basic screen is our main limiter / control for motor rotation speed. We therefore want as little Current Decay as possible — let the motor speed limiter handle limiting! We also don’t want to decay current early. Current shouldn’t decay until exactly when we’re at our Speed%. So we set this to 8. Keep Current, in our context, essentially represents how much current the motor should be allowed to use when we’re actively pedaling along and either a) start going up a hill, or b) you shift up a gear and the motor kicks in a lot of power to get your cadence back up. Keep Current is a limiter, not a “current will always stay at this output” value. For simplicity, I always keep this locked to the same value as my PAS levels: 77%.

Throttle Screen

I don’t use throttle with my BBSHD. If you do, feel free to set it however you’d like. It’s not the goal for this tune/bike/build.

Visualizations

To (hopefully) illustrate how this system works, I’ve drawn up a comprehensive cadence-to-power diagram which covers first push off, shifting, and climbing a hill events. Please click the following image to explore the interactive diagram. Zoom in, move around, etc.

Riding Experience

Simply put, I was really less than thrilled with the BBSHD until I got this configuration right. Now I absolutely love riding this thing. It’s extremely intuitive and better than even torque-sensing motors in some ways (I explained this here). It helps me spin all the time with (as-little-as) zero effort, does all the work for me to get back up to spinning after up-shifting (e.g. the motor does the work to make us go faster but keeps me spinning with it in the meantime), and allows me to put in as much or little torque from my own legs as I want to in any given moment. I set PAS to 2 (usually) when I start up the bike and don’t touch the controller for the rest of the ride, really! I’m just riding, spinning, and shifting gears as needed.

One thing this configuration gives is a much longer battery life. Energy can’t come from nowhere (this isn’t a magic programming configuration, I’m sorry) but I’ve been surprised by how much the range is extended by just my spinning along with the drivetrain. I’d estimate that I’m putting less than 100 watts into the pedals myself throughout the entirety of a very relaxing ride, yet outside of up-shifts and hills, the motor is typically between 50-250W output. As long as we keep spinning, the motor really isn’t doing as much as you might think! This makes the battery last so long. YMMV, of course, but on a loaded cargo bike, using this configuration, I’m fairly certain my 52V 21Ah battery will go 100 miles on a full charge.

And one nice, unexpected perk that comes with the above is that we don’t need shift sensors! I do like them, but I never got around to installing mine. Now I don’t need to! When I shift, I just wait until the motor gets us up to spinning speed and the power output drops into that 50-250W range. From there, I can feel free to shift again! 50-250W is a totally normal human wattage that bike drive-trains are very much able to shift under without damage or stress. The shift will sound very normal and acoustic-bike-like. Then, as soon as the shift completes, the motor will realize that the cadence has suddenly dropped and kick in a lot of power to bring the cadence back up. This is fine because the chain is already full seated on the new cog. Then, once that happy cadence is reached, the power will drop off and we can shift again. Rinse and repeat! No shift sensor required.

Now, I have a 500c display that shows real-time wattage outputs, but I learned within a few rides to hear and feel when we hit that ‘spinning’ / low-power phase. You’ll quickly sense both that the pedals are moving as fast as you want them to and that the motor has let off its push since you got to spinning speed. If you don’t have a display that can show you real time power levels, just learn to feel this and you’ll be able to shift without a shift sensor as well.

2024 Edit: I did end up settling on using a push-button motor kill-switch on my rig (like the following image). JohnnyNerdOut sells one with the cable pre-terminated for the BBSHD/BBS02 system for $9. I recommend that! I essentially just tap the button any time I shift and it ensures that as few watts as possible are going into the chain when it moves. The motor kicks back in after just a moment in the new gear. It’s also handy when navigating around slow moments and not wanting any motor. It’s great!

So that’s it! That’s how I program and ride my BBSHD. It’s exactly what I wanted and works 100% for my needs. I highly recommend giving it a shot if you like keeping a good pedaling cadence (regardless of actual torque output) and being connected to your drivetrain at all times while riding (down with ghost pedaling)!


Changelog

  • 8/19/23
    • Updated PAS 1-8 with lower Current% (from 85% to 77%)
    • Two reasons. First, general motor longevity. Second, when switching to a higher gear and the motor kicks in strongly to bring cadence back up, I wanted it to peak lower. I don’t like seeing much in the 900W’s or 800W’s on my screen, so this keeps those peaks down in the 700W’s and 800W’s typically. This will make my chain, cassette, and motor all last much longer and has virtually no noticeable difference.
    • Updated PAS levels to use all 1-9
    • #9 is dedicated for throttle in the rare cases that I do use a throttle (now explained above)
    • #1-8 are just linear steps now, as I found that higher PAS levels (higher Speed%) may actually be useful when the battery is getting very low. In that “only 10-15% of my battery charge remaining” state, those higher Speed%‘s do map to good cadence levels. It’s just rare that I ever ride the battery that deep.
  • 3/10/24
    • Fixed broken images — not sure why they broke before but rebuilt and reuploaded new images across the board
    • Added note about now using the motor cutoff button
    • Pulled out the notes about using a throttle. I only used a throttle with the BBSHD for maybe a week — didn’t like it.

Comments? Thoughts?

Jasper Greve

Hi, thank you for this! Previously I had a TSZD2b with a torque sensor which always cut out before I reached my prefered cadence (90-95 rpm) I’m now interested in trying out a BBS of some sort. One question though: When you set “Speedmeter Model” to “External” doesn’t that refer to the wheel speed sensor? And isn’t it trying to to help till you reach a certain wheel speed rather then cadence?

Jon Sully (Author)

Hey! Thanks for the comment :)

Yes, setting the speedmeter to ‘external’ tells it to interpret the speed sensor’s input as magnet passes (which come from the magnet on the spokes). And that data does indeed compute out to become road speed. But unless you’re hitting your global maximum road speed limit (which should be set to 99kph, so… you’re not), that data is only used to show you your current road speed on the display, not to limit the motor in any way. This programming essentially globally limits power to 77% for the sake of longevity and components (though feel free to go with 100% if you’d like!) but the real control is that Speed%, which is in cadence/rpm.

Jasper Greve

Jon, Thank you! That explains it!

Willie Rip

Are there a few screen settings missing in this blog post? It seems there were many more graphs and charts explaining things. I keep getting “GATSBY_EMPTY_ALT” where there used to be charts and graphs.

Best regards, Damon

Jon Sully (Author)

Greetings! Apologies for the delay here, but just wanted to give you a heads up that the images in this post have since been restored. Hope they help!

Allen

Jon, first thanks for all the information it’s been helpful. Programming my bbs02 performs just like you said. Increases cadence when shifting up. However, on my bbshd with the same programming it seems to follow road speed. For example: If my global speed limit is 20 mph, and my %speed is 50 my bike will do aprox 10 mph no matter what gear I"m in. So an upshift causes the cadence to slow and it maintains 10 mph. Same thing for different assist levels. Not sure why, or if I’m missing something, but those are my results.

Reply

Please note: spam comments happen a lot. All submitted comments are run through OpenAI to detect and block spam.