A Python-based emulator for Video Transmitter (VTX) devices that implements the SmartAudio protocol, commonly used in FPV (First Person View) drones.
This project provides a software emulation of a VTX device that can respond to SmartAudio protocol commands. It creates a TCP server that listens for incoming SmartAudio commands and responds with appropriate data, mimicking the behavior of a real VTX device.
The SmartAudio protocol is a popular standard used in FPV drones to control video transmitters, allowing flight controllers to change VTX settings such as channel, power level, and frequency.
- Emulates SmartAudio protocol versions 1, 2, and 2.1
- Supports all standard SmartAudio commands:
- Get Settings
- Set Power
- Set Channel
- Set Frequency
- Set Mode
- Implements proper CRC-8 validation
- Handles connection retries with exponential backoff
- Comprehensive logging
- Well-tested with unit tests
- Python 3.6 or higher
- Standard Python libraries (socket, time, logging)
Clone the repository:
git clone https://github.com/vkopitsa/vtx_emulator.git
cd vtx_emulatorNo additional dependencies are required as the project uses only standard Python libraries.
The project includes Docker support for easy deployment:
# Build and run using Docker
docker build -t vtx-emulator .
docker run -p 5762:5762 vtx-emulator
# Or use Docker Compose
docker-compose upYou can also use the Makefile for Docker operations:
# Build Docker image
make docker
# Run Docker container
make docker-run
# Run with Docker Compose
make docker-composeThe VTX Emulator can be integrated with both INAV and BetaFlight when running in SITL (Software In The Loop) mode, allowing you to test VTX control functionality without physical hardware.
INAV SITL can connect to the VTX Emulator to test SmartAudio communication:
-
Start the VTX Emulator first:
python run_emulator.py --ip 127.0.0.1 --port 5762
-
Configure INAV SITL to use the SmartAudio protocol on the appropriate port:
- In the INAV SITL configuration, set the VTX protocol to SmartAudio
- Configure the serial port that will communicate with the VTX Emulator
- Ensure the port matches the one used by the VTX Emulator (default: 5762)
-
Run INAV SITL with the appropriate configuration:
# Example command (actual command may vary based on your INAV SITL setup) ./inav_sitl --serial-device tcp://127.0.0.1:5762 --vtx-protocol smartaudio -
Use the INAV Configurator or CLI to change VTX settings, which will be sent to the emulator.
BetaFlight SITL can also be configured to work with the VTX Emulator:
-
Start the VTX Emulator:
python run_emulator.py --ip 127.0.0.1 --port 5762
-
Configure BetaFlight SITL:
- Set the VTX protocol to SmartAudio in the BetaFlight configuration
- Configure the appropriate UART port for SmartAudio communication
- Set the port to connect to the VTX Emulator's TCP server
-
Run BetaFlight SITL:
# Example command (actual command may vary based on your BetaFlight SITL setup) ./betaflight_sitl --serial tcp://127.0.0.1:5762 --vtx smartaudio -
Use the BetaFlight Configurator to change VTX settings and observe the communication with the emulator.
- Configuration Parameters: INAV and BetaFlight use slightly different configuration parameters for VTX control.
- CLI Commands: The CLI commands for configuring VTX settings differ between INAV and BetaFlight.
- SmartAudio Implementation: BetaFlight may use a more recent implementation of the SmartAudio protocol with additional features.
- Default Ports: The default serial port assignments may differ between the two firmwares.
For both flight controllers, you can verify the communication by checking the VTX Emulator logs, which will show the received commands and sent responses.
There are several ways to run the VTX emulator:
To start the VTX emulator with default settings:
python main_port.pyOr, if you've made the script executable:
./main_port.pyBy default, the emulator will:
- Listen on all interfaces (0.0.0.0)
- Use port 5762
- Attempt to reconnect if the connection is lost
For more flexibility, you can use the run_emulator.py script with command-line arguments:
python run_emulator.py --ip 127.0.0.1 --port 5763 --version 3 --channel 2 --power 1 --frequency 5800Available options:
--ip IP Server IP address (default: 0.0.0.0)
--port PORT Server port (default: 5762)
--version VERSION SmartAudio version (1, 2, or 3 for V2.1) (default: 2)
--channel CHANNEL Initial channel (default: 1)
--power POWER Initial power level (default: 0)
--frequency FREQ Initial frequency in MHz (default: 5865)
--retries RETRIES Maximum connection retries (default: 5000)
--delay DELAY Initial retry delay in seconds (default: 1)
--help Show this help message and exit
The project includes a Makefile for common tasks:
# Run the emulator with default settings
make run
# Run the emulator with command-line arguments
make run-args ARGS="--ip 127.0.0.1 --port 5763"
# Run basic unit tests
make test
# Run extended unit tests
make test-extended
# Run all unit tests
make test-all
# Install the package
make install
# Clean build artifacts
make clean
# Show help
make helpYou can also modify the settings directly in the Configuration class in main_port.py:
TCP_IP: Server IP address (default: '0.0.0.0')TCP_PORT: Server port (default: 5762)RETRY_DELAY: Initial delay in seconds before retrying (default: 1)MAX_RETRIES: Maximum number of retries (default: 5000)
The examples/ directory contains scripts demonstrating how to use the emulator:
custom_vtx_config.py: Shows how to use the emulator with custom configurationclient_example.py: Demonstrates how to connect to the emulator and send SmartAudio commands
Run the unit tests to verify the emulator's functionality:
python -m unittest test_main_port.py
python -m unittest test_main_port_extended.py[SYNC_BYTE][HEADER_BYTE][COMMAND][LENGTH][DATA...][CRC]
SYNC_BYTE: 0xAAHEADER_BYTE: 0x55COMMAND: Command IDLENGTH: Length of the data sectionDATA: Command-specific dataCRC: CRC-8 checksum (polynomial 0xD5)
| Command | ID | Description |
|---|---|---|
| GET_SETTINGS | 0x01 | Get current VTX settings |
| SET_POWER | 0x02 | Set VTX power level |
| SET_CHANNEL | 0x03 | Set VTX channel |
| SET_FREQUENCY | 0x04 | Set VTX frequency directly |
| SET_MODE | 0x05 | Set VTX mode (e.g., pit mode) |
main_port.py: Main emulator implementationrun_emulator.py: Script to run the emulator with command-line argumentstest_main_port.py: Basic unit teststest_main_port_extended.py: Extended unit testsexamples/: Example scripts demonstrating how to use the emulatorcustom_vtx_config.py: Example of using the emulator with custom configurationclient_example.py: Example client that connects to the emulator
docs/: Documentationsmartaudio_protocol.md: Detailed documentation of the SmartAudio protocol
Makefile: Makefile for common taskssetup.py: Setup script for installing the packagepyproject.toml: Configuration for Python tools (Black, isort, pytest)requirements.txt: List of dependencies (empty as only standard libraries are used)LICENSE: MIT License fileCHANGELOG.md: Changelog file to track changesCODE_OF_CONDUCT.md: Code of Conduct for contributorsSECURITY.md: Security policy and vulnerability reporting.gitignore: Git ignore file.editorconfig: EditorConfig file for consistent coding styles.dockerignore: Docker ignore fileDockerfile: Docker configuration filedocker-compose.yml: Docker Compose configuration file.github/workflows/: GitHub Actions workflowspython-tests.yml: Workflow for running tests on GitHub
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please read CONTRIBUTING.md for detailed guidelines on how to contribute to this project, CODE_OF_CONDUCT.md for our code of conduct, and SECURITY.md for our security policy and how to report security vulnerabilities.
This project is licensed under the MIT License - see the LICENSE file for details.
- The FPV community for developing and documenting the SmartAudio protocol
- All contributors to this project