The Romans knew it already "Sterzare Necesse Est" (free after Plutarch) and it is still valid in a virtual cycling world.
What it means
The phrase is a playful remix of the Latin saying "Navigare Necesse Est" ("To sail is necessary"). Replacing Navigare with Sterzare — the Italian verb for steering — reflects the project’s goal: enhancing interaction through alternative Human Interface Devices (HIDs).
- More autonomy: increased user-experience
- Ride the optimal line through a corner
- Turn left or right at intersections
- Tactical positioning in a group
Open Virtual Steering (OVS) is an open-source project that explores interfacing with various Human-Interface-Devices (HID) for the use case of steering control in virtual cycling platforms. It provides examples of alternative input methods for navigating and positioning a cycling avatar in a virtual world.
NimBLESteeringServer is an open-source, Arduino-compatible C++ library that provides a reusable Bluetooth Low Energy (BLE) server implementation for transmitting steering data to virtual cycling platforms, for use with the Espressif ESP32 SoC's and ESP-NimBLE v2.x.
It is designed as a shared backend for projects in the Open Virtual Steering ecosystem and supports pairing with BLE clients that recognize a known steering profile used in commercial platforms.
This project allows users to explore a range of input devices for steering control in virtual cycling worlds. The emphasis is on enhancing interactivity and user experience through both accessible and innovative control methods.
| HID Focus | Bluedroid/NimBLE Repository | Bluefruit Repository |
|---|---|---|
| Buttons, Joysticks, Rotary Encoders | OVS-DiscreteHIDs |
OVS-DiscreteHIDs-Bluefruit |
| Turn & lean-based steering with MPU6050 | OVS-MotionIMU |
OVS-MotionIMU-Bluefruit |
| Voice-activated steering with TinyML | OVS-VoiceControl |
ℹ️ |
ℹ️ The VoiceControl project is tightly coupled to the XIAO ESP32S3 Sense, which includes a built-in microphone and supports only ESP32 BLE-Hosts. A Bluefruit version is not applicable.
Bluefruit is Adafruit's branding for its line of development boards and firmware built around Nordic Semiconductor's nRF52 family of Bluetooth Low Energy (BLE) chips. This line is also supported by the Open Virtual Steering project. See: Bluefruit-Steering-Server
There are two hosts, ESP-Bluedroid and ESP-NimBLE. The major difference between them is as follows:
-
Although both support Bluetooth LE, ESP-NimBLE requires less heap and flash size.
-
ESP-Bluedroid supports both Classic Bluetooth and Bluetooth LE, while ESP-NimBLE only supports Bluetooth LE.
NimBLE is a completely open source Bluetooth Low Energy stack produced by Apache. It is more suited to resource constrained devices than ESP-Bluedroid and has now been ported by h2zero to the ESP32 plus Arduino: NimBLE-Arduino.
- API Reference
With the NimBLESteeringServer library installed, developers can easily create applications that act as dedicated BLE steering controllers for use with virtual cycling platforms.
The user application is responsible for interfacing with a Human Interface Device (HID) — such as buttons, a joystick, an IMU, or voice input — and regularly passing steering data to the NimBLESteeringServer.
Once paired with a BLE client, the application uses BLESteeringServer::updateSteeringValue() to transmit real-time steering angle data over Bluetooth.
To ensure interoperability, the library implements a known BLE Steering Profile, which defines a consistent structure of services and characteristics used in commercial BLE steering devices. BLE profiles serve as an application-layer contract between the controller (peripheral) and the receiving client (central), ensuring compatibility across devices and platforms.
🔍 More Info
Introduction on BLE profiles, services, characteristics, device roles and network topology
-
Supported MCU's with NimBLE-Arduino
- Espressif: ESP32, ESP32C3, ESP32S3
- Nordic: nRF51, nRF52 series (Requires using n-able arduino core)
- Install the NimBLESteeringServer library from this repository. Download as
.zipand extract toArduino/librariesfolder, or
in Arduino IDE fromSketch menu->Include library->Add .Zip library - Select one of the Related Repositories that apply this shared backend and offer you ready-to-use exemplary access to a selection of different Human-Interface-Devices.
💡 Research & Independence
This project is not affiliated with, endorsed by, or associated with any commercial virtual cycling platform or steering device manufacturer. It is a research and interoperability initiative designed to explore alternative human interface methods in the context of indoor cycling. All development is conducted independently for educational and experimental purposes.✅ Compliance & Responsibility
This repository does not include or promote any circumvention of technological protection measures, reverse engineering of proprietary software, or unauthorized access to restricted systems. Users are solely responsible for ensuring that their use of this code complies with local laws, software licenses, and platform terms of service.🔍 Copyright & Contact
If you are a rights holder and believe that this project includes content that violates your intellectual property rights, please open an issue on this repository to initiate a respectful review. We are committed to responding promptly and, if appropriate, taking corrective action.The functionality of Open Virtual Steering with NimBLESteeringServer was tested using standard BLE debugging tools to ensure proper communication and responsiveness. One of the primary tools used was nRF Connect for Mobile, a widely available application for scanning, connecting, and interacting with BLE devices. This allowed for verification of characteristic read/write operations, response timing, and general stability of the BLE communication.
#include <NimBLESteeringServer.h>
void setup() {
BLESteeringServer::getInstance().begin();
}
void loop() {
float angle = getSteeringAngleFromHID();
BLESteeringServer::getInstance().updateSteeringValue(angle);
}⚖️ Legal Notice (EU Context)
This project is developed and published in accordance with EU directives that recognize the right to study, test, and develop software components for the purpose of achieving interoperability (e.g., Directive 2009/24/EC on the legal protection of computer programs, Article 6).
No part of this project is intended to infringe upon intellectual property rights or violate technological protection measures. All content is shared in good faith under the belief that it falls within the bounds of legitimate research, reverse engineering for interoperability, and fair use under EU law.
Users must ensure their own compliance with national implementations of EU directives, and are responsible for how they apply or modify this code.
