Introduction: Zwift Capable Pedal Generator
I've been using a pedal generator for a few years now during the winter months, but this year decided to sign up with Zwift and see if I could integrate my pedal generator with Zwift. This Instructable will show how I tied my pedal generator and a charge controller to Zwift using an Arduino Nano 33 IoT. Zwift now controls the wattage (resistance) through the Arduino using the Bluetooth Low Energy Fitness Machine Service.
Some history first... I initially built the Zwift integration Arduino code using the Cycle Power Service, and was able to report the wattage to Zwift this way. A good first step, but was not the "full experience" of Zwift. I stumbled upon a blog post where Luke shows how to control a DPSxxxx controller using a modbus library with an Arduino. "Eureka!!!", I thought - this is how I can control the wattage. I bought a DPS5020 and reworked my code to use the BLE Cycle Power Service and the Fitness Machine Service, and actually had a working version that controlled the resistance while training on Zwift! Yay! A few days later as I was writing this up to share, I decided to make a video of it. As I started things up to make the video, Zwift had an update - (rut row Shaggy). Sure enough, the update broke my code.
Back to the drawing board - I dug around and found people suggesting that trying to do both Cycle Power and Fitness Machine services in one Bluetooth service was problematic. Fortunately in my stumbling around the internet, I found Kris' GitHub with the FTMS service already coded for Arduino, but with a different use case (retro fitting Zwift into a Tacx Flow ergotrainer). I refactored the code, integrating the DPSxxxx charge controller code I had used previously into the FMTS only BLE service and removing any of Kris's code that didn't fit my needs. Now I have a working Zwift pedal generator that automatically changes wattage resistance while in Zwift "erg" mode, and can also provide a more realistic ride in Zwift "sim" mode, adding resistance going up hills, reducing it while going down hill. Overriding sim mode is allowed as well, just manually change the amps to get 20 watts or more over the base and an OVERRIDE state will be triggered for the remainder of the ride. From there on, you manually change the resistance to whatever you choose - helpful if you want to challenge yourself on the sprints, or want to keep a specific pace on a group ride.
Putting this all together took many fits and starts, but I'm so excited to be able to fully experience Zwift on my pedal generator! A great big shout out to Luke and Kris for helping me get through some of the challenges!
Supplies
You will need a pedal generator capable of 1.1x volts over the voltage needed to charge the batteries you are targeting. You can follow the design of my previous instructable Best Design DIY Bike Trainer Generator, but may need to change out the 320Kv motor to a lower Kv motor to produce higher voltage output like I show in this instructable. My daily driver pedal generator is a stationary bike turned pedal generator. Since I've covered those build details previously, I won't repeat them here.
You'll need an ArduinoBLE compatible Arduino, these should all work (I used the Nano 33 IoT):
- Arduino Nano 33 IoT or with headers already soldered
- Arduino Nano 33 BLE
- Arduino WiFi Rev 2
- Arduino MKR WiFi 1010
I haven't researched what changes you'd need to make in order to use the other Arduinos.
I also used a Nano screw terminal breakout module to make mounting and wiring the Arduino easier. You could also use a breadboard to wire it together, or just wire directly to the Arduino.
Next, I used a DPS5020 charge controller with the USB interface module. You won't actually use the USB module, but the wire harness and plug will be used to connect to the Arduino. This controller is capable of delivering 1000 watts with the right setup. I demonstrate charging batteries with a DPS5015 without the Zwift integration in this video as well as compare a "tire on" verses an e-bike motor based pedal generator.
A battery or bank of batteries to charge. I'm using a 50Ah LiFePO4 battery with a home made portable charging station similar to what I showed before that accepts up to 14.6 volts charging which will get us to over 300 watts reported to Zwift after accounting for losses. Doubling this up (wiring 2 batteries in series) will accept up to 29.2 volts and over 600 watts. I've also tried this setup with a Grid Tie Inverter with mixed results.
I used some 24 AWG hookup wire to go from the charge controller USB connector wire to the Arduino, or you can cut the USB connector off and use the wires from the harness directly. I left the connector intact in case I want to play around with the USB module down the road.
Step 1: Wiring It Up
The connections for this are quite simple. Assuming you already have a working pedal generator, you just need to insert the DPSxxxx charge controller into the circuit, positive and negative in, positive and negative out as in the diagram. Then connect the TX of the DPSxxxx to RX on the Arduino, RX to TX and GND to GND. The DPSxxxx outputs 3.3v as well, so I connected the DPS 3.3v to the 3.3v pin on the Arduino. My understanding is you "shouldn't" use the Arduino Nano 33 IoT 3.3v pin for "input power", however I have and so far it has worked just fine. If you are more cautious, you could use another power source (USB or other VIN) instead of putting power in on the 3.3v pin.
Step 2: Upload Code to Arduino
Get the free and open source Arduino IDE installed on your computer, connect a USB to MicroUSB cable to the Arduino (if using the Arduino Nano 33 IoT as I have), open the source code file listed here and click the "Upload" arrow in the menu bar.
Note that you may need to change the ftpWatts variable to match your fitness level, and depending on your setup, change the losses variable. I have losses at 16% (multiplying requested watts by 1.16) which I've calculated based on losses in the drive train, bridge rectifier and charge controller. If you are using a "tire on" bike trainer, this number will be closer to 40% losses, give or take. If anyone has some Power Pedals and can confirm the losses of a "tire on" trainer vs actual watts produced, please share! My current setup uses an exercise bike with a flywheel and ebike motor and has lower losses than the "tire on" trainer.
If you need to debug for whatever reason, set debugging = true at the top of the source file.
Attachments
Step 3: Get Zwifting!
With it all wired up and ready to go, start pedaling and you should see the DPSxxxx start up, and the power LED light up on the Arduino. Go to Zwift and look for the pedal generator for Power Source and Controllable, and get connected! Once Zwift connects to the Arduino, the onboard LED will light up (on the Nano 33 IoT, it's yellow). If you have any concern for the environment, this is a great way to get a workout while actually putting those watts you produce to good use! Using a decent capacity battery will allow you to get a full workout in, then just be sure to charge all your devices (laptop, mobile phones, portable speakers, electric toothbrush - anything with a rechargeable battery) with the watts you created so the battery is sufficiently drained and ready for the next workout.
Step 4: What's Next?
There is always room for improvement with projects - for this one, adding a couple hall effect sensors and collecting speed and cadence are next. With those along with bike and rider weight, I'll better be able to calculate resistance in SIM mode.
As always, questions are welcome! I'd love to hear from those that add this to their pedal generators!