🎮 Control SPIKE Prime with WASD

🚀 What You'll Build

Control your robot using your keyboard:

  • W → Forward
  • S → Reverse
  • A → Turn Left
  • D → Turn Right
  • X → Stop
  • Q → Quit

🧰 Requirements

  • SPIKE Prime Hub
  • 2 Motors (A + B)
  • Mac or Windows Computer
  • Bluetooth Enabled
  • Python Installed

🔧 Step 1: Install Pybricks Firmware

Go to code.pybricks.com

⚠️ Use one of these browsers:
  • Google Chrome ✅
  • Microsoft Edge ✅
  • Chromium-based browsers ✅
  • Safari ❌ (does NOT work)
Steps:
  1. Plug your SPIKE hub into your computer
  2. Open Pybricks Code
  3. Click the menu → Install Pybricks Firmware
  4. Follow the on-screen instructions

💻 Step 2: Install Python

Download Python from the official website:

During installation:
  • ✅ Check "Add Python to PATH" (Windows users)
  • Use default settings unless you know otherwise

Verify installation by opening a terminal (Command Prompt, Terminal, or shell) and running:

python --version

If that doesn't work, try:

python3 --version

Install required packages:

pip install bleak pynput
If pip doesn't work, try:
  • pip3 install bleak pynput
  • python -m pip install bleak pynput

🧠 Step 3: Set Up Visual Studio Code

Download VS Code:
code.visualstudio.com
Steps:
  1. Open VS Code
  2. Click "Open Folder"
  3. Create a new folder (example: spike-control)
  4. Click "New File"
  5. Name it: spike_wasd.py
Recommended:
  • Install the Python extension in VS Code
  • Restart VS Code after installing
To run your script:
  • Open the Terminal inside VS Code (View → Terminal)
  • Run:
python spike_wasd.py

⚠️ Troubleshooting (All Systems)

  • If Python isn't recognized → restart your computer
  • If Bluetooth fails → make sure no other app is connected to the hub
  • If keyboard input doesn't work → check system permissions
Common fixes:
  • Mac → Enable Input Monitoring + Bluetooth for Terminal
  • Windows → Run terminal as Administrator
  • Linux → Ensure Bluetooth service is running

🤖 Step 4: Upload Code to SPIKE Hub

Open Pybricks and paste this code:

from pybricks.pupdevices import Motor
from pybricks.parameters import Port
from pybricks.tools import wait

from usys import stdin, stdout
from uselect import poll

left = Motor(Port.A)
right = Motor(Port.B)

keyboard = poll()
keyboard.register(stdin)

while True:
    stdout.buffer.write(b"rdy")

    while not keyboard.poll(0):
        wait(10)

    cmd = stdin.buffer.read(3)

    if cmd == b"fwd":
        left.dc(60)
        right.dc(60)
    elif cmd == b"rev":
        left.dc(-60)
        right.dc(-60)
    elif cmd == b"lft":
        left.dc(-40)
        right.dc(40)
    elif cmd == b"rgt":
        left.dc(40)
        right.dc(-40)
    elif cmd == b"stp":
        left.stop()
        right.stop()
    elif cmd == b"bye":
        left.stop()
        right.stop()
        break
Plug motors:
  • Port A → Left
  • Port B → Right

💻 Step 5: Python Keyboard Controller

Paste this into your spike_wasd.py file:

import asyncio
from bleak import BleakScanner, BleakClient
from pynput import keyboard

UUID = "c5f50002-8280-46da-89f4-6d8051e4aeef"
HUB_NAME = "Pybricks Hub"

pressed = set()
ready = asyncio.Event()

def key_char(key):
    try:
        return key.char.lower()
    except:
        return None

def on_press(key):
    k = key_char(key)
    if k:
        pressed.add(k)

def on_release(key):
    k = key_char(key)
    if k and k in pressed:
        pressed.remove(k)

async def main():
    device = await BleakScanner.find_device_by_name(HUB_NAME)

    if not device:
        print("Hub not found.")
        return

    async with BleakClient(device) as client:

        def rx(_, data):
            if data and data[0] == 0x01:
                if data[1:] == b"rdy":
                    ready.set()

        await client.start_notify(UUID, rx)

        async def send(cmd):
            await ready.wait()
            ready.clear()
            await client.write_gatt_char(UUID, b"\x06" + cmd, response=True)

        listener = keyboard.Listener(on_press=on_press, on_release=on_release)
        listener.start()

        print("Connected! Press hub button to start.")

        while True:
            if 'q' in pressed:
                await send(b"bye")
                break
            elif 'x' in pressed:
                await send(b"stp")
            elif 'w' in pressed:
                await send(b"fwd")
            elif 's' in pressed:
                await send(b"rev")
            elif 'a' in pressed:
                await send(b"lft")
            elif 'd' in pressed:
                await send(b"rgt")
            else:
                await send(b"stp")

            await asyncio.sleep(0.05)

        listener.stop()

asyncio.run(main())

▶️ Step 6: Run the Program

python3 spike_wasd.py
1. Run the script 2. Press the center button on the hub 3. Drive with WASD 🎮

⚠️ Mac Permissions (IMPORTANT)

  • Allow Bluetooth for Terminal
  • Allow Input Monitoring for Terminal