Tricycletops is a Bluetooth Low Energy (BLE) controlled robotics/car platform consisting of:
tricycletops-fw: An asynchronous,no_stdRust firmware for the RP2040 (configured for Raspberry Pi Pico W) driving a dual-motor differential drive system via PWM.tricycletops-app: A Kotlin Jetpack Compose Android app acting as a BLE remote control to command the robotic car's speed and direction.
tricycletops/
├── tricycletops-fw/ # Async Rust Firmware (Embassy & trouble-host)
│ ├── src/ # Firmware source code (motors, BLE peripheral, main)
│ ├── .cargo/ # Embedded targets and build configurations
│ ├── memory.x # RP2040 memory map
│ └── Cargo.toml # Rust cargo manifest
│
└── tricycletops-app/ # Kotlin Android Application (Jetpack Compose)
├── app/ # Android application module source & configs
├── gradle/ # Declarative Gradle version catalogs
└── build.gradle.kts # Project-level build script
To compile and flash Rust firmware to the RP2040 micro-controller, install the following:
- Rust Toolchain: Use rustup to install Rust.
- Arm Cortex-M0+ Target: Install the compilation target for the RP2040:
rustup target add thumbv6m-none-eabi
- Picotool: Required to flash the RP2040 board over a USB cable without a debugger. Follow the Raspberry Pi Picotool Installation Guide to compile or install it on your OS.
- Probe-rs (Optional): If you use a physical SWD debug probe (like another Pico running Picoprobe), install probe-rs to flash and debug in real-time.
To compile and run the Android app:
- Java Development Kit (JDK 17 or higher): Download and install JDK from Eclipse Temurin.
- Android Studio: Install the official IDE from Android Studio Download. This automatically configures the Android SDK and build tools.
- Navigate to the firmware directory:
cd tricycletops-fw - Verify compilation:
Run a fast syntax and type check on the project:
cargo check --target thumbv6m-none-eabi
- Build the binary:
Compile the release-optimized binary:
Note: The compilation automatically downloads the necessary Cyw43 Wi-Fi/Bluetooth firmware binaries into
cargo build --release --target thumbv6m-none-eabi
target/cyw43-firmware/viabuild.rs. - Flash the RP2040 / Pi Pico W:
- Using Picotool (USB): Put your Pico W into BOOTSEL mode by holding the
BOOTSELbutton while plugging in the USB cable. Then run:This invokescargo run
picotool load -u -v -x -t elfas defined in.cargo/config.tomlto load and automatically start the program. - Using Probe-rs (Debugger): Edit
.cargo/config.tomlto swap the runner toprobe-rs run --chip RP2040and executecargo run.
- Using Picotool (USB): Put your Pico W into BOOTSEL mode by holding the
- Navigate to the app directory:
cd tricycletops-app - Compile and build the Debug APK:
Use the Gradle wrapper to build the package:
./gradlew assembleDebug
- Run tests:
Validate build sanity by executing the unit tests:
./gradlew test - Install on a Device/Emulator:
- Open the
tricycletops-appfolder inside Android Studio. - Connect your Android phone via USB with Developer Options & USB Debugging enabled, or start an Android Virtual Device (AVD) emulator.
- Click the green Run 'app' button (or press
Shift + F10) in Android Studio to build, deploy, and launch the application.
- Open the
When the firmware boots, the Raspberry Pi Pico W acts as a Bluetooth Low Energy (BLE) peripheral:
- Advertised Name:
TricycleTops - GATT Service UUID:
fff0(represented as[0xf0, 0xff]in advertising packets) - Characteristic UUID:
fff1(Read / Write, 8-byte payload)
To steer and move the Tricycletops car, write an 8-byte payload to characteristic fff1 containing two little-endian 32-bit floats (f32):
| Byte Range | Type | Value Range | Description |
|---|---|---|---|
| 0 to 3 | f32 (little-endian) |
-1.0 to 1.0 |
Left Motor Speed (Positive = Forward, Negative = Reverse, 0.0 = Stop) |
| 4 to 7 | f32 (little-endian) |
-1.0 to 1.0 |
Right Motor Speed (Positive = Forward, Negative = Reverse, 0.0 = Stop) |
The firmware outputs highly optimized debug logs over RTT (Real-Time Transfer).
- If using
probe-rs, logs will stream directly to your terminal. - The onboard LED on the Raspberry Pi Pico W blinks once per second when advertising, and changes state when a central BLE device connects/disconnects.