An intelligent and modular flight controller for drones and UAVs
Fly Controller is an advanced firmware that implements a complete flight control system with DroneCAN communication and intelligent power management. Specifically designed to work with Hobbywing ESCs and run on the ESP32-C3 platform.
- Overview
- System Architecture
- Main Components
- Communication Protocols
- Features
- Supported Hardware
- Installation and Configuration
- Contributing
- License
Fly Controller is a modular ESP32-based flight control system that offers:
- Intelligent Throttle Control: With automatic calibration, cruise control, and safety protections.
- DroneCAN Communication: Complete interface with Hobbywing X-series ESCs.
- Bluetooth LE Telemetry: Real-time data transmission to monitoring apps like XCTRACK via the Xctod module.
- Power Management: Dynamic power calculation based on battery voltage and component temperature.
- User Interface: Control button and a PWM-driven passive buzzer for audio feedback.
- Complete Telemetry: Serial output for real-time monitoring and debugging.
- Platform: ESP32-C3 Super Mini
- Framework: Arduino
- Build System: PlatformIO
- CAN Bus: Built-in ESP32 TWAI controller for DroneCAN.
- Bluetooth LE: For telemetry transmission.
- Serial: Telemetry and debug (115200 baud).
- PWM: Direct ESC control.
- Hall Sensor: Throttle control (ADS1115 Channel 0)
- NTC Sensor: Motor temperature (ADS1115 Channel 1)
- NTC Sensor (XAG only): ESC temperature (ADS1115 Channel 2)
- Voltage Divider (XAG/Tmotor): Battery voltage (ADS1115 Channel 3)
- ESC PWM: GPIO 7 (1050-1950ΞΌs)
- Buzzer: GPIO 6 (Passive, PWM controlled)
- Button: GPIO 5 (with interrupt)
- CAN TX/RX: GPIO 2/3
// Main features
- Automatic Hall sensor calibration on startup
- System arming/disarming
- Cruise control mode
- Noise filtering with moving average
- Sensor failure protectionTechnical Specifications:
- Hall sensor reading is calibrated automatically.
- 30 samples for filtering.
- Automatic calibration completes in 3 seconds.
- Cruise mode activated with 30%+ throttle.
// DroneCAN protocol for Hobbywing ESCs
- Complete telemetry (RPM, voltage, current, temperature)
- LED and motor direction control
- Throttle source configuration
- Automatic ESC ID discoverySupported Messages:
0x4E52: Status 1 (RPM, direction)0x4E53: Status 2 (voltage, current)0x4E54: Status 3 (temperature)- LED control (red, green, blue)
- Direction and throttle commands
T-Motor uses TmotorCan (UAVCAN); XAG uses XagTelemetry with analog sensors.
// Intelligent available power calculation
- Battery voltage-based limitation
- Motor thermal protection
- Battery power floor
- ESC PWM conversion
- Throttle ramp limiting (smooth acceleration/deceleration)Protection Algorithms:
- Minimum voltage limitation (42.0V)
- Thermal protection (60Β°C motor, 110Β°C ESC)
- Progressive power reduction based on motor and ESC temperature
- Throttle ramp limiting: 4 ΞΌs/tick acceleration, 8 ΞΌs/tick deceleration (prevents jerky movements)
// Agnostic NTC sensor (ReadFn + adcVoltageRef)
- Beta = 3950K for 10K NTC
- Filtering with 10 samples
- ADC source: ADS1115 I2C (all builds β legacy GPIO ADC not used in production)// CAN message handling using ESP32 TWAI controller
- receive() non-blocking API - returns raw ESC frames
- main.cpp routes frames to HobbywingCan/TmotorCan
- NodeStatus and GetNodeInfo handled internally
- sendNodeStatus() for periodic announcements// Sonorous alert system with a passive buzzer
- Success, error, and warning beeps
- Customizable beeps via PWM control
- Continuous alert when motor stops// Single button control
- Single click: Arming/Disarming
- Long press: Cruise activation
- Tactile feedback with buzzer// Data output for monitoring via BLE
- Transmits telemetry data compatible with the XCTRACK app.
- Battery information
- Throttle status
- Motor and ESC data
- Overall system status// WiFi Access Point with captive portal and OTA updates
- AP mode for easy device discovery
- Real-time telemetry dashboard
- Configuration pages: power, thermal, BMS, system settings
- Firmware Over-The-Air (OTA) updates via ElegantOTA
- CSV flight log viewing and download// BLE client for smart battery pack monitoring (Daly and JBD)
- Cell voltage monitoring (min, max, delta)
- Pack voltage, current, and state-of-charge (SoC)
- Temperature sensors per pack
- Charge/discharge/balance status flags
- BLE device scanning triggered via web portal// CSV logging to LittleFS
- Auto-start on arm, auto-stop on disarm
- Configurable data fields and header
- Log download and deletion via web interface- Speed: 500 kbps
- Node ID: 0x13 (controller), 0x03 (ESC)
- Messages: Status, control, configuration
- Format: CAN 2.0B with DroneCAN payload
- Telemetry: RPM, voltage, current, temperature, LED control
- Speed: 1 Mbps
- Protocol: UAVCAN v0
- Messages: Status, control, configuration
- Format: CAN 2.0B with UAVCAN payload
- Telemetry: RPM, voltage, current, temperature
- Provides a service to transmit flight data to compatible mobile applications (XCTRACK).
- Available in all controller modes.
- β Low voltage protection
- β Motor thermal limitation
- β ESC thermal limitation
- β Auto-disarm on failure
- β Sonorous alert when motor stops
- β Automatic throttle calibration
- β Intelligent cruise control
- β Button arming/disarming
- β Direct ESC PWM control
- β Smooth throttle ramp limiting (acceleration/deceleration control)
- β Bidirectional CAN bus communication (DroneCAN/UAVCAN)
- β Bluetooth LE telemetry for apps (XCTRACK)
- β Complete serial telemetry
- β Real-time status
- β Event logging
- β Failure diagnosis
- β Battery Management System support (Daly, JBD via BLE)
- β Cell voltage and balance monitoring
- β State-of-charge (SoC) tracking
- β CSV flight logging to LittleFS (auto on arm/disarm)
- β Web portal with OTA firmware updates
- ESP32-C3 Super Mini
- Hobbywing X-Series (DroneCAN mode - default): Full telemetry via CAN bus
- T-Motor (UAVCAN mode): Full telemetry via CAN bus
- XAG Motors (XAG mode): PWM-only control with NTC temperature sensors
- Any ESC with PWM input (compatible with all modes)
- 14S Li-ion/Li-Po packs (configurable voltage)
- Hall Sensor (throttle)
- 10K NTC 3950K (temperature)
- Push-button
- Passive piezoelectric buzzer
The project supports three controller types with dedicated build environments:
| Controller | Environment | Protocol | CAN Bus |
|---|---|---|---|
| Hobbywing | lolin_c3_mini_hobbywing |
DroneCAN | β Required |
| T-Motor | lolin_c3_mini_tmotor |
UAVCAN | β Required |
| XAG | lolin_c3_mini_xag |
PWM-only | β Not required |
Quick Build Commands:
# Hobbywing (default)
~/.platformio/penv/bin/pio run -e lolin_c3_mini_hobbywing
# T-Motor
~/.platformio/penv/bin/pio run -e lolin_c3_mini_tmotor
# XAG
~/.platformio/penv/bin/pio run -e lolin_c3_mini_xag# Install PlatformIO CLI
pip install platformio
# Or use the PlatformIO IDE extension for VSCodegit clone https://github.com/rodrigomedeirosbrazil/fly-controller.git
cd fly-controllerThe required libraries are automatically managed by PlatformIO.
# platformio.ini
lib_deps =
bxparks/AceButton@^1.10.1
madhephaestus/ESP32Servo
https://github.com/me-no-dev/ESPAsyncWebServer.git
ayushsharma82/ElegantOTA
AsyncTCP
adafruit/Adafruit ADS1X15@^2.4.6
bblanchon/ArduinoJson@^6.21.3Using VS Code PlatformIO Extension (Recommended):
- Install the PlatformIO extension in VS Code
- Open the project folder
- Select the desired environment from the PlatformIO toolbar (bottom status bar)
- Use the PlatformIO toolbar to build, upload, and monitor
Using PlatformIO CLI:
The project supports three controller types, each with its own build environment:
# Build for Hobbywing ESC (DroneCAN protocol)
~/.platformio/penv/bin/pio run -e lolin_c3_mini_hobbywing
# Or use the default environment
~/.platformio/penv/bin/pio run -e lolin_c3_mini
# Upload firmware
~/.platformio/penv/bin/pio run -e lolin_c3_mini_hobbywing -t upload
# Monitor serial output
~/.platformio/penv/bin/pio device monitor -e lolin_c3_mini_hobbywingFeatures:
- Full CAN bus support (500 kbps)
- DroneCAN protocol communication
- Complete telemetry (RPM, voltage, current, temperature)
- LED control and ESC configuration
# Build for T-Motor ESC (UAVCAN protocol)
~/.platformio/penv/bin/pio run -e lolin_c3_mini_tmotor
# Upload firmware
~/.platformio/penv/bin/pio run -e lolin_c3_mini_tmotor -t upload
# Monitor serial output
~/.platformio/penv/bin/pio device monitor -e lolin_c3_mini_tmotorFeatures:
- Full CAN bus support (1 Mbps)
- UAVCAN protocol communication
- Complete telemetry (RPM, voltage, current, temperature)
- ESC configuration and control
# Build for XAG motors (PWM-only, no CAN bus)
~/.platformio/penv/bin/pio run -e lolin_c3_mini_xag
# Upload firmware
~/.platformio/penv/bin/pio run -e lolin_c3_mini_xag -t upload
# Monitor serial output
~/.platformio/penv/bin/pio device monitor -e lolin_c3_mini_xagFeatures:
- PWM-only control (no CAN bus required)
- Analog temperature sensors (NTC)
- Battery voltage monitoring via voltage divider
- Throttle ramp limiting for smooth acceleration/deceleration
Note: The XAG motor has a ~1.5 s reaction delay when stopped. During this wake-up period, the firmware sends 5% PWM; after 1.5 s, the ramp runs from 5% to the throttle target. Ramp rates: THROTTLE_RAMP_UP_US_PER_MS (2 ΞΌs/ms), THROTTLE_RAMP_DOWN_US_PER_MS (6 ΞΌs/ms).
// src/config.h - Main configurations
// I2C Bus (ADS1115 ADC - all builds)
#define I2C_SDA_PIN 20 // GPIO20 - I2C SDA
#define I2C_SCL_PIN 21 // GPIO21 - I2C SCL
// ADS1115 Channels
#define ADS1115_THROTTLE_CHANNEL 0 // Channel A0 - Hall Sensor
#define ADS1115_MOTOR_TEMP_CHANNEL 1 // Channel A1 - Motor NTC 10K
#define ADS1115_ESC_TEMP_CHANNEL 2 // Channel A2 - ESC NTC 10K (XAG only)
#define ADS1115_BATTERY_CHANNEL 3 // Channel A3 - Battery voltage divider (XAG, Tmotor)
// Digital I/O
#define BUTTON_PIN 5 // GPIO5 - Push button
#define BUZZER_PIN 6 // GPIO6 - Passive Buzzer (PWM)
#define ESC_PIN 7 // GPIO7 - ESC PWM signal
// CAN Bus (TWAI) - Hobbywing and T-Motor modes only
#define CAN_TX_PIN 2 // GPIO2 - CAN TX
#define CAN_RX_PIN 3 // GPIO3 - CAN RX// src/config.h - Throttle ramp limiting parameters
#define THROTTLE_RAMP_UP_US_PER_MS 2.0f // Acceleration rate (ΞΌs/ms)
#define THROTTLE_RAMP_DOWN_US_PER_MS 6.0f // Deceleration rate (ΞΌs/ms)
// XAG (useSmoothStart): 1.5s wake-up at 5% PWM before ramp
#define XAG_MOTOR_REACTION_DELAY_MS 1500
#define XAG_WAKEUP_PWM_PERCENT 5Behavior:
- Acceleration: Limited to 2 ΞΌs/ms (smooth ramp-up)
- Deceleration: Limited to 6 ΞΌs/ms (responsive braking)
- XAG: 1.5 s at 5% PWM when starting from stopped; then ramp from 5% to target
The system automatically calibrates the Hall sensor for the throttle on every startup. No manual configuration is needed.
Calibration Process:
- On startup, move throttle to maximum position and hold for 3 seconds
- Move throttle to minimum position and hold for 3 seconds
- Calibration complete - system is ready to arm
- Initialization: Automatic throttle calibration, CAN bus setup (if applicable).
- Arming: Press the button to arm the system (throttle must be at minimum).
- Operation: Adjust the throttle; the system calculates and delivers safe power with smooth ramp limiting.
- Cruise: Maintain throttle >30% for a few seconds to activate cruise control.
- Disarm: Press the button again to disarm.
Hobbywing/T-Motor (CAN bus):
- Ensure CAN bus is properly connected (H/L lines)
- ESC must be configured for DroneCAN (Hobbywing) or UAVCAN (T-Motor) mode
- Full telemetry available via CAN bus
XAG (PWM-only):
- No CAN bus required
- Temperature sensors must be connected (motor and ESC)
- Battery voltage divider must be connected
- Motor has ~1.5 s reaction delay when stopped; firmware sends 5% PWM during wake-up, then ramps to target
src/
βββ main.cpp # Main loop
βββ config.h, config.cpp # Configuration and object instances
βββ config_controller.h # Build type (IS_HOBBYWING, IS_TMOTOR, IS_XAG)
βββ ADS1115/ # I2C 16-bit ADC (primary sensor interface, all builds)
βββ Throttle/ # Throttle control (ReadFn via ADS1115)
βββ Temperature/ # Thermal sensor (ReadFn via ADS1115)
βββ Power/ # Power management & throttle ramp limiting
βββ Canbus/ # CAN receive() API (Hobbywing/Tmotor only)
βββ Hobbywing/ # HobbywingCan, HobbywingTelemetry
βββ Tmotor/ # TmotorCan, TmotorTelemetry
βββ Xag/ # XagTelemetry (PWM-only)
βββ Sensors/ # BatteryVoltageSensor (XAG)
βββ Telemetry/ # Telemetry facade, TelemetryFormatter
βββ BatteryMonitor/ # Coulomb counting, SoC
βββ Settings/ # Persistent configuration (ESP32 Preferences)
βββ Button/ # User interface (AceButton)
βββ Buzzer/ # Audible alerts (PWM)
βββ Xctod/ # BLE telemetry (XCTRACK format)
βββ BluetoothBms/ # BLE BMS client (auto-detects Daly/JBD)
βββ DalyBms/ # Daly BMS protocol implementation
βββ JbdBms/ # JBD BMS protocol implementation
βββ Logger/ # CSV flight logging to LittleFS
βββ WebServer/ # WiFi AP, captive portal, OTA updates
βββ Pages/ # HTML/JS page handlers
- Create a class in
src/ComponentName/. - Add includes in
config.h. - Create a global object instance.
- Call its methods in
main.cpp.
Contributions are welcome! Please:
- Fork the repository.
- Create a feature branch (
git checkout -b feature/new-feature). - Commit your changes (
git commit -am 'Add new feature'). - Push to the branch (
git push origin feature/new-feature). - Open a Pull Request.
- Code in English.
- Document new features.
- Follow PlatformIO standards.
This project is licensed under the MIT License.
Developed by: Rodrigo Medeiros Repository: https://github.com/rodrigomedeirosbrazil/fly-controller
For technical support or questions, open an issue in the repository.