๐ฎ ESP32-based Dual-Core LoRa Ground Control Station with PS5 Controller
A sophisticated dual-core ground control station for remote aircraft control using LoRa communication and PS5 DualSense controller input. This project provides real-time flight control with OLED display feedback, robust wireless communication, and optimized dual-core performance for enhanced responsiveness and safety.
- Core 1 (High Priority): Real-time PS5 controller processing and LoRa transmission at 20Hz
- Core 0 (Lower Priority): OLED display updates and LoRa reception at 10Hz
- Thread Safety: Mutex protection for shared data between cores
- Performance Monitoring: Real-time system health and performance statistics
- Watchdog Protection: Robust error handling to prevent system crashes
- Full DualSense Support: Buttons, analog sticks, triggers, and IMU sensors
- Flight Controls:
โ๏ธ Left stick X-axis โ Aileron controlโ๏ธ Right stick X-axis โ Rudder controlโ๏ธ Right stick Y-axis โ Elevator control- ๐๏ธ R2 trigger โ Engine throttle
- Auxiliary Controls:
- ๐ชถ L1/R1 โ Flaps control (decrease/increase)
- ๐ L3/R3 โ Reset aileron/elevator trim
- ๐ PS Button โ Enable airbrake
- โ Cross Button โ Disable emergency stop
- โญ Circle Button โ Enable emergency stop
- Safety Features: Emergency stop override and safety interlocks
- 915MHz ISM Band: Long-range, low-power wireless communication
- Packet Protocol: Custom message format with checksum validation
- Real-time Transmission: 60ms update rate for responsive control
- Data Optimization: Smart packet filtering to reduce redundant transmissions
- 128x64 SSD1306 Display: Real-time status and control feedback
- Multi-frame UI: Switchable display screens
- Status Overlays:
- ๐ต Bluetooth connection status
- ๐ Battery percentage display
- โก Charging indicator
- ๐ถ WiFi status (when available)
- Flight Data Display: Live control surface positions and engine status
- Emergency Stop: Immediate control override capability
- Connection Monitoring: Automatic safety engagement on signal loss
- Input Validation: Checksum verification for all transmitted data
- Redundant Safety: Multiple layers of safety interlocks
- ESP32 Development Board: TTGO LoRa32 v2.1 (recommended)
- LoRa Module: 915MHz SX1276/SX1278
- OLED Display: 128x64 SSD1306 (I2C)
- PS5 DualSense Controller: Bluetooth connectivity
- LoRa Module: Uses board default pins (automatically configured)
- OLED Display: I2C (uses board default SDA/SCL pins)
- Analog Input: Pin 34 for manual throttle slider (optional)
- Built-in LED: Status indication
- FreeRTOS Tasks: Dual-core task management with priority scheduling
- Memory Management: Optimized 8000-word stack size per task
- Error Handling: Graceful degradation and automatic recovery
- Performance Optimization: Load balancing across both ESP32 cores
lib_deps =
thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays@^4.5.0 ; ๐ฅ๏ธ
sandeepmistry/LoRa@^0.8.0 ; ๐ก
; PS5 Controller library included in lib/ folder ๐ฎ- Connect LoRa module to ESP32 (refer to pin definitions in
include/common.h) - Connect OLED display via I2C
- Power up the system
- Find your PS5 controller's Bluetooth MAC address:
- Connect controller to your phone via Bluetooth
- Check "About" settings for the MAC address
- Update the MAC address in
include/common.h:#define PS5_MAC_ADDRESS "xx:xx:xx:xx:xx:xx" // ๐ฎ Your controller's MAC
- Upload the code and the controller will automatically pair
# Using PlatformIO
pio run --target upload
# Or use VS Code PlatformIO extension
# Click "Upload" button in PlatformIO toolbar| Control | Function | Description |
|---|---|---|
| ๐น๏ธ Left Stick X | Aileron | |
| ๐น๏ธ Right Stick X | Rudder | |
| ๐น๏ธ Right Stick Y | Elevator | |
| ๐๏ธ R2 Trigger | Engine | ๐ Throttle control |
| โฌ๏ธ D-Pad Up | Elevator Trim + | |
| โฌ๏ธ D-Pad Down | Elevator Trim - | |
| โก๏ธ D-Pad Right | Aileron Trim + | |
| โฌ ๏ธ D-Pad Left | Aileron Trim - | |
| ๐ด L1 | Flaps Down | ๐ชถ Decrease flaps |
| ๐ด R1 | Flaps Up | ๐ชถ Increase flaps |
| ๐ L3 | Reset Aileron Trim | ๐ Center aileron |
| ๐ R3 | Reset Elevator Trim | ๐ Center elevator |
| โ Cross | Disable Emergency | ๐ Enable flight |
| โญ Circle | Emergency Stop | ๐จ Immediate stop |
| ๐ PS Button | Airbrake | ๐ Enable airbrake |
The system uses a custom LoRa packet format:
e[engine]a[aileron]r[rudder]l[elevator]t[trim]i[aileron_trim]f[flaps]z[reset_a]y[reset_e]b[airbrake]#[checksum]
- Engine: 0-180 (mapped from 0-4095 analog input)
- Control Surfaces: 0-180 (mapped from controller input)
- Trim: ยฑvalues for fine adjustment
- Flaps: 0-4 discrete positions
- Checksum: XOR validation byte
- Control Positions: Live aileron, elevator, rudder values
- Engine Status: Throttle percentage with ๐ indicator
- Emergency Status: ๐จ STOP indicator when active
- Flaps Position: Current flap setting ๐ชถ
- Developer Info: ๐จโ๐ป Arsalan Iravani
- ๐ต Bluetooth: Connection status indicator
- ๐ Battery: Controller battery percentage
- โก Charging: Active charging indicator
- ๐ถ WiFi: Network status (when applicable)
- Automatic Stop: Engine cuts to zero on emergency activation
- Connection Loss: Safety engagement if controller disconnects
- Input Validation: All commands verified with checksums
- Redundant Controls: Multiple ways to activate emergency stop
- Stick Deadzone: Idle deviation threshold prevents accidental inputs
- Rate Limiting: Flap changes limited to prevent servo damage
- Range Mapping: All inputs mapped to safe servo ranges
Ground Lora/
โโโ ๐ LICENSE # ๐ MIT License file
โโโ ๐ platformio.ini # ๐ง Build configuration with dual-core flags
โโโ ๐ README.md # ๐ This file
โโโ ๏ฟฝ include/ # ๐ Header files directory
โ โโโ ๐ common.h # ๏ฟฝ Shared definitions and pin config
โ โโโ ๐ Display.h # ๐ฅ๏ธ Display interface
โ โโโ ๐ images.h # ๏ฟฝ๏ธ Display graphics and icons
โ โโโ ๐ main.h # ๐ Main function declarations
โ โโโ ๐ PS5Joystick.h # ๐ฎ Controller interface
โ โโโ ๐ SD-Card.h # ๐พ SD card interface
โโโ ๐ src/ # ๐ Source code directory
โ โโโ ๐ main.cpp # ๐ Main program with dual-core tasks
โ โโโ ๐ Display.cpp # ๐ฅ๏ธ OLED display management
โ โโโ ๐ Lora.cpp # ๐ก LoRa communication
โ โโโ ๐ PS5Joystick.cpp # ๐ฎ Controller handling (no mutex)
โ โโโ ๐ SD-Card.cpp # ๐พ SD card functionality
โโโ ๐ lib/ # ๐ Libraries directory
โ โโโ ๐ PS5Library/ # ๐ฎ PS5 controller library
โ โโโ ๐ component.mk # ๐ Component makefile
โ โโโ ๐ Kconfig # โ๏ธ Configuration file
โ โโโ ๐ keywords.txt # ๐ค Arduino IDE keywords
โ โโโ ๐ library.properties # ๐ Library properties
โ โโโ ๐ PACKET_ANALYSIS.md # ๐ก Packet analysis documentation
โ โโโ ๐ README.md # ๏ฟฝ Library documentation
โ โโโ ๐ SENSOR_IMPLEMENTATION.md # ๐ Sensor implementation details
โ โโโ ๐ examples/ # ๐ Example implementations
โ โ โโโ ๐ ps5_advanced_sensors.ino # ๐งช Advanced sensors example
โ โ โโโ ๐ ps5_packet_debug.ino # ๐ Packet debugging example
โ โ โโโ ๐ ps5_sensors_example.ino # ๏ฟฝ Basic sensors example
โ โโโ ๐ src/ # ๐ Library source code
โ โโโ ๐ ps5_int.h # ๐ Internal PS5 definitions
โ โโโ ๐ ps5_l2cap.c # ๐ก L2CAP protocol implementation
โ โโโ ๐ ps5_parser.c # ๏ฟฝ Data parser implementation
โ โโโ ๐ ps5_spp.c # ๐ถ SPP protocol implementation
โ โโโ ๐ ps5.c # ๐ฎ Core PS5 functionality
โ โโโ ๐ ps5.h # ๐ฎ PS5 header file
โ โโโ ๐ ps5Controller.cpp # ๐ฎ Controller class implementation
โ โโโ ๐ ps5Controller.h # ๐ฎ Controller class header
โ โโโ ๐ osi/ # ๐ OS interface
โ โ โโโ ๐ allocator.h # ๐พ Memory allocator
โ โโโ ๐ stack/ # ๏ฟฝ Bluetooth stack
โ โโโ ๐ bt_types.h # ๐ต Bluetooth type definitions
โ โโโ ๐ btm_api.h # ๐ต BTM API definitions
โ โโโ ๐ gap_api.h # ๐ต GAP API definitions
โ โโโ ๐ hcidefs.h # ๐ต HCI definitions
โ โโโ ๐ l2c_api.h # ๐ต L2C API definitions
โ โโโ ๏ฟฝ l2cdefs.h # ๐ต L2C definitions
โโโ ๏ฟฝ๐ Resources/ # ๐ Resource files directory
โ โโโ ๐ blIcon.png # ๐ต Bluetooth icon
โ โโโ ๐ charging.png # โก Charging indicator icon
โ โโโ ๐ ps5 icon.png # ๐ฎ PS5 controller icon
โ โโโ ๐ PS5-Controller-PNG-Image.png # ๐ฎ Controller image
โ โโโ ๐ wifiIcon.png # ๐ถ WiFi status icon
โโโ ๐ test/ # ๐ Unit tests directory
โโโ ๐ README # ๐ Test documentation
โโโ ๐ test_config.py # โ๏ธ Test configuration file
โโโ ๐ test_display/ # ๐ฅ๏ธ Display tests
โ โโโ ๐ test_display.cpp # ๐งช Display unit tests
โโโ ๐ test_integration/ # ๐ Integration tests
โ โโโ ๐ test_integration.cpp # ๐งช Integration unit tests
โโโ ๐ test_lora/ # ๐ก LoRa tests
โ โโโ ๐ test_lora.cpp # ๐งช LoRa unit tests
โโโ ๐ test_main/ # ๐ Main tests
โ โโโ ๐ test_main.cpp # ๐งช Main functionality tests
โโโ ๐ test_ps5/ # ๐ฎ PS5 controller tests
โ โโโ ๏ฟฝ test_ps5.cpp # ๐งช PS5 controller unit tests
โโโ ๐ test_safety/ # ๏ฟฝ๏ธ Safety system tests
โ โโโ ๐ test_safety.cpp # ๐งช Safety feature tests
โโโ ๐ test_utilities/ # ๐ง Utility tests
โโโ ๐ test_utilities.cpp # ๐งช Utility function tests
main.cpp: Dual-core task implementation with FreeRTOScommon.h: Shared definitions, pin configurations, and extern declarationsmain.h: Function declarations for dual-core tasks and system functions
PS5Joystick.cpp/.h: PS5 controller handling with optimized callback functionsPS5Library/: Complete PS5 DualSense library with advanced featuresps5Controller.cpp/.h: Main controller class implementationps5.c/.h: Core PS5 functionality and protocol handlingexamples/: Sample implementations for various PS5 features
Display.cpp/.h: OLED display management with frame-based UIimages.h: Graphics definitions for icons and symbolsResources/: Icon and image assets for the display interface
Lora.cpp: LoRa communication with packet protocol and checksumsSD-Card.cpp/.h: SD card functionality for data logging
test/: Comprehensive unit testing suitetest_config.py: Python configuration for test automationtest_display/: Display functionality teststest_integration/: System integration teststest_lora/: LoRa communication teststest_main/: Core functionality teststest_ps5/: PS5 controller teststest_safety/: Safety system validation teststest_utilities/: Utility function tests
platformio.ini: Build configuration with dual-core optimization flagsLICENSE: MIT License fileREADME.md: This comprehensive documentation
- PlatformIO: VS Code extension or CLI
- ESP32 Toolchain: Automatically installed by PlatformIO (dual-core enabled)
- PS5 Controller: DualSense controller with Bluetooth
- Hardware: TTGO LoRa32 or compatible ESP32 board with LoRa module
# Clone the repository
git clone https://github.com/Arsalan134/Ground-Lora.git
cd Ground-Lora
# Build the project (with dual-core support)
pio run
# Upload to ESP32
pio run --target upload
# Monitor serial output (view dual-core performance stats)
pio device monitorThe project is configured for dual-core operation with optimized flags:
build_flags =
-std=gnu++17
-DCONFIG_FREERTOS_NUMBER_OF_CORES=2- Core 1 (Controller): 20Hz update rate for responsive control input
- Core 0 (Display): 10Hz update rate for smooth UI without blocking control
- LoRa Transmission: ~16.7Hz with smart packet optimization
- System Health: Monitored every 30 seconds with performance statistics
- RAM Usage: ~12% of 320KB (highly efficient)
- Flash Usage: ~87% with all features enabled
- Stack Usage: 8000 words per task with monitoring
- Heap Monitoring: Real-time memory leak detection
- Range: Several kilometers (LoRa 915MHz)
- Latency: <50ms typical (improved with dual-core)
- Pairing Failed: Check MAC address in
src/Common/common.h - No Response: Ensure controller is charged and in pairing mode
- Input Lag: Check for Bluetooth interference, dual-core should minimize lag
- Init Failed: Check antenna connections, system will continue without LoRa after 10 retries
- Poor Range: Verify antenna positioning and frequency settings
- Packet Loss: Check for interference on 915MHz band
- Blank Screen: Verify I2C connections (uses board default pins)
- Corrupted Display: Check power supply stability
- Slow Updates: Normal with dual-core - Core 0 handles display at 10Hz
- Watchdog Timeout: See
WATCHDOG_TIMEOUT_FIX.mdfor detailed solutions - Core Crashes: Check serial output for mutex warnings and stack usage
- Memory Issues: Monitor heap usage in performance statistics
- Task Failures: Verify stack high-water marks in health checks
- Check Serial Output: Look for dual-core performance statistics every 5 seconds
- Monitor System Health: Health checks appear every 30 seconds
- Stack Monitoring: Ensure >1000 words free space per task
- Heap Memory: Should stay >100KB for stable operation
- ๐ด Fork the repository
- ๐ฟ Create a feature branch (
git checkout -b feature/amazing-feature) - ๐พ Commit your changes (
git commit -m 'โจ Add amazing feature') - ๐ค Push to the branch (
git push origin feature/amazing-feature) - ๐ Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License Summary:
- โ Commercial use allowed
- โ Modification allowed
- โ Distribution allowed
- โ Private use allowed
- โ๏ธ Liability and warranty disclaimed
Arsalan Iravani
- ๐ GitHub: @Arsalan134
- Airplane: Companion dual-core receiver project for aircraft-side control
- PS5-ESP32: Enhanced PS5 controller library with dual-core support (included in lib/)
- ๐ Dual-Core Implementation Guide: Complete architecture documentation
- ๐ก๏ธ Watchdog Timeout Fix: System stability troubleshooting
- โ Implementation Summary: Development status and metrics
This is a dual-core remote control system for model aircraft. Always follow local regulations and safety guidelines when operating remote-controlled aircraft. The dual-core architecture provides enhanced safety features, but proper operation is still the responsibility of the user. The author is not responsible for any accidents or damages resulting from the use of this system.
๐ Happy Flying!