A Kivy-based Digital Read-Out (DRO) and single-axis controller UI for rotary tables and similar devices, designed to run on Raspberry Pi or desktop environments (Windows, macOS, Linux). Interfaces via RS-485/Modbus RTU with a dedicated STM32-based control board.
🛒 Purchase all boards from our shop: Provvedo Shop
- Responsive touch-capable UI built with Kivy
- Communicates over RS-485 Modbus RTU with an STM32 controller (rotary-controller-f4)
- Configurable axes — add/remove axes, assign hardware scale inputs, apply transforms (identity, scaling, weighted sum, angle cos/sin)
- Electronic Lead Screw (ELS) mode for synchronized threading and power feed on manual lathes
- Sync mode with configurable gear ratios for spindle-synchronized movement
- Circle pattern calculator for bolt hole patterns
- Customizable display: fonts, colors, digit formats (metric/imperial/angle)
- Contextual help — info button on every setting field with documentation and examples
- Works on Raspberry Pi 3/4/5, Windows, macOS, and Linux
- Runs headless on Pi using the custom OSPI OS with pre-installed RCP (ospi)
-
Hardware
- Rotary controller board (STM32 firmware from rotary-controller-f4)
- RS-485 interface (e.g. via Power Hat)
- Raspberry Pi 3/4/5 for Pi deployments
-
Software
- Python 3.10+
uvpackage manager
git clone https://github.com/bartei/rotary-controller-python.git
cd rotary-controller-pythonInstall uv (Linux/macOS):
curl -LsSf https://astral.sh/uv/install.sh | shFor Windows, see the uv installation docs.
uv syncuv run python -m rcp.mainuv run pytest- Python >= 3.10
- Virtual environment managed automatically by
uv - Ensure your RS-485 adapter is accessible (check serial port permissions on Linux/macOS)
-
Install an SD card image from the OSPI project
-
RCP is pre-installed in
/root/rotary-controller-python/ -
To update:
sudo systemctl stop rotary-controller cd /root/rotary-controller-python git pull uv sync reboot -
View logs:
journalctl -u rotary-controller journalctl -xeu rotary-controller tail -n +1 /var/log/kivy*
rcp/
├── main.py # Entry point (asyncio + Kivy event loop)
├── app.py # MainApp class
├── feeds.py # Feed/thread pitch configurations
├── help/ # Contextual help documents (markdown)
├── components/ # UI layer
│ ├── home/ # Home screen (coordbar, servobar, elsbar, statusbar)
│ ├── screens/ # Full-screen views (setup, scale, servo, formats, etc.)
│ ├── widgets/ # Reusable form widgets with help button support
│ ├── popups/ # Modal dialogs (keypad, help, feeds table, etc.)
│ ├── toolbars/ # Toolbar buttons
│ └── plot/ # Plot/visualization
├── dispatchers/ # Event dispatchers and state management
│ ├── saving_dispatcher.py # Auto-persisting properties to YAML
│ ├── formats.py # Display format settings
│ ├── circle_pattern.py # Circle pattern calculator
│ └── board.py # Board/device event dispatcher
└── utils/ # Hardware communication layer
├── communication.py # ConnectionManager (Modbus RTU)
├── base_device.py # C typedef parser and register I/O
└── devices.py # Device type definitions
- Serial issues: Verify RS-485 wiring, correct serial port, and permissions
- Service failures (Pi): Check
journalctllogs and Kivy log files under/var/log/ - Display issues: Adjust font size and display format in the Formats setup screen
- Firmware & hardware: rotary-controller-f4
- PCB design & BOM: rotary-controller-pcb
- OSPI OS with pre-installed RCP: ospi
See CHANGELOG.md for detailed history, updates, and breaking changes.
Contributions are welcome! Please:
- Open issues for bugs or feature requests
- Submit pull requests or improvements
- Help with testing, documentation, porting new features
Join our Discord community for support, collaboration, and updates.
Licensed under MIT. See LICENSE for full terms.