For the last 6 years I have been running on a NordicTrack C1750 treadmill. This is a great machine: sturdy, powerful, quiet and has an amazing ventilation system. Its weak point is the software: buggy, slow to boot and, worst of all, with basic features (such as customized programs) blocked behind a monthly iFit subscription.
Since the treadmill is now out of extended warranty I’ve decided to take a stab at replacing the software with my own. Hacking the on-board computer was not a real option, as I have no access to any technical information on it. Instead, I chose to replace it with a Raspberry Pi 4 running QNX.
Controlling the Treadmill
Luckily, almost all treadmills are controlled by a few standard boards for which there is enough information to get started. Mine has an MC1648 model, which is pretty much the same as the more common MC2100. Note that the control board is separate from the console computer. The board is located at the head of the running deck and is responsible for powering and controlling both the belt motor and the incline motor. It also provides power to the on-board computer, which is housed in the central console, next to the touch screen. A header on the control board is used for connecting it to the computer via a multi-wire cable running through one of the arms holding the central console. These wires are (in order):
- 12v (for powering the console electronics)
- Speed sensor (output to the computer)
- PWM for controlling the speed (input to the controller)
- Incline up (input)
- Incline down (input)
- Incline sensor (output)
The motor speed is determined by a 20Hz PWM signal fed into the control board. When using the Raspberry Pi PWM generator it is important to select the M/S option to get a proper square wave at 20Hz, and not the default PWM option that is more adequate for simulating an analogue signal. To determine the PWM duty cycle values for various speeds I experimented by measuring the length of the belt, marking a white line on it, and then using an IR LED and receiver as a speedometer. This setup proved to be adequate for testing, but did not work properly once I tried running, due to what appears to be electrical interference that I couldn’t fix.
As mentioned above the header connected to the computer does have a speed sensor line. However, as it turns out, there is no speed sensor connected to the board. A two pin header for a sensor exists but is not in use. I connected a reed switch to that header and put a little magnet on the belt roller. The speed sensor wire is then connected to a pull-up GPIO on the Raspberry Pi, and the GPIO interrupt is used to calculate the speed and running distance, based on the circumference of the roller. I made sure that the values calculated for speed and distance matched those reported by the original software.
The incline motor is simple to control, with two output GPIOs connected to the two wires coming from the control board. Setting each of these to high causes the motor to tilt the running deck in the appropriate direction. An input GPIO is connected to the incline sensor from the control board and counts high/low transitions, with 5 of these to each degree (a value I read in a forum post and seems to be good enough).
As mentioned above, the ventilation system on this treadmill is one of its strongest points. There is a central fan under the console, and two fans on each side of it. I had no information on these and had to guess.
The central fan is connected via three wires, black, red and blue. I assumed these are ground, 12v and PWM, and that works. The blue wire is connected to a GPIO that uses a different PWM channel from the one used for controlling the speed (you don’t want to mix the two). However, as both channels are driven by the same clock I ended up using 20Hz for the fan as well, albeit in PWM rather than M/S mode.
The side fans only have two wires connecting each – ground and power. I tried different voltages and settled on 5v. Measuring the current shows that the fans draw 300mA at that voltage. Using a 2N2222 NPN transistor with a gain value of 160 and a 1.8Kohm resistor allows these fans to be turned on and off.
Connecting the Raspberry Pi
The Raspbery Pi is normally powered by a 5v power supply with a current rating of 3A (assuming you want to connect anything substantial to it). The power line from the control board supplies 12v, which is then reduced to 5v using a DC-DC converter.
I purchased a 7 inch touch screen display (same size as the original one) which is connected to the Raspberry Pi with an HDMI cable and a USB cable. The latter is used both to power the display and to deliver touch events.
While my original goal was to keep the existing electronics in place just in case I have to revert to these, this proved to be untenable due to space restrictions inside the console. I removed the existing on-board computer and screen and replaced with my own.
Quite a few wires are left over from the original setup. In particular the ribbon cables used to connect the console buttons, and which my implementation does not use, are still there and are tucked under the plywood board holding the Raspberry Pi and the power module.
The Raspberry Pi is running a pre-release version of QNX, though can be adapted to running the latest released version (7.1). The treadmill is controlled by a driver implemented as a resource manager, which registers itself under
/dev/treadmill. The treadmill can thus be controlled by issuing commands to the device, e.g.
# echo speed:100 > /dev/treadmill # echo inc:4 > /dev/treadmill # echo fan:3 > /dev/treadmill
For those who, for one reason or another, shy from opening a terminal and entering commands while running, the screen displays a web-based touch UI (Update: I have since switched to a Qt6-based UI. See below for details). The UI consists of information on the run (speed, time, distance) and has buttons to change the speed and incline level, to turn on the fans to one of three speeds, to pause/resume a run, and, one of the features I wish the original software had, to turn off the time and distance dials (too much agony in accidentally looking at these and realizing it’s only been a quarter of the run). While I’m not a fan of browser-based user interface, I chose this route as I plan on replicating one of the paid features of the original software, which is to plot a course based on a map, with images of the view and the incline adjusting based on real-world data.
The code is available here: https://gitlab.com/elahav/treadmill
- Raspberry Pi 4B These are hard to come by these days, but can be substituted by almost any small, single-board computer (Jetson Nano, Beagle IA-64, Pine RockPro, etc.)
- LCD touch display. This is the one I used, but there are countless alternatives. The size will also depend on the treadmill model and whether you want to mount it internally or not (see below).
- DC-DC Buck converter (many alternatives)
- MTA-100 connection plugs: 8 positions for the control-board connector and 3 positions for the fan. Note that these require a special and quite expensive tool to crimp the wires, but as I don’t have one I simply soldered the wires to the connector (carefully!) and it worked just fine.
- 2N2222 transistor and 1.8KOhm 1/4W resistor for the side fans (optional)
- Assorted wires. I used mainly 24AWS gauge
See here for the GPIOs used on the Raspberry Pi. The first 5 should should match the wires coming out of the control board listed under “Controlling the treadmill”: https://gitlab.com/elahav/treadmill/-/blob/master/controller/treadmill.h#L39. GPIO_FAN_PWM is connected to the blue wire from the 3-pin connector mentioned above under “Fans”. GPIO_FAN_SIDE is connected to the base of the transistor.
It is not necessary to open the console, remove the existing board and screen and mount the new ones instead. I only did that out of a sense of completeness and for aesthetics. My original prototype had the RaspberryPi mounted on the back of the frame and the display just sitting on the console. As the pictures show this works just fine, with the exception of the side fans that have no external connection.
The original web-based UI turned out to be too limiting, and the browser itself (based on Google’s Chrome) is a behemoth that takes too long to start. To replace this I wrote a Qt6-based application. Boot time is better now, the application looks great and it took just a day to develop from scratch:
Switching to Qt also made it easy to add programs, which are simple text files read by the application and used to control the run:
The code for the application is available here: https://gitlab.com/elahav/treadmill/-/tree/master/qt