VEXcode V5 Guide
Configuration. Code. Calibration. The full workflow for building a competition-ready VEXcode V5 project from scratch. Companion to the architecture reference; use the Setup Guide instead if you just want to import an existing project.
CONTENTSWhat this guide covers
PART 1Starting a new project
- Open VEXcode V5 (the standalone IDE — Blocks + Text app, not VS Code)
- File → New Text Project → C++
- When asked for a template, pick Empty Project (or "Plain C++")
- File → Save As, give it a name like
Clawbot-2822 - The IDE creates
main.cpp,vex.h, and (depending on template)robot-config.h/cpp
PART 2Configuring hardware — two paths
VEXcode V5 has two ways to tell the brain about your motors and sensors. Pick one and stick with it — mixing them causes redefinition errors.
| Aspect | Path A: Devices Wizard | Path B: Manual Code Declaration |
|---|---|---|
| How | Open Devices panel → click + → configure graphically | Write motor LeftDrive = motor(PORT1, ratio18_1, false); in main.cpp |
| Auto-names motors? | Yes — e.g., LeftDriveSmart, DrivetrainInertial | No — you name them |
| GUI port testing | Yes — click device in panel to test | No — write a test routine in code |
| Version-control friendly | Hidden in project metadata | Yes — visible in main.cpp |
| Share across robots | Tedious — recreate by clicking | Yes — paste Section 1 |
| Recommended for | Solo students, prototyping | Team projects, competition robots |
Path A — Devices wizard step-by-step
The Devices button is in the top of the left sidebar. Click it to open the Devices panel. To add any device, click Add a Device, pick the device type, configure it, and click Done.
Add devices in this order for cleanest results:
- Controller — always first, gates everything else
- Drivetrain — if your robot has one (do this before adding individual motors so the wizard knows which ports are taken)
- Individual smart motors — arm, claw, intake, anything not in the Drivetrain
- Smart-port sensors — Distance, Optical, Vision / AI Vision
- 3-wire devices — Limit switches, potentiometers, bumpers
1. Adding a Controller
- Click Add a Device → Controller
- Click Done (no other options to set)
Auto-generated code: controller Controller1 = controller(primary);
2. Adding an individual Smart Motor (arm, claw, intake)
- Click Add a Device → Motor
- Select the port (1-21). Ports already used by other devices appear grayed out.
- Rename the motor (default is Motor1, Motor2, etc.). Use meaningful names like
Arm,Claw,Intake. - Pick the cartridge: Red (100 RPM) / Green (200 RPM) / Blue (600 RPM). Must match what's physically in the motor.
- Check Reversed if the motor spins the wrong direction (test in driver control; flip if backwards).
- Click Done
Auto-generated code: motor Arm = motor(PORT8, ratio36_1, false);
3. Adding a Drivetrain (2-motor or 4-motor)
Only one Drivetrain per project. Picks up ports for both motors plus the IMU in one step.
- Click Add a Device → Drivetrain 2-Motor or Drivetrain 4-Motor
- Select the ports for the Left motors (e.g., port 1 for 2-motor; ports 1 and 2 for 4-motor)
- Select the ports for the Right motors (e.g., port 10; or 9 and 10)
- (Recommended) Click Inertial Sensor and select its port (e.g., 11). Required for IMU-corrected PID autons.
- Set Wheel Size (e.g., 4" for Clawbot), Gear Ratio (usually 1:1), and Gear Cartridge (must match physical motors)
- Click Done
Auto-generated code:
motor LeftDriveSmart = motor(PORT1, ratio18_1, false);
motor RightDriveSmart = motor(PORT10, ratio18_1, true);
inertial DrivetrainInertial = inertial(PORT11);
smartdrive Drivetrain = smartdrive(LeftDriveSmart, RightDriveSmart,
DrivetrainInertial, 319.19, 295, 40, mm, 1);
LeftDriveSmart / RightDriveSmart, IMU as DrivetrainInertial, smartdrive as Drivetrain. You reference these exact names in your code's usercontrol (for arcade-drive mixing) and pre_auton (for IMU calibration). Spelling them wrong is the #1 cause of build errors when starting out.
4. Adding 3-wire devices (limit switch, potentiometer, bumper, gyro)
3-wire devices plug into the brain's ADI ports (labeled A-H). Same workflow regardless of device type.
- Click Add a Device → 3-Wire Devices
- Pick the specific device: Limit Switch, Bumper Switch, Potentiometer, Encoder, Line Tracker, etc.
- Select the 3-wire port (A-H). Ports already in use are grayed out.
- Rename to something meaningful:
ArmTop,ArmBot,ArmPot,FrontBumper, etc. - Click Done
Auto-generated code:
limit ArmTop = limit(Brain.ThreeWirePort.A); limit ArmBot = limit(Brain.ThreeWirePort.B); pot ArmPot = pot(Brain.ThreeWirePort.C); bumper FrontBumper = bumper(Brain.ThreeWirePort.D);
5. Adding smart-port sensors (Distance, Optical, Vision)
Smart-port sensors are simpler than 3-wire — just port assignment.
- Click Add a Device → pick from Distance, Optical, GPS, etc.
- Select the smart port (1-21). Avoid ports used by the Drivetrain or individual motors.
- Rename to something meaningful:
BackDist,ClawOptical - Click Done
Auto-generated code: distance BackDist = distance(PORT5); · optical ClawOptical = optical(PORT4);
6. Adding a V5 Vision Sensor (older) or AI Vision Sensor (new)
Vision sensors require an extra calibration step beyond just picking a port — you train them to recognize colors (and, for AI Vision, AprilTags and AI classifications).
- Click Add a Device → Vision Sensor or AI Vision Sensor
- Select the smart port
- (AI Vision only) Connect via USB-C to the computer when prompted
- The configuration window opens with the live camera feed
- Drag a box over a colored object to teach the sensor a Color Signature
- (Optional) Add 2+ signatures to create Color Codes (sequences of colors)
- (AI Vision only) Toggle AprilTag detection or AI Classifications on/off — no per-tag setup needed, the sensor detects all standard AprilTags
- Click Done
Auto-generated code (AI Vision with AprilTags enabled):
aivision AIVision1 = aivision(PORT7, aivision::ALL_AIOBJS,
aivision::ALL_TAGS);
See the Vision Sensor + AprilTags page for project ideas and integration patterns once vision is configured.
Editing or deleting devices
After a device is added:
- Edit: Click the device in the Devices panel → change port, rename, flip reversed, click Done
- Delete: Click the device → Delete button at the bottom. Warning: if your code references the device by name, you'll get build errors after deletion. Update or remove the references first.
Official VEX references (step-by-step with screenshots)
VEX publishes detailed walkthroughs with screenshots for each device type. Use those when you need the visual reference; come back here for what the wizard produces (the auto-generated names your code uses).
- Configuring V5 Smart Motors in VEXcode V5 ↗
- Configuring 3-Wire Devices in VEXcode V5 ↗
- Configuring a 4-Motor Drivetrain in VEXcode V5 ↗
- Configuring the V5 Controller in VEXcode V5 ↗
- Adding the V5 Vision Sensor as a Device in VEXcode V5 ↗
- Getting Started with the AI Vision Sensor ↗
Path B — manual declaration in code
main.cpp for you to paste. Updates live as you change inputs.
Skip the Devices panel entirely. Put all hardware in Section 1 of your main.cpp:
controller Controller1 = controller(primary);
motor LeftDriveSmart = motor(PORT1, ratio18_1, false);
motor RightDriveSmart = motor(PORT10, ratio18_1, true);
inertial DrivetrainInertial = inertial(PORT11);
smartdrive Drivetrain = smartdrive(
LeftDriveSmart, RightDriveSmart, DrivetrainInertial,
319.19, 320, 40, mm, 1.0);
motor Arm = motor(PORT8, ratio36_1, false);
motor Claw = motor(PORT3, ratio36_1, false);
limit ArmTop = limit(Brain.ThreeWirePort.A);
limit ArmBot = limit(Brain.ThreeWirePort.B);
pot ArmPot = pot(Brain.ThreeWirePort.C);
competition Competition;
Motor cartridges — the right value matters
| Cartridge code | Color | Free-speed RPM | Best for |
|---|---|---|---|
ratio6_1 | BLUE | 600 RPM | Fast drive, intake rollers |
ratio18_1 | GREEN | 200 RPM | Most drives, lifts (stock Clawbot) |
ratio36_1 | RED | 100 RPM | High-torque mechanisms (arms, claws) |
ratio6_1 (600 RPM) but you physically have green cartridges (200 RPM), PID drive distances will be 3x off. Pop a motor cap and check the actual cartridge color before tuning anything.
PART 3Understanding the code — the 9-section architecture
The reference projects organize main.cpp into 9 banner-commented sections. Each section has one job. To find any section, use Ctrl+F and search for SECTION N.
| Section | What it does |
|---|---|
| 1. HARDWARE | Motor/sensor/pneumatic definitions. Only section to edit for port changes. |
| 2. FORWARD DECLS | Function signatures so code can call functions defined later in the file |
| 3-5. SUBSYSTEMS | One section per mechanism (arm, claw, lift, intake, etc.). Tunable constants at top, then init / control / auton API functions |
| 6. DASHBOARD TASK | Background task printing live sensor values to the brain screen during operation |
| 7. AUTONS | Drive helpers (pid_drive, pid_turn) + per-auton routines |
| 8. AUTON SELECTOR | Brain-screen menu — Up/Down cycle, A confirm |
| 9. MAIN | pre_auton(), autonomous(), usercontrol(), main() — pure orchestration |
The two-API pattern (every subsystem)
Every subsystem section exposes two parallel APIs — one for opcontrol, one for autons:
| API | Purpose | Example (arm) |
|---|---|---|
| Opcontrol | Called every usercontrol loop (~50×/sec). Reads buttons, drives motors. | arm_control() |
| Auton API | Called once with target values. Drives motors to target. | arm_set_power(80), arm_to_pot_angle(170) |
| Init | Called once in pre_auton(). Sets brake mode, tares encoder. | arm_init() |
PART 4Building, downloading, running
- Click Build (hammer icon at top, or Ctrl+F5 / Cmd+B). Output panel shows progress.
- Read errors top-to-bottom. The FIRST error is almost always the real problem — later errors are often cascading consequences. Fix #1, rebuild, re-read.
- Connect V5 brain via USB cable. Brain icon at top of VEXcode turns green when connected.
- Pick a slot from the dropdown if you don't want slot 1 (default).
- Click Download (arrow icon). Watch the progress bar — takes ~5 seconds.
- Press Run on the brain (or controller). The auton selector should appear on the brain screen.
- Use UP/DOWN on the controller to cycle autons, A to confirm. Dashboard appears after selection.
PART 5Calibration workflow
Calibration is a one-time-per-robot process. Do it in this order — each step assumes the previous one is correct.
| Step | What you do |
|---|---|
| 1. Driver Control Sanity | Push the joysticks. Verify drive direction. Test L1/L2 (arm up/down) and R1 (claw toggle). If anything is backwards — flip the reversed flag (true ↔ false) for the affected motor in Section 1. |
| 2. Pot Preset Calibration (arm) | Run the project, watch the brain dashboard. Move the arm by hand to each preset position, read the pot angle from the dashboard, update ARM_DOWN_DEG / ARM_MID_DEG / ARM_HIGH_DEG in Section 3. Rebuild + download. |
| 3. Drive Distance (PID) | Run Auton 1 (Drive Test). Should drive 24″ forward, then 24″ back. Measure with tape. If actual ≠ 24″, adjust wheelTravel in Section 1: new = old × (24 / actual) |
| 4. Turn Angle (PID) | Run Auton 2 (Square Drill) — 4× (24″ + 90°). Should return roughly to start. Robot ends rotated CW of start → decrease trackWidth. Robot ends rotated CCW → increase trackWidth. Adjust ±10mm at a time. |
| 5. Sensor Auton Mission | Run Auton 5 (Sensor Mission). End-to-end test using all sensors. Compare repeatability vs. Auton 4 (time-based Grab and Score) — low battery should especially show the difference. |
PART 6Common errors — lessons learned the hard way
These are the 6 errors that real teams hit when first using VEXcode V5 with our architecture. Knowing them in advance saves hours of practice time.
| Error message | Cause & fix |
|---|---|
redefinition of 'Brain' |
Cause: Your project template (likely Empty Project, our recommended setup) auto-declares Brain in robot-config.cpp, but the reference's brain Brain; line in Section 1 is uncommented — producing a duplicate declaration.Fix: Comment out the brain Brain; line in Section 1. Reference projects ship with this line already commented out for this exact reason. If your template doesn't auto-declare Brain, uncomment it. |
| Devices wizard refuses to add a sensor / Devices changes break the build | Cause: You deleted the #pragma region VEXcode Generated Robot Configuration lines at the top of main.cpp. The Devices wizard uses those markers to know where to inject auto-generated device code — without them, it doesn't know where to write.Fix: Re-paste the entire reference file (the pragma region is included at the top). Or manually add this at line 1: #pragma region VEXcode Generated Robot Configuration followed by a matching #pragma endregion VEXcode Generated Robot Configuration a few lines down. Path B users who never plan to touch the Devices wizard can technically run without the pragma, but keeping it costs nothing and preserves the upgrade option. |
no matching member function for call to 'spinToPosition' |
Cause: Used the 5-arg overload with percent as velocityUnits — ambiguous because percent matches multiple enums.Fix: Use Motor.setVelocity(SPEED, percent); in init, then 3-arg spinToPosition(pos, deg, false) everywhere. |
using integer absolute value 'abs' when argument is of floating point |
Cause: Used abs() on a double — abs is for ints only.Fix: Change to fabs() (floating-point absolute). |
call to member function 'printAt' is ambiguous |
Cause: Variadic arg can implicitly convert to bool, matching two overloads.Fix: Add explicit false as the 3rd argument: Brain.Screen.printAt(10, 30, false, ...). |
'LeftDriveA' was not declared |
Cause: Code uses motor names different from what your Devices wizard auto-generated. Fix: Either use the wizard's names (likely LeftDriveSmart/RightDriveSmart), or switch to Path B and declare manually. |
| Motor goes wrong direction in opcontrol | Cause: reversed flag set incorrectly. Fix: Flip the third constructor argument ( true ↔ false) for that motor in Section 1, rebuild. |
PART 7Using the dashboard for debugging
The sensor-loaded reference projects include a background dashboard task that prints live sensor values to the brain screen during opcontrol and auton. This is your primary debugging tool.
Sample dashboard output:
IMU heading: 142.3 deg Arm pot angle: 87.0 deg Arm top limit: - Arm bot limit: - Front bumper: - Back dist: 780 mm Claw object: DETECTED Optical hue: 165.0 deg Battery: 82 %
Use it for:
- Calibrating pot presets — move arm by hand, read live pot angle
- Verifying sensors are wired correctly — press limit switches by hand, watch "PRESSED" flash
- Diagnosing auton failures — watch IMU heading drift during a turn
- Battery monitoring — below 70% your PID drive distances start drifting
- Optical color tuning — hold objects in front of the claw, note the hue degrees
PART 8Where to go next
Adding a new subsystem (the 6-step pattern)
When your robot has a new mechanism (intake, lift, flywheel, etc.):
- Add the motor to Section 1 HARDWARE
- Add the new function names to Section 2 FORWARD DECLS
- Add a new subsystem section (copy an existing one, change the names) — constants at top, then init / control / auton API
- Call
<name>_init()in Section 9pre_auton() - Call
<name>_control()in Section 9usercontrol() - Optionally use the auton API from autons in Section 7
Adding a new auton
In Section 7:
- Write the new auton as
void auton_my_routine() { ... }usingpid_drive,pid_turn, and subsystem auton APIs - In Section 8, add an entry to the
autons[]array:{"6. My Routine", auton_my_routine} - Rebuild + download. The new auton appears in the selector.
Migrating to multi-file (when you outgrow single-file)
Once your main.cpp exceeds ~800 lines, consider splitting to multi-file. VEXcode V5 standalone doesn't support multi-file well — you'll need the VEX VS Code Extension (NOT the same as PROS + VS Code; much simpler). Each SECTION becomes its own .cpp + .h file. See the Setup Guide's appendix.
Migrating to PROS + EZ-Template (for competitive autons)
When you need tunable PID (custom kP, kI, kD per auton segment), exit conditions, or odometry, the path is PROS + EZ-Template. VEXcode V5's built-in PID uses VEX-tuned constants you can't change — fine for student-level autons, but tournament-winning autons usually need finer control. The architecture pattern is identical; each section maps to its own file.
Companion resources
- Setup Guide: spartandesignrobotics.org/vexcode-setup (import existing reference projects)
- Architecture Reference: spartandesignrobotics.org/code-architecture-vexcode (full pattern explanation)
- Reference projects: Clawbot, Flex, Skimmer (single-file + multi-file editions)
- PROS + EZ-Template archive: spartandesignrobotics.org/code-architecture (shelved but preserved)
PART 9Blocks vs Text — when to use which
VEXcode V5 lets students write in Blocks, Python, or C++. All three use the same Devices wizard, same competition template, and same underlying API. But each has different capabilities — here's when to pick which.
What's the same between Blocks and Text
- Same Devices wizard (Part 2 applies to both)
- Same motor / sensor / drivetrain commands —
driveFor,turnFor,spin,spinToPosition - Same competition template hat blocks: When Started → pre_auton, When Autonomous → autonomous, When Driver Control → usercontrol
- Same built-in PID via
smartdrive(in Blocks, the Drivetrain "Drive for" block uses the same closed-loop control) - Multiple When Started hat blocks run in parallel — like background tasks in text
- Custom blocks via the My Blocks category support parameters (number / boolean / label) — equivalent to text functions with arguments
What Blocks CAN'T do (where the Spartan architecture lives)
| Feature | Why our architecture needs it | Blocks status |
|---|---|---|
| Function pointers | The auton selector's AutonEntry autons[] array maps names to functions | ✗ No concept of "function as value" |
static file-scope state | static bool claw_open encapsulates subsystem state | ✗ All variables are global |
const typed constants | const double ARM_HIGH_DEG = 170; for calibration | ✗ Variables only, no type-safe consts |
printf-style formatting | printAt(x, y, false, "Pot: %6.1f deg", angle) for the dashboard | ✗ Blocks print does string concat only |
| Structs / arrays of structs | Auton selector entries, sensor pose data | Partial (lists exist, structs don't) |
| Multi-file projects | Subsystem files via VS Code Extension | ✗ Single workspace only |
| Forward declarations | Functions can call each other in any order | N/A in Blocks; limits complex flow |
When to use Blocks
- New students with no prior programming — especially if they haven't done Scratch or similar
- Quick prototyping — testing a sensor or motor behavior before committing to a design
- Drag-and-drop visual learners — the visual flow of blocks makes parallel "When Started" stacks especially clear
- Simple competition autons — tournament-grade if the auton doesn't need subsystem encapsulation
- The first week of curriculum — Sensor Exercise 0 + Drive Test work fine in Blocks
When to use Text C++
- The Spartan 9-section architecture — the pattern is fundamentally text-based
- Competition autons with sensor fusion — Auton 5 (Sensor Mission) needs proper state management
- Multi-subsystem robots — once you have arm + claw + lift + intake, encapsulation matters
- Built-in auton selector — the function-pointer pattern requires text
- Migration to PROS — tunable PID via EZ-Template requires C++
- Industry-relevant programming skill — text-based C++ is what professional embedded developers use
The graduation path — Blocks → Text
Students don't have to pick once and stick forever. VEXcode V5 makes the transition explicit:
- Write a behavior in Blocks (e.g., "drive forward until limit switch hits")
- Open the Code Viewer (View menu) — see the generated C++ side-by-side with your blocks
- Note the syntax patterns:
Drivetrain.drive(forward),while (!LimitA.pressing()),wait(20, msec) - Create a new Text C++ project and replicate the behavior by typing the patterns
- Extend with text-only features: function pointers, static state, structs, multi-file
The Code Viewer is a read-only learning tool — you can't edit the generated C++. Treat it as a Rosetta Stone between the two languages.
Recommendation for coaches
| Student profile | Start with | Move to text when... |
|---|---|---|
| No prior programming experience | Blocks | Comfortable with conditionals + loops in Blocks (1-2 sessions) |
| Prior Scratch / block-language experience | Blocks for 1 session | Comfortable with Devices wizard + opcontrol |
| Prior Python / Java / any text language | Text C++ directly | (already there) |
| Building a competition robot | Text C++ | (already there) |
| Wants to learn the Spartan architecture | Text C++ | (already there) |
The Spartan curriculum (reference projects, training exercises, sensor-loaded edition) is text-based by design. Starting in Blocks for the first practice session is fine — but the moment a student wants multiple autons with a selector or soft-limit sensors gating motor commands, the natural next step is text.
PART 10The toolchain progression — Blocks → VEXcode V5 → VS Code
The Spartan curriculum moves students through three programming environments. The progression isn't arbitrary — each step changes exactly one variable at a time. You never have to learn a new language AND new tooling simultaneously.
Blocks
Text (C++)
Extension
The single-variable-change rule
| Transition | What changes | What stays the same |
|---|---|---|
| Blocks → VEXcode V5 Text | Language (visual → syntax) | IDE, Devices wizard, build/download workflow, sensor APIs, competition template |
| VEXcode V5 Text → VS Code Extension | IDE (proprietary → professional) | Language, sensor APIs, SDK, build process — still VEX C++ |
What each transition unlocks
Stage 1 → Stage 2: the language transition
The student already knows the Devices wizard, the competition template, and the API. The Code Viewer in Blocks shows the C++ equivalent of every block, so the syntax isn't foreign — it's just a different way to write things they already understand.
What gets unlocked: Function pointers (auton selector), static file-scope state (subsystem encapsulation), const calibration values, printf formatting (dashboard), structs. The Spartan 9-section architecture lives here.
Stage 2 → Stage 3: the tooling transition
The student already knows VEX C++, the SDK, the build/download workflow. Now they keep all of that but get a professional editor.
What gets unlocked: Multi-file projects (separate .cpp files per subsystem), IntelliSense (autocomplete + hover docs), Git integration, AI Copilot, the same tools 75% of professional developers actually use. According to VEX, this transition exists specifically to align with industry tooling.
Why not skip Stage 2 — Blocks straight to VS Code?
Why VEX themselves designed it this way
VEX retired their old VEXcode Pro V5 (their proprietary text-only IDE) in favor of the VS Code Extension. The thinking is two-fold:
- VEXcode V5 stays simple as the on-ramp — Blocks + Text in one app, no install complexity, runs on Chromebooks
- VS Code Extension is the professional landing zone — multi-file, Git, IntelliSense, AI tooling. The same VS Code that millions of professional developers use, with VEX support layered on top
VEXcode Pro V5 was the awkward middle ground that didn't serve either purpose well, so VEX killed it. The Blocks → VEXcode V5 Text → VS Code Extension progression is now the official VEX-recommended path.
What each step costs to gain
| Step | You gain | You pay |
|---|---|---|
| Blocks | Visual flow, zero syntax, parallel hat blocks make multitasking obvious | No function pointers, no encapsulation, no multi-file, no PID tuning |
| VEXcode V5 Text | Real C++, the full Spartan architecture, builds a real engineering skill | Single-file (caps practical size around 500-1000 lines), no version control, no IntelliSense |
| VS Code Extension | Multi-file projects, Git, IntelliSense, AI Copilot, industry tooling | More setup steps, harder error messages (the VS Code error UI is less forgiving than VEXcode V5's) |
When each student moves up
- Blocks → Text: when they want a real auton selector, soft-limit sensors that gate motor commands, or a dashboard with formatted sensor data
- Text → VS Code: when one
main.cppbecomes unwieldy (typically multi-subsystem robots with arm + lift + claw + intake all in one file), or when they want to use Git for version control across multiple programmers
main.cpp. VS Code Extension is for students aimed at engineering college or industry careers who want to learn professional tooling. It's optional capability, not required progression. A team can win at States with Stage 2.
What this looks like in practice for our team
| Phase | Tool | Reference materials |
|---|---|---|
| Week 1 (new students) | VEXcode V5 Blocks | VEX example projects, Devices wizard |
| Weeks 2-N (most students) | VEXcode V5 Text | Setup Guide, this Guide, Code Generator, Clawbot SmartDrive |
| Advanced students / multi-developer projects | VS Code Extension | Multi-file editions of reference projects (*-vexcode-project.zip), PROS architecture archive |
reversed flag. Watch the motor go the wrong way. Every error you fix on a practice robot is one you won't hit at a tournament.