Applied Tuning in KTM 790/890 ECUs


Into the weeds of tuning – because of our steadfast commitment to ignoring the emotional part of the vehicle / operator relationship, it’s very easy to end up making something that tricks our brain into feeling fast but isn’t actually fast. A giant hit of power feels fast, but requires the rider to think about and manage the bike effectively changing the amount of power going to the ground even though they might be maintaining the same throttle position.

As an example – I’ve been lucky enough to ride some of the old turbocharged bikes from the 80s and they were the best demonstration of this (see also: the widowmaker generations of Porsche 911s). The CX650 Turbo was as fast as the ZZR1200 I was riding at the time in a straight line to about 110mph, but the amount of work, focus, and concentration to make it hustle at the same pace up a twisty road was orders of magnitudes more. You’d approach the apex, and need to add throttle extremely early to get the bike to start building boost to get out of the corner, far, far earlier than you would with a traditional motor. But once boost started building, you’d have to back off the throttle as the boost increased power output at the same throttle position. Those bikes ran skinny tires, so keeping the bike adding power progressively as you reduced lean angle up might require you to go from 75% throttle to 45% throttle as it comes on boost, and then back to 75% to keep it accelerating progressively on corner exit. You had to predict the boost you were going to gain on the gas, and manage the increase in engine output proactively. Because boost was changed by throttle application over time creating exhaust velocity to spool the turbo, not directly controlled by the throttle, but influenced the output of the throttle, you were managing a complex, multi-variable system via only one input to get a progressive application of power to the ground. This will be important later, as we talk about how modern ECUs solve this problem for you. Boosted motors benefit even more from modern ECU designs, but NA motors still benefit and are influenced by the technology developed to handle the complexity of boosted applications.

The core principle here is this: Power that you can not put to the ground is power that is wasted. It can be wasted because you can’t easily put the power to the ground due to inconsistent throttle response, as in the CX650 Turbo demonstrates, or it can be wasted because you do not have the precision to balance holding the bike at the very limit of available rear tire grip, as the old 500cc 2 stroke GP bikes would demonstrate, by flicking their riders off the highside when they went on the pipe.

So: The goal of tuning, in my opinion, is to make power outputs predictable, then maximize available power output. You need the bike to respond consistently so you can maximize drive off the corner while you are in the danger zone of high levels of lean and high levels of throttle application.  This has been a lot of words, so here’s a more tangible example:

You can hear the shift at :02 that takes place effectively at the apex of the last corner, which is comfortable due to two factors: The quality of the KTM quickshifter, and the confidence that being one gear up won’t create an uncontrolled burst of power.  It’s a relatively gentle turn, but you are putting a lot of inputs into the bike to get it to change direction, and an unanticipated burst of power could cause a slide or unbalance the suspension, causing you to lose drive or induce instability.

So how do we make that happen?

In the old days, we had carburetors, and tuning for those systems was somewhat different – the fuel metering available from a carb was dependent on a large number of factors that couldn’t be controlled by the carb itself. I’ll assume a carb with a throttle cable directly to the slide here for simplicity, which were treasured because they offer very direct throttle feel. Lectron / Smartcarb are examples of modern carbs like this. The rider can change the settings on the carb, but once it is set, you cannot change it live, and the only control the rider has is the throttle. Given a specific vacuum through the intake and slide position, the carb will always respond with the same amount of fuel.

On the flip side, using the KTM ECU as an example, it has a plethora of sensors:

  • Air temperature sensors
  • Manifold Air Pressure sensors
  • Throttle plate angle sensors
  • Knock sensors
  • RPM sensors
  • Throttle sensors
  • Lambda sensors
  • (and more!)

The KTM ECU also has complete control over the following:

  • Throttle plate position
  • Injection timing
  • Ignition timing
  • (and more!)

This enables a much more complex but powerful control over the power output characteristics of the motor. If we reduce an ICE motor to an air pump, then you can determine the ideal operating characteristics of the motor by understanding how much air it can take in at a given RPM (Volumetric Efficiency map) and intake pressure(Manifold Air Pressure sensor), and that tells you how much fuel should be injected to burn at a specified air fuel ratio, which when combined with a spark table and other environmental factors (air temperature, altitude, etc), means the ECU can model how much torque the motor puts out. This has multiple major benefits – you can manage places where the motor doesn’t run particularly efficiently by adding a bit more throttle to compensate at anything below 100% power output, you can back the torque output of the motor off at an appropriate rate if a rider suddenly loses traction, you can precisely output enough torque to unload the transmission with an autoblip downshift but not cause the bike to lurch, and you can make sure that if the rider asks for 20% throttle they get a consistent torque output, regardless of the conditions. You can also compensate in an extremely specific, accurate way for boundary conditions like going from closed throttle to pinned that a more basic system like a carburetor would struggle with, or wear on the engine over time (via monitoring charge burn via lambda) to validate the engine is operating as intended. You can also take action to save the motor if it begins to knock, reduce harm to the motor if it is pinned while unloaded or in neutral, and a variety of other things that aren’t possible in a system where fuel is metered strictly by the throttle slide and vacuum characteristics.

But I thought this was about tuning?

If we’re not just gonna throw shit at a wall and see what sticks, we have to actually understand what we are tuning. This ain’t just throwing jets in a hole, my dude, this is precision binary engineering.

So if you’ve built this complex ECU, with all these variables to manage, you have to have a way to interact with them. After all, as my initial post said, the ECUs themselves are generic until they’re programmed, so understanding how the ECU processes each of the available sensors and then reacts is critical to actually having some control over the motor. This is done in the ECU by a combination of flags (ie, should the O2 sensors be on or not), and lookup maps. Those maps look like this in raw memory:

Which – to be honest, isn’t very useful. But it’s useful to understand that the maps get flattened into memory. If you do some normalization on them, mapping the memory values into something more human parseable, you get something closer to this:

This specific map describes the relationship between RPM and throttle, and the expected amount of air in kg/h that the motor will ingest as a result. It can be sometimes useful to represent these in 3 dimensions to better understand the nature of how the system interact:

The small dot you see represents that at 6500 RPM and 39.99% throttle, with the lookup value being 74.62 kg/h of air. From reading the throttle sensor, the RPM sensor, the motor can now know how much air is processed, and it can infer how much fuel should be injected to start. That brings in a starting point, and then from there the ECU determine if it needs to apply additional fuel trim based on the Lambda sensors reporting how much oxygen remains in the exhaust:

Those trim maps over the top of that to compensate for changes atmospheric conditions, wear, ethanol in fuel, etc.

You’ll discover as you dig into these maps that there’s a lot of inferences that may or may not be correct – after all, you’re basically looking at the shape of the map in 3 dimensions and trying to match it to what makes sense in terms of shape for what the map itself does. This map is called “normal lambda for component protection”, but I believe it’s a lambda target map, so the ECU uses this in combination to validate feedback from the O2 sensors on each header and then dials in fuel trim accordingly. Too much trim will usually cause an error, as it indicates something is operating out of expected values – so it’s important to baseline appropriately, so you don’t over-rely on the trim tables to fix your fueling.

Okay, NOW can we start tuning?

I thought you’d never ask! Once we’ve determined what type of maps we have, we’ve got a few goals. While many people think that air/fuel ratios make power, A/F ratios actually mostly make safety, not power. HPTuners does a lot of excellent work, and they have a great YT video where they show how a motor with only AF changes has different outputs on the dyno:

You can see here that as long as Lambda is somewhere between .87 and 1.0 or so, it makes basically the same power. The difference is the additional fuel will help with cooling, and avoiding detonation, especially on boosted motors. If you’re looking for “Rich Best Torque”, you’ll probably find it about .87, if you’re looking for Lean Best Torque, you’ll probably find it around .97.

So there’s a few things here. Although I haven’t talked about the VE tables (oh yes, there is more here), you can kinda hack around the fact that motors will default to lean tuning by adjusting the values of Kg/h of air processed to tell the ECU that more air is coming in, and then adjusting the lambda targets to get the ECU to avoid tuning out the richer default to a leaner target. It also gives you the flexibility to have dramatically different setups for lean cruise, which is how bikes like my 1290 SuperDuke could get ~60mpg under light cruise, while still making 160hp when full throttle – the ECU can have dramatically different values for different load and usage conditions, unlike a carb. It can also correct within reason for changes away from the baseline, which is why you can get check engine lights – the engine is expecting a certain set of values within a certain range, and discovering that the readouts are not matching expected values.

First step is to make sure that the motor operates consistently and reliably, and safely. We’ll first make the basic injection a bit richer by adding a 5% change mostly across the board, as i’ve modified the exhaust and intake on this bike:

I also did some smoothing to help clean things up a bit.

Then we need to adjust the Lambda values, because we don’t want the ECU tuning out my changes, so we’ll modify the values listed above to this:

You can see that I’ve broadly moved the values towards .90. I could have run them a bit richer, but this is already quite a bit richer than before, and anything in the lower ranges is still pretty safe for my use case. I might adjust even farther into the rich range for many of those values, but I’m sure this is pretty safe, and avoiding large swings in values means the motor will run more consistently, and consistency is predictability.

So how do we know this was a good change?

The blue run is the original run before these changes, and the red run is after the changes – more importantly, there’s no piggyback unit – the ECU will always attempt to tune back to these values. Back to back runs showed this:

Predictability – although I’d still like to clean it up just a bit more.

Now that you’ve got a predictable, safe AF ratio, that you can trust the bike will maintain independently, you can start tuning for power, via adjusting ignition. It’s pretty much the same routine with ignition – identify which maps control ignition timing in the areas you want to adjust, adjust ignition within safe boundaries for reasonable power, and test and validate your changes are actually leading to more power and are applied consistently.

There’s also some other details around things like throttle -> torque maps that will interact with this – you can make the bike run better, but if the ecu is programmed to never give you more than a specific amount of torque, it will actually back the throttle off as the motor has already hit the effective target. Piggybacks fix this by just messing with the signals at the injector, but you’re always gonna be fighting with the closed loop systems. Adjusting the closed loop values means the closed loop corrects automatically to where you want it to be, but does require you to do a bit more work. On the flip side, the ECU will never undo your changes, as it will always try to shoot for your values. Okay, that’s enough for today! Here’s a few useful resources for folks who want to go down this rabbit hole themselves:

How to use/ identify maps in WinOLS:

HP Tuners A/F HP

A final note here – I have seen some godawful maps from tuners – massive swings in spark values, maps that barely ran but the ECU valiantly compensated for, creating “power” by just making the throttle response completely abrupt. When you’re modifying an ECU like this, take some time to understand what the tuner is actually changing, and if it can’t be validated meaningfully, I’d encourage you to take it to another dyno tuner and get a quick a/f sample run. There’s also the question of if the tuner actually correctly managed and compensated for closed loop corrections – nothing like the tune running great on the dyno and then the ECU happily tuning it all out over the first 20 miles away from the dyno shop. Not to mention piggyback units failing, and the plethora of other woes that can show up with tuning. If they can’t explain what they’re doing, how it might fail, and how they compensate for that…maybe find another tuner.

,