In recent months, the use of virtual shifting on smart trainers has been gaining popularity, following Zwift's inclusion of this functionality in its own model of smart trainer, the Zwift Hub One, back in October 2023, along with a hardware component called the Cog, eliminating the need for a conventional cassette. Subsequently, this smart trainer has been discontinued, but Zwift and Wahoo have collaborated to bring virtual shifting functionality to a large number of Kickr models through a firmware update for these smart trainers.
Here's a link to Zwift Insider where you can find more details of All About Virtual Shifting in Zwift. In this article, Eric Schlange offers a comprehensive understanding of virtual shifting:
"Unless you ride a single-speed bike, you’re using physical gears to make your riding more enjoyable. You’ll typically shift to an easier (lower) gear when riding uphill so you aren’t grinding away, and you may shift to a higher gear on a descent so you don’t spin out.
With virtual shifting, your chain doesn’t move between different front chainrings or rear cassette cogs when you shift. Instead, when you make a virtual shift, your physical gearing doesn’t change, but Zwift simply changes the resistance of your smart trainer so it feels like you’ve changed gears."
All of this is great, except if you don't own a Zwift Hub One or one of the compatible models of Wahoo Kickr. That happens to be my case, as I own a Tacx Neo 1, and as time goes by, I see no information from Garmin that would make me believe in a new firmware version enabling virtual gears on Zwift.
Working detailsAnd how does Zwift know when you're shifting gears virtually and adjust the resistance of the smart trainer?
Well, as we'll see in more detail later on, there is more than one way to implement this functionality. In the case of Zwift's implementation, they've chosen not to directly modify the resistance of the smart trainer for each device, but rather smart trainers that want to be compatible must implement an API by updating their firmware, so Zwift can call it to adjust resistance. I guess this API includes the virtual gear selected by the user, allowing the smart trainer to adjust the resistance accordingly. Surely it's a bit more complex, as factors such as the road gradient percentage, the physical gear of the bike (which can be calculated from cadence and power/speed generated), etc., also need to be considered. But ultimately, this is information available to Zwift and can be sent to the smart trainer through the API for resistance adjustment.
With this approach, Zwift avoids having to develop and maintain for each device, and allows each manufacturer to ultimately implement gear shifting as they see fit. For example, they could include some resistance effect so that the user feels the gear change, similar to what happens in reality.
Finally, it's worth mentioning how Zwift detects when users shift gears virtually. This is accomplished through the use of Zwift Play or Zwift Click devices. Essentially, these peripherals connect via Bluetooth to the device running Zwift (PC, tablet, etc.), or alternatively, they can connect through the Zwift Companion app.
So, neither Zwift Play nor Zwift Click directly connects to smart trainers to adjust the resistance. Instead, this is achieved through Zwift's program via the API they have designed, which the smart trainer must implement.
I haven't found details of this API on the web, but I did come across another interesting article from Zwift Insider where they discuss this and related topics such as compatibilities, similarities with ERG mode, auto-shifting, etc. Virtual Shifting and Gearing on Zwift: Looking at Recent Patent Applications
However, how could we have virtual gears if we use a smart trainer whose manufacturer hasn't updated the firmware to implement the API designed by Zwift for virtual shift functionality?
This leads us to consider what alternative Zwift could have implemented to introduce the functionality without relying on manufacturers updating the firmware of their smart trainers. Well, the option is to increase or decrease resistance based on shifting virtual gears using the API currently provided by each manufacturer on their smart trainers (yes, I know it's a lot of work for development and maintenance, especially considering the variety of vendors and models of smart trainers).
The calculation to adjust the resistance could be more or less complex. For instance, a straightforward way to implement it could be to adjust the gradient percentage according to the virtual gear number: Gear 0 would maintain the same percentage as the road, gear 1 would add 1 to the percentage, and gear -1 would subtract 1 from the percentage, so that the final resistance is increased or decreased according to the selected gear. Later, you can include an offset to adjust based on your real transmission.
Fortunately, we don't need to implement such feature ourselves. We can use the QZ app (available for Android and iOS), that acts as a bridge between Zwift and smart trainers, allowing it to implement virtual shifting functionality as we discussed earlier. In this case, Zwift instead of connecting directly via Bluetooth, ANT+, or WiFi through the Companion app, to the smart trainer, connects to a "virtual smart trainer" version provided by the QZ app (which does connect directly to the smart trainer via Bluetooth) via WiFi.
By other hand, QZ app is also well-known in Zwift forums for covering the functionality of increasing the "reality slider" above 100%. Just as lowering the value of this slider enables cyclists without sufficient gearing to climb steep gradients such as the ascent to the Watopia radio tower, it also allows cyclists with low gearing to enhance their performance on descents, flat terrain, or during sprints, particularly when using a single-chainring mountain bike. (Yes, it's a feature that has been long demanded in the Zwift forum for several years, but it seems that Zwift doesn't care about users who use a single-chainring mountain bike).
QZ includes a trial version (link to the current version as of the date of writing this article) that allows you to test the application on Android for a few minutes to verify compatibility with your device.
Don't be fooled by the appearance of the application; it has many functionalities, is quite reliable (I've used it for many hours, for instance, to complete all stages of the FRR Grand Tour), and its author, Roberto Viola, is always accessible to address questions, bugs, and listen to requests for new features. For example, in the case of the Android version, which is the one I use, it offers the option to prevent the application from closing when in the background, remember the last virtual gear used when the application was closed, as well as compatibility to change virtual gears with Zwift Play and Zwift Click. While in the case of using these peripherals, as they need to be connected via Bluetooth to the QZ app, they cannot be connected to Zwift, and in the case of Zwift Play, you cannot use the rest of the functionalities/buttons it includes. As for Zwift Click, since it only has a couple of buttons for shifting up and down virtual gears, there is no loss of functionality by not connecting directly to Zwift.
Unlike the Zwift Companion app, the QZ app also allows changing and shifting virtual gears through a widget on the screen (Yes, I know it's not the most comfortable way, but why doesn't Zwift provide this option in the Companion app, at least for testing purposes?). Although it can be used for some trial rides (in my case, I used it in a TTT race in the Zwift Racing League), for more convenient operation, it's necessary to use a physical device. While I had the option to purchase a Zwift Play or Zwift Click, I was intrigued to find that the QZ app also allows enabling an option to change using the volume up and down buttons of the smartphone, as you can see above in the DIY section of this article.
I would like to emphasize that making a gear-shifting device yourself is not necessary at all (although it can be very enjoyable and allows you to customize it to your setup). You can use the QZ application with these options to change virtual gears:
- Using the touch buttons in the QA application widget (although not very comfortable, it's valid for testing purposes before making or buying a physical device).
- Enabling the option to change gears via the volume buttons +/- of the smartphone in the QA application (the QZ application must be in the foreground at that time).
- Using the Zwift Play or Zwfit Click devices (pairing it with the phone via Bluetooth).
- Using any device connected to the phone (for example, via Bluetooth) and simulating volume changes to switch virtual gears. (This will be the option we use in the DIY section).
Below are the steps to get the virtual gears working using the QZ app:
1. Enable Bluetooth on your mobile device.
2. Turn on the smart trainer.
3. Open the QZ app (it will automatically detect the smart trainer; it's possible you have to find/select the first time, I don't remember).
4. (Only once) Configure the QZ app: Enable virtual shifting (Settings > Title Options > Gears), enable changing gears with volume buttons if you need this feature (Settings > Advanced Settings > Volume buttons change gears), and enable Android notifications to prevent the operating system from closing the app (Settings > Experimental Features > Android Notification).
5. Pair the Zwift Click with the mobile device for the first time.
6. Launch the Zwift application (ensure that Wi-Fi is enabled; Bluetooth is only necessary if using a HR band; in my case, I connect it through the Zwift Companion app using the mobile's Bluetooth).
7. In the Zwift application, go to devices and search for the roller. You'll automatically find a "Wahoo Kickr."
Make your own shift buttonsIn my smart trainer setup, I use a mountain bike, and on the handlebars, I have a pair of long extensions for a more comfortable position when pedaling and not gripping the lower part of the handlebar. Reviewing this setup, I decided that the best option for changing gears would be to place a button at the end of each extension, so that the right one shifts up and the left one shifts down.
Of course, here we enter the DIY part so that everyone could design their own gear shift buttons wherever they consider it could be more comfortable. Even on a road bike, they could be included in the original physical shift levers, similar to how some smart bikes do it.
So let's get started.
How do we remotely change the volume of the smartphone? For this, we'll use an ESP32S3 board (another model from the ESP32 series with BLE could also work) to implement a HID (Human Interface Device) that we'll connect to the Android smartphone via Bluetooth, where the QZ app is running.
We'll connect two buttons to microcontroller, so that when one is pressed, the volume increases by one unit, and when the other is pressed, the volume decreases by one unit.
To simplify the implementation, we'll use a couple of examples included in the Espressif ESP-IDF framework to program the microcontroller. Specifically:
- ble_hid_device_demo (Note: I had to use the master branch version because the last stable version was not compatible with the latest Android version)
- button_power_save
The code developed is located in this repository. Follow the instruction in the readme file to build and flash it.
Here is a schematic overview of the project:
Below is a diagram of ESP32 connections:
The summarized operation is as follows:
- The QZ app has been previously configured to enable virtual gears, close the application if it goes to the background, allow changing virtual gears using the smartphone's volume keys (or via an HID device), and remember the last virtual gear used.
- The smart trainer (in this case, Tacx Neo 1, but it could be any model compatible with the QZ app) connects via Bluetooth to the QZ application running on an Android mobile device (version 13).
- The HID device (implemented with the ESP32) has been paired with the Android smartphone.
- In addition to the QA app, the Zwift Companion app is also running on the Android smartphone to connect a Bluetooth-connected heart rate band.
- The Android smartphone and the Zwift application running on the PC are on the same WIFI network.
- The Zwift application connects to the "virtual" smart trainer of the QZ app via WIFI. Bluetooth does not need to be enabled on the PC.
- The Zwift application communicates with the heart rate band via WiFi through the Zwift Companion app.
- Using the buttons connected to the ESP32 board, the volume is adjusted. It is necessary for the QA app to be in the foreground on the smartphone for virtual gears to change and roller resistance to be adjusted. Otherwise, the smartphone's volume will be changed.
Below are somes photos of the final assembly on the bike:
After the initial tests, the operation seems reliable, not detecting keystrokes that do not change the gear in the application. The gear shift response time and the subsequent resistance change are also performed quickly enough, estimated between 2-3 seconds (I suppose in newer smart trainer models it can be better).
In the case of a road profile with a fast variation in gradients, for example, in the climb to the Temple on Makuri Island (Zwift), "too many" gear changes up and down are needed to adapt to the undulating terrain. This is for two main reasons: we are using a virtual cassette with many gears but with a small linear progression, and the mechanism for shifting up/down gears is one by one.
If we compare it with a physical shift, we have a cassette with a non-linear progression with gears with increasing teeth each time, and also the possibility in the shifter mechanism to change several gears at once.
Regarding having progressive shifts, I think it's an advantage because when you're, for example, on a long climb with more or less constant gradients, it allows you to adjust at every moment the gear ratio that you can best handle.
Therefore, I think we should focus on being able to change more gears quickly, for this I've included the following features as an addition to the simple shift by pressing the button once:
- Shift three gears simultaneously with a double press.
- Shift five gears simultaneously with a long press.
Not only in Zwift, but also in other platforms. In fact, that's the beauty of this approach—it's not limited to a specific platform. So far, I've successfully tested it with Zwift, IndieVelo, Rouvy and MyWhoosh.
Last thoughtsAfter testing the implementation in several races on Zwift, with good performance and effectiveness in changing the resistance of the smart trainer to adapt to the gradient changes of the route, both in terms of the sufficient number of gear changes and the speed of applying the changes, I have some reflections to share for the specific case of the Tacx Neo 1, the smart trainer that I use.
Unlike most other smart trainers on the market, the Tacx Neo models are characterized by implementing a virtual flywheel instead of including a physical flywheel. It simulates inertia through a motor that spins at a variable speed/force in the direction of pedal movement and variable resistance by activating a magnetic brake.
The use of a virtual flywheel theoretically allows the simulation of flywheels with a weight closer to the real weight (weight of the bike + rider) and also adjust it, for example, to the rolling resistance and road gradient. This way, there is more inertia on flat terrain than when climbing a mountain pass. This clearly affects the pedaling sensation, impacting accumulated fatigue and the ease of generating more or fewer watts, as the forces throughout the pedal stroke are different.
And that is where a virtual shifting implementation like the one described, which relies on external adjusting the % gradient to increase/decrease the roller resistance and simulate the effect of virtual gear changes, becomes a handicap and influences the inertia simulation performed by the Tacx Neo in an unrealistic way. In this case, to be able to simulate virtual gear changes and maintain inertia simulation, we would need the firmware of the smart trainer to be updated, which cannot be done externally using an application like QZ.
On the other hand, in trainers that rely on a physical flywheel (Wahoo Kickr Core, Elite, etc.), this handicap should not occur. In fact, the compatibility with other commercial trainers of the new Elite Square device announced at Eurobike 2024 suggests that it operates similarly to the implementation described in this blog. This means that applying such a virtual shifting simulation will affect the inertia flywheel implementation in the Tacx Neo trainer models.
Comments
Please log in or sign up to comment.