Emulating a smart trainer
Now we have the codes that the Proform bike sends from the console to the lower control board. It is time to connect the bike to a fitness program using bluetooth low energy (|BLE).
Normally I'd use an Arduino for this type of real time project, but most Arduinos don't have bluetooth. I'd contemplated using a Raspberry Pi for the bluetooth, but it might be overkill. Luckily, someone introduced me to the ESP32 boards and after a virtual trip to Digikey I am now a proud owner of a Seeed Studios XIAO ESP32C3 (hereafter known as ESP32). Bluetooth, wifi, loads of ram and flash, decent IO pins and only $7.66 from Digikey. Amazing. AMAZING. (so many projects beckon...)
I'd looked at BLE fitness protocols before and honestly, the documents are as dry as hay and less informative. Previously I made a pseudo-smart exercise bike with a stepper motor and bluetooth was so confusing that I just went for ANT+ on a Raspberry Pi.
Luckily, this time I was able to find some code from others that had successfully used bluetooth. The BLE code was reused from a project by Gene's Green Machine. His Zwift connected exercise bike instructable:
https://www.instructables.com/Zwift-Capable-Pedal-Generator/. Great projects, I adapted the code to fit the Proform situation. This really helped me start sending data from the Proform bike via bluetooth.
In a nutshell, the ESP will calculate power based on resistance settings and current cadence. Power is torque times angular velocity -- ie resistance times load. The ESP32 also receive values for incline and sends these along to the Proform to adjust the
resistance level accordingly to simulate riding up or down hills.
The power calculation was a tricky thing. Initially I "injected" cadence values to the console and then noted the power calculated at each gear level (0 to 26). I then empirically determined a second order polynomial formula that closely calculated power to those provided by the bike. The formula works best at cadence values 60 to 100. I didn't spend a lot of time massaging the calculation because I intend to better calculate the true power at different resistance levels and speeds using an old treadmill motor. Stay tuned.
The ESP takes input from 4 buttons allowing a the ride to
change gears - the bike simulates shifting (by changing resistance).
I've programmed 3 front gear ranges and 11 rear ranges. The buttons
shift the front rings up or down and the rear cassette up or down. The
ESP also gets incline values from Zwift and converts them to resistance
settings. The bike seems to have about 128 resistance settings. Zwift
goes from 0 to 15 degrees incline so initially I had 8 steps of
resistance per degree of incline - -this was absolutely BRUTAL so I
dialed it back to 4 steps per degree.
The ESP will also take the Zwift incline and set the tilt of the bike
based on the Zwift numbers. The incline changes often so I found the
clunking of the tilt annoying and disabled it in my current running code. All the data is communicated to the bike via RS485 using the original codes and protocol of the Proform bike. To wire in the ESP32 and avoid conflicts, I disconnected the console from the lower control board to add the ESP32.
So the console no longer displays power, gears, time, etc.
I've
been using the ESP32 setup to successfully to connect and ride in Zwift. I've uploaded
some code and a schematic to Github.
https://github.com/kevinmott09/proformBLE
Next on the TO DO is add an ERG mode and also firm up the real power numbers of the bike. And also get the setup off the breadboard and tidily tucked away into the bike somewhere.
