First calibration attempts

There are two modes that will need to be supported, slope and ergo. I’ve been concentrating on slope mode so far, and have it successfully working with Golden Cheetah following a course file (although not well calibrated against reality).


As you may expect, slope mode is used to match a specific gradient. This gradient could be set either manually or from a Computrainer course (.crs) file.

My initial thought had been to simply find a resistance level that matched a given gradient, without worrying about the realtime power & speed data. However (and obviously with hindsight), the power curve for the mag trainer is fairly linear, and so won’t match a curve from the real world where wind resistance increases exponentially. So to be more lifelike, the resistance level will need to be based on both the selected gradient and the current speed.

As we can only control the resistance down to it’s minimum level, and not actually apply any power like a fully electronic trainer might, I’m expecting to be quite limited in simulating downhills. I suspect we’ll get to minimum resistance quite quickly as we drop below 0% gradient.


In ergo mode, we need to hold the rider to a specific power output – regardless of speed & gearing. For instance, at a given power output we could be turning over a big gear against a lower resistance, or a smaller gear against a higher resistance.

In this mode we can expect the applied resistance level to be reduced as the speed rises, and increased as speed drops (until we reach a cut-off speed where we’ll drop the resistance to the minimum level).

Calibration process

In order to set the required resistance levels, I’m attempting to build a three dimensional model, with speed on the x-axis,  power on the y-axis, and the resistance required to hold that state on the z-axis.

My starting point was power data based on the graphs from the tacx website. (It’s worth noting up front that this data does not correlate particularly closely to my own PowerTap measurements, so I’ll be following up with some more manual calibration sessions).tacx_curves

Others have already calculated the curves for each resistance level, so using the formula for each level, I was able to populate a speed/power/resistance table (initially using a speed range of 10-60kph in increments of 5kph, at all ten standard resistance levels).

The next question is then how to ‘fill in the gaps’ between the points in the table. I think there are two options. (1) Use a 3D curve/surface fitting program to give us a formula for estimating the z-axis value for any given x & y axis values. (2) Index directly into this table, using the current speed and power, and interpolate between the bounding resistance values.

Future Improvements

To keep things moving at this stage, I’m just hard coding the calibration for both modes. However, to make this more flexible in the future, I plan to move towards a PC based calibration routine, with the calibration output uploaded to the microcontroller at runtime.

As well as speed, we’re also receiving the realtime power data, which could potentially be further used to trim the estimated load. However, this will be something for a later day once the basics are in place!

Next post

I expect to be working on the calculations to estimate power for a given speed & slope, and for mapping power & speed to a resistance level.