The codebase is operating-system independent for development. Hardware-bound pieces (MetaWear over Bluetooth, motor drivers) are meant to run on the Raspberry Pi, so you can develop on any platform and run the full stack on the Pi.
It is recommended to use WSL; that is what our team used. A guide to installing WSL can be found at https://ycpcs.github.io/dev-env-setup-guide/ under the Windows 11: WSL2 guide (Personal Computer) section. The instructions below focus on the relevant steps.
- Enable Virtualization in your PC BIOS/UEFI
- Install WSL2 and an Ubuntu 24.04 LTS Virtual Machine
- A. I Already Have WSL Installed
- Opening WSL
- Running the project
- Setting up VS Code with WSL
Follow the full virtualization instructions in:
Follow the full WSL2 + Ubuntu installation instructions in:
Source for both guides: YCP Dev Environment Setup Guide See the linked guide pages for full attribution and copyright.
If WSL is already installed, you can skip the virtualization and installation sections above and continue at Opening WSL.
-
Open the WSL application:
- Press
Win + Rto open the Run dialog - Type
wsland press Enter - Alternatively, search for "WSL" or "Ubuntu" in the Windows Start menu
- Press
-
You'll now be in a Linux terminal where you can run the commands below.
Clone the repo:
git clone https://github.com/YCP-Rev-Metrix/BallSpinner-Controller-v2/
cd BallSpinner-Controller-v2Check Python version
This project targets Python 3.13:
python3 --versionIf you need 3.13 on Ubuntu/WSL, add the deadsnakes PPA first, then install:
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.13 python3.13-venvMore info on deadsnakes PPA.
Create virtual environment and install dependencies
python3 -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txtRun the app
python main.py-
Install VS Code on Windows (if not already installed)
- Download from https://code.visualstudio.com/
-
Open the project in VS Code
- In WSL, from your repo folder, try:
code .- If that fails with
Exec format errororcode: command not found, run this from Windows PowerShell instead:
code --remote wsl+Ubuntu /home/matty/BallSpinner-Controller-v2
- If you still want to launch from WSL and
code .continues to fail, repair WSL interop in WSL:
sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf' sudo systemctl unmask systemd-binfmt.service sudo systemctl restart systemd-binfmt code .
-
Run the project from VS Code
- Open the integrated terminal (Ctrl+`)
- Ensure the terminal is in WSL
- Activate the virtual environment:
source venv/bin/activate - Run the app:
python main.py
See the UI guide in BSC_Ui_README.md for how to set up Qt Designer and the page workflow.
Install Homebrew and Python 3.13, then create a virtual environment and install dependencies:
# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Add Homebrew to your shell (Apple Silicon)
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
# Install Python 3.13
brew update
brew install python@3.13
python3.13 --versionCreate a virtual environment and install dependencies:
python3.13 -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txtRun the app
python main.pyFor UI work, see BSC_Ui_README.md.
Preferred option (no manual venv activation required):
powershell -ExecutionPolicy Bypass -File .\build_windows.ps1Manual option:
py -3.13 -m venv venv
venv\Scripts\python.exe -m pip install --upgrade pip
venv\Scripts\python.exe -m pip install -r requirements.txt pyinstaller
venv\Scripts\python.exe -m PyInstaller --clean -y main.specAfter installing dependencies in the virtual environment, build with PyInstaller:
source venv/bin/activate
pip install pyinstaller
python -m PyInstaller --clean -y main.specBuild output is created in dist/, typically:
dist/BallSpinnerController/dist/BallSpinnerController.app
If PyInstaller warns about macOS codesigning, the bundle is still generated but may need manual signing for distribution.
This guide will walk you through setting up a Raspberry Pi to run the BallSpinner-Controller-v2 application.
- Raspberry Pi with Raspbian Trixie OS flashed
- Access to YCP network credentials
- Working computer for SSH access
- Initial Setup
- Network Configuration
- SSH Configuration
- VNC Configuration
- GitHub SSH Key Setup
- Repository Setup
- System Updates
- Python Installation
- Motor Driver Requirements
- GPIO Defaults
- MetaWear SDK Installation
- Testing
Flash Raspbian Trixie to your Raspberry Pi OS -- 64 Bit OS!!
Option 1: York Connect
- Register the Pi's MAC address at: https://clearpass.ycp.edu/guest/guest_index.php
Option 2: eduroam
- Select eduroam from the network dropdown
- Choose "No CA certificate is required"
- Use your YCP credentials to connect
Enable SSH connection on your Raspberry Pi:
sudo raspi-configNavigate to:
- Interface settings → SSH → Enable SSH
On the Raspberry Pi, run:
hostname -IFrom your personal computer:
ssh RPIname@IPAddressReplace RPIname with your Pi's hostname and IPAddress with the IP address from the previous step.
If you run pi_install.sh, VNC should already be enabled (the installer prompts to enable it, default is Y).
If needed, you can enable it manually:
sudo raspi-config nonint do_vnc 0
sudo systemctl enable vncserver-x11-serviced.service
sudo systemctl restart vncserver-x11-serviced.service- Generate a new SSH key on the Pi (run this in a terminal on the Raspberry Pi). Use your GitHub email in the
-Cfield so the key is labeled; it does not log you in by itself.
ssh-keygen -o -t rsa -b 4096 -C "you@example.com"ssh-keygen will ask a few questions:
- File to save the key — press Enter to accept the default (
/home/<you>/.ssh/id_rsa). That is what the steps below expect. - Passphrase — you can press Enter twice for no passphrase (simpler on a headless Pi) or set one (more secure; you will need to enter it when using the key).
Only the public key (the .pub file) ever leaves the Pi. Never copy or share the private key file (id_rsa without .pub).
- Show the public key and copy it to the clipboard, or copy from the terminal after running:
cat ~/.ssh/id_rsa.pubThe line should start with ssh-rsa and end with the same comment you passed to -C. Copy the entire single line.
- Add the key in GitHub (in a browser, on your computer is fine):
- Open GitHub → Settings → SSH and GPG keys
- New SSH key
- Title — e.g.
Raspberry Pi(any name you will recognize) - Key — paste the line you copied
- Add SSH key
- Test the connection from the Pi (optional but recommended):
ssh -T git@github.comThe first time, type yes if asked to trust the host. You should see a message that GitHub does not provide shell access, which means authentication worked.
git clone git@github.com:YCP-Rev-Metrix/BallSpinner-Controller-v2.gitAfter cloning the repo on the Pi, run the single interactive installer. It installs system dependencies, can enable VNC for remote desktop access, creates the virtual environment, builds MetaWear/PyWarble, runs unit tests, and then starts the app via startup.sh. It can optionally configure autostart and logs to logs/pi_install.log.
cd BallSpinner-Controller-v2
chmod +x pi_install.sh
./pi_install.shUpdate your system packages:
sudo apt update
sudo apt upgradeUpgrade to Python 3.13:
First check your version, if you are already running 3.13 then you are all good.
python3 --versionelse install python3.13
sudo apt install software-properties-common
sudo apt install --reinstall python3-launchpadlib
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.13 python3.13-venvcd BallSpinner-Controller-v2
python3 -m venv venv
source venv/bin/activateInside the cloned directory and virtual environment:
pip install -r requirements-pi.txtInstall requirements for motor drivers:
sudo apt-get install liblgpio-dev
sudo apt install swig
pip install rpi-lgpioSet BCM pins 5 and 6 to output low at boot by editing /boot/firmware/config.txt:
sudo cp /boot/firmware/config.txt /boot/firmware/config.txt.bak
sudo nano /boot/firmware/config.txtAdd this block at the end of the file:
# >>> BallSpinner GPIO defaults >>>
gpio=5,6=op,dl
# <<< BallSpinner GPIO defaults <<<Reboot the Pi to apply the boot-time defaults.
If you use pi_install.sh, it can add this block automatically.
The MetaWear SDK allows connection to MetaMotionS devices via Bluetooth.
sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev libboost-all-dev build-essentialsource venv/bin/activategit clone --recurse-submodules git@github.com:mbientlab/MetaWear-SDK-Python.git
cd MetaWear-SDK-Python
git clone --recurse-submodules https://github.com/mbientlab/PyWarble.git
cd PyWarble/clibs/warble/deps/libbleppcd PyWarble/clibs/warble/deps/libblepp
./configure
makeExpected output:
-------------- Test Results ---------------
test_scan: OK
-------------------------------------------
Set environment variables (replace [YOUR PATH TO] with your actual path):
export BLEPP_LIB="[YOUR PATH TO]/PyWarble/clibs/warble/deps/libblepp"
export LD_LIBRARY_PATH="$BLEPP_LIB:$LD_LIBRARY_PATH"Example:
export BLEPP_LIB="/home/ballz/MetaWear-SDK-Python/PyWarble/clibs/warble/deps/libblepp"
export LD_LIBRARY_PATH="$BLEPP_LIB:$LD_LIBRARY_PATH"Test the library (in the libblepp directory):
sudo LD_LIBRARY_PATH="/home/ballz/MetaWear-SDK-Python/PyWarble/clibs/warble/deps/libblepp" ./lescanIf you encounter Bluetooth issues, try these commands:
sudo systemctl status bluetooth
sudo systemctl start bluetooth
rfkill list
sudo rfkill unblock bluetooth
hciconfig
sudo hciconfig hci0 upcd PyWarble/clibs/warble
nano MakefileEdit the ARCH= line in the Makefile, then:
Change it to ARCH=-march=armv8-a
makeSet environment variables (replace [YOUR PATH TO] with your actual path):
export BLEPP_LIB="[YOUR PATH TO]/PyWarble/clibs/warble/deps/libblepp"
export WARBLE_BUILD="[YOUR PATH TO]/PyWarble/clibs/warble/dist/release/lib/arm"
export LD_LIBRARY_PATH="$BLEPP_LIB:$WARBLE_BUILD:$LD_LIBRARY_PATH"From the PyWarble directory:
cd ~/MetaWear-SDK-Python/PyWarble
pip install .sudo setcap cap_net_raw+eip $(eval readlink -f $(which python3))- Find the MAC address for your MetaMotion device
- Test the connect.py script:
python3 connect.py "MacAddress of device"
If it fails, restart Bluetooth and initiate a scan:
sudo systemctl restart bluetooth
bluetoothctl
scan on
scan offsudo nano src/metawear/dfu/cpp/json.hppAdd this include at the top:
#include <cstdint>In the MetaWear-SDK-CPP directory:
cd ~/MetaWear-SDK-Python/MetaWear-SDK-Cpp
make CXX=g++ CXXFLAGS="-Wall -fPIC -std=c++14 -I$(pwd)/src" -j$(nproc)A successful build will show these lines at the end:
ln -sf libmetawear.so.0.20.7 dist/release/lib/arm/libmetawear.so.0
ln -sf libmetawear.so.0 dist/release/lib/arm/libmetawear.soSet all library locations and add them to your environment (replace [YOUR PATH TO] with your actual paths):
export METAWEAR_HEADERS="[YOUR PATH TO]/MetaWear-SDK-Python/MetaWear-SDK-Cpp/src/metawear"
export METAWEAR_LIB="[YOUR PATH TO]/MetaWear-SDK-Python/MetaWear-SDK-Cpp/dist/release/lib/arm"
export BLEPP_LIB="[YOUR PATH TO]/PyWarble/clibs/warble/deps/libblepp"
export BLEPP_HEADERS="[YOUR PATH TO]/PyWarble/clibs/warble/deps/libblepp/blepp"
export WARBLE_BUILD="[YOUR PATH TO]/PyWarble/build/lib/mbientlab/warble"
export LD_LIBRARY_PATH="$METAWEAR_LIB:$BLEPP_LIB:$WARBLE_BUILD:$LD_LIBRARY_PATH"
export CFLAGS="-I$METAWEAR_HEADERS -I$BLEPP_HEADERS"
export LDFLAGS="-L$METAWEAR_LIB -L$BLEPP_LIB -L$WARBLE_BUILD"Example with actual paths:
export METAWEAR_HEADERS="/home/ballz/MetaWear-SDK-Python/MetaWear-SDK-Cpp/src/metawear"
export METAWEAR_LIB="/home/ballz/MetaWear-SDK-Python/MetaWear-SDK-Cpp/dist/release/lib/arm"
export BLEPP_LIB="/home/ballz/MetaWear-SDK-Python/PyWarble/clibs/warble/deps/libblepp"
export BLEPP_HEADERS="/home/ballz/MetaWear-SDK-Python/PyWarble/clibs/warble/deps/libblepp/blepp"
export WARBLE_BUILD="/home/ballz/MetaWear-SDK-Python/PyWarble/build/lib/mbientlab/warble"
export LD_LIBRARY_PATH="$METAWEAR_LIB:$BLEPP_LIB:$WARBLE_BUILD:$LD_LIBRARY_PATH"
export CFLAGS="-I$METAWEAR_HEADERS -I$BLEPP_HEADERS"
export LDFLAGS="-L$METAWEAR_LIB -L$BLEPP_LIB -L$WARBLE_BUILD"Note: To make these environment variables persistent across sessions, add them to your ~/.bashrc or ~/.profile file.
cd ~/MetaWear-SDK-Python
pip install .Run the main application:
python main.pyOptional test runners:
./run_unit_tests.sh
./run_integration_tests.shExpected Result: The application should open and you should now be using the BallSpinner-Controller-v2.
Use VNC when you want to control the Pi desktop remotely and interact with the app UI.
pi_install.sh should already enable VNC during setup (default prompt is Y).
-
In the app, open Cloud Test.
-
Read the IP shown in the top-right menu bar (
IP: ...). -
On your Mac, open Screen Sharing (Finder -> Go -> Connect to Server) and connect to:
vnc://PI_IP_ADDRESS -
Log in with your Pi username and password.
Manual fallback if VNC was previously disabled:
sudo raspi-config nonint do_vnc 0
sudo systemctl enable vncserver-x11-serviced.service
sudo systemctl restart vncserver-x11-serviced.serviceIf you are off-campus or off-LAN, use a VPN solution (for example Tailscale) and connect using the VPN IP.
- Make sure your virtual environment is activated (
source venv/bin/activate) before running Python commands - Keep track of your actual file paths and update the environment variables accordingly
- If you encounter issues, refer to the troubleshooting sections for Bluetooth and library path configuration