Using Zwift With Nearly Any Fitness Device




About: I am always young, because i feel so!

On Zwift the best results are with a Power Meter.

But what when you have no Bicycle with Power Meter, or no High Expensive Standalone Trainer?

With this Instructable you are able to Running / Driving on Zwift with virtual Data from a Power Table.

The most cheap Trainer have this table in the manual. If you dont have the manual anymore, google can help you to find it. Just search with "manual" + your Training device. Without this table you cant use my Instructable.

See the example:

Step 1: What You Need

An Ergometer or Elliptical Trainer works good. If you have a rowing device with flywheel, then it should work, too.

2x ANT+ Stick *I use Garmin and a noName Ebay Link

1x Raspberry PI 2 or 3 All in package

Some 4.7K Resistors Resistors

Some 50K Resistors Resistors

1x Magnet (I use a cube neodym)

1x reed Switch (fast) KSK 1A87

1x connector/ terminal strip (4 ports are good) Terminal Strip

Some Wires / Dupont connectors Cableset

A piece of PCB *optional PCB

A PC or Laptop / MAC for Zwift Software To Zwift

For your Fitness Device you have 2 Options:

Open the Display an place a cable parallel to the switches for the level + -

Or place a foil switch over your switches.

I use the 1 Option. The second works too.

Be sure what you do! If you are not familiar with wiring and soldering then someone should help you!

Step 2: Hard and Soft Lets Do Some Nerd Stuff

Place the Terminal strip with power glue on the chassis of the fitness device.

Carefully put the reed switch in your terminal strip (It is Glass) From the terminal let 2 wires out 1-2 meter are fine. On the moving round plate(flywheel) place the magnet with power glue. (I use a neodym magnet). Check that the reed contact closes when the magnet pass the reed switch (You hear a click).

Install for the Raspberry PI a actuality debian jessie: Full Image

Raspberry PI Download

Do not connect any wires to your Raspberry PI yet.

Put 1 ANT+ Stick in the Raspberry PI and boot your PI

Step 3: The Software Part

install some stuff:

sudo apt-get update

sudo apt-get upgrade

you do grab a coffee * :)

sudo apt-get install mc (I use mc often)

sudo apt-get install git

you will clone this rep:

git clone

install some more stuff :)

sudo apt install libudev-dev

sudo apt-get install nodejs npm

sudo npm install -g typings

sudo npm install -g typescript

cd ant-cycling-power

sudo typings install

sudo npm install

If you fail put a sudo before the installer command. If you have issues follow the instructions on:

test it with "sudo node test.js" You need to see an output! If not you have an issue.

I try to help, ask here.

When you seeing an output with power and cadence go on:

if you are not there:

cd ant-cycling-power

sudo npm install rpi-gpio

clone my git in your ant-cycling-power:

git clone

copy SpeedMeter.js and test.js

in ant-cycling-power

My table have 16 Level and example for 24 Levels is also included.

If the values are not yours open the SpeedMeter.js and correct the table for your needs.

Many Thanks for helping me with the code goes to tsseh from

Shutdown your PI and remove the power supply.

Step 4: The Hard Hardwarepart

Wire up (Do not make a Chaos like me in the 1 Picture!) :) :

Connect to GPIO 20(PIN 38) and 21(PIN 40) the Switch lines the reed goes to GPIO 4 (PIN 7)

How i did connect the switches:

From (Pin1 3.3V) --> 4.7K Resistor --> to Level Switch Training Device.

From Training Device Level+ output Wire --> to GPIO20 from GPIO20 --> 50K Resistor --> Ground

From Training Device Level- output Wire --> to GPIO21 from GPIO21 --> 50K Resistor --> Ground

You need to put a voltage divider, if you use the open Display Version, because the output voltage on my device are 5.5Volt.

My Voltage divider from GND to a 10k Resistor, from the 10k Resistor to a (10k and 4,7k parallel) Resistors.

Lazy Version:

The ReedSwitch: GPIO4 --> to reed Switch, from reed Switch to Ground. Check twice! All correct placed? No short circuit?


Step 5: Lets Test It. and Do Not Doubt Yourself...

Turn on your PC and install Zwift with the second ANT+ Stick. (may be you need to install driver for the Stick)

Check if the ANT+ Stick working on PC see the ANT+ icon upper left in Zwift. Working?

OK start your Rapsberry PI and login

then go to directoy:

cd /ant-cycling-power

sudo node test.js

your output should be Power 0w Cadence 0rpm

let the console running and start pedaling / walking The power and rpm should have values now.

OK Go to Zwift and pair your new power meter and cadence You should see them now in Zwift pair Window!

Make sure that PC Windows ANT+ device and Raspberry PI ANT+ Device close together, 1-2 Meter i wrote above :)

Congrats you have a cheap accurate cadence and power meter to ride in Zwift what is also usable for Intervall Training.

do not cheating! Cheating makes you small and you lie to yourself.

Ride on!

Step 6: Troubleshooting...

When you plug in a USB-m ANT+ stick, the default permissions are for only root to get access to it:

$ node test.js /home/pi/ant-plus/node_modules/usb/usb.js:33 this.__open() ^

Error: LIBUSB_ERROR_ACCESS at Error (native) at (/home/pi/ant-plus/node_modules/usb/usb.js:33:7)

We can fix this by changing udev settings, for Garmin v1 and v2 sticks:

$ cat /etc/udev/rules.d/51-garmin-usb.rules SUBSYSTEM=="usb", ATTRS{idVendor}=="0fcf", ATTRS{idProduct}=="1009", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1" SUBSYSTEM=="usb", ATTRS{idVendor}=="0fcf", ATTRS{idProduct}=="1008", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1"

And reload udev rules: $ sudo udevadm control --reload-rules

In power-meter.js change:

stick.write(Ant.Messages.setPeriod(channel, 8182)); to

stick.write(Ant.Messages.setPeriod(channel, 4096)); // (Hz

This should reduce the drop outs to 1%

if you have still problems with radio, make sure that the both stick see each other to stable the signal.

If you have power freezes, because you have NaN values in console logout update the test.js to the latest version

Good Luck!



  • 1 Hour Challenge

    1 Hour Challenge
  • Fandom Contest

    Fandom Contest
  • Frozen Treats Challenge

    Frozen Treats Challenge

16 Discussions


Question 4 weeks ago on Step 2

Hello All,

i'm trying to put this project in place too
Using a raspberry 3b+ with Debian Raspian installed.

Following the instructions i get in trouble

When using:
sudo npm install -g typings
i get two warnings:
npm WARN deprecated typings@2.1.1: Typings is deprecated in favor of NPM @types -- see README for more information
npm WARN deprecated popsicle-proxy-agent@3.0.0: Use `agent` option with `popsicle` directly

then using: sudo typings install
and iḿ in big trouble:
typings WARN enoent Path "/root/ant-cycling-power/typings.json" is missing

I have no idea to solve this - can somebody provide me a solution to this missing file?

Thx in Advance


5 months ago

Hello All,

I am trying to put the project in place, thanks for all the code that's really useful.
I encountered some issue also with the Message object not properly defined but the solution provided in the comments is working.

Now I am facing another issue, I did implement the Lazy version: just connecting the sensor to GPIO 4 and GRD. When lauching the script i get : RPM (xxxxxxx) out of range. I believe it is coming from the speed meter.js as IdxUpper is above 12 but i am not sure what is this valiue suposed to represent.

thanks for your help,


Question 5 months ago on Step 4

Sudo npm Install
Error git Clone Permission denied
Konnte nicht lesen
Does it exists ?


Question 1 year ago

I have problems with the code and libraries. I hope you can guide me to the source of the issue, please.

I'm using a CYCPLUS U1 usb ant+ stick on a Raspberry Pi 3, and latest Raspbian version and updates.

Installed node.js 8.1.1 with these lines:
sudo su -
apt-get remove nodered -y
apt-get remove nodejs nodejs-legacy -y
apt-get remove npm -y # if you installed npm
curl -sL | sudo bash -
apt-get install nodejs -y
node -v
npm -v

Then I copied the code to my raspberry pi 3:
1) Cloned ant-cycling-power
2) Copied SpeedMeter.js into that folder.
3) npm install rpi-gpio
4) npm link rpi-gpio
5) npm install ant-plus
6) npm link ant-plus
7) Finally, I run sudo node test.js

My errors are this:

pi@raspberrypi:~/ant-cycling-power $ sudo node test.js
Max channels: 8
stick.write(Ant.Messages.assignChannel(channel, 'transmit'));

TypeError: Cannot read property 'assignChannel' of undefined
at GarminStick2.<anonymous> (/home/pi/ant-cycling-power/power-meter.js:15:30)
at emitOne (events.js:116:13)
at GarminStick2.emit (events.js:211:7)
at (/home/pi/.nvm/versions/node/v8.11.1/lib/node_modules/ant-plus/build/ant.js:527:18)
at InEndpoint.<anonymous> (/home/pi/.nvm/versions/node/v8.11.1/lib/node_modules/ant-plus/build/ant.js:374:23)
at emitOne (events.js:116:13)
at InEndpoint.emit (events.js:211:7)
at Transfer.transferDone (/home/pi/.nvm/versions/node/v8.11.1/lib/node_modules/ant-plus/node_modules/usb/usb.js:328:9)

I tried to investigate, but I cannot figure this out. :-(

2 answers

Answer 1 year ago

Hi, I solved the problem. This error was because of a bug in ant-plus.js missing this line in the module.exports = { } block:

Messages: Ant.Messages,

There were other specific setup stuff I had to do differently than this document, so a little later I will send you the suggested corrections.


Question 1 year ago

Hi, Andreas. Thanks. I made this project recently (thanks to you), however I struggled with understanding your English and grammar. I request your permission to re-write the instructions, diagrams, and code, or your permission for me to publish a new version this document while giving credit to you?
I found there are some key things in this document that should be a lot more clear and specific. Fortunately I was able to overcome obstacles through intuition and some experience, but other people might not have success without clarification and better words and pictures. I also modified the code a little. I'm also hoping to add support for automatically changing the level based on the the % grade incline of the road if possible.
Please let me know. Thanks! :-)

1 answer

Question 1 year ago

What voltage should I see on a voltmeter after I used the voltage divider circuit? In your case, you say you need it because your Elliptical machine's voltage is 5.5v. So what voltage are you hoping to have by "dividing" it?

1 answer

Answer 1 year ago

My output of the trainer gives 5.5 V to the gpios, i dont know why. So i have to reduce the voltage below 3.3V to not kill the gpio ports.

When you see under 3.3V you are good to go. If you see 0 is also good :)


Question 1 year ago on Step 3

Hallo Andreas,

ich bekomme folgende Warnmeldung:

typings is deprecated in favor of npm @types (sudo npm install -g typings).

Habe ich mit Rasphian stretch und jessie versucht.

Da ich sehr an deinem Projekt interessiert bin bitte ich um Hilfe.

Was kann ich tun ?

Vielen Dank



1 year ago

Amazing! Have you thought about building a system to control fan speed according to ant + sensors like speed and power? Would be amazing!

4 replies

Reply 1 year ago

For a bit win resistance, nice idea, but in indoor the eyes running fast dry.

I have a fan behind/side of me, makes me not faster :)


Reply 1 year ago

Nice project Andreas. Do you happen to know how Zwift works with a load adjustable trainer? I'm thinking of adding a variable load device to my trainer, and so that Swift can alter the loading (via ant+ & raspberry pi). Do you think your project would make a good basis for this idea?


Reply 1 year ago

you need to read the values from zwift, i have no idea to do this. But for a start it could help.


Reply 1 year ago

Something like this?