Sources & confidence: All hardware specs, part numbers, and PROS API references verified against the official VEX Library articles and pros.cs.purdue.edu (PROS V5 3.8.0 / PROS 4 documentation). The GPS Sensor recommendations (rear-facing, 10.5″ height) come directly from VEX's "Best Practices with the GPS Sensor" KB article. Override-specific use cases are speculation until the manual drops Monday April 27, 2026.
// Section 01

GPS, Switches & Potentiometer 🎯

Three discrete sensor types that solve different problems. The GPS gives absolute field position; switches give binary contact events; potentiometers measure angular position of mechanisms. Each is cheap, well-supported in PROS, and high-leverage in competition.
📍 Position Sensing 🔌 Contact Detection 🏆 V5RC / VEX U Legal

Quick Decision Tree

I need absolute (X, Y) position on the fieldUse the GPS Sensor — reads the printed field code on the perimeter walls.
I need to know "has my mechanism reached its limit?"Use a Limit Switch or Bumper Switch — mounts at the end of travel.
I need the angular position of a fixed-rotation mechanism (arm, lift)Use a Potentiometer V2 — reports angle 0–330°.
I need to track a continuously rotating shaft (drivetrain, flywheel)Use the V5 Rotation Sensor (Smart Port). Not covered in this guide — see the sensor onboarding roadmap.
I need to detect ring/object color in the intakeUse the V5 Optical Sensor. See the Optical Sensor guide.
I need to identify field landmarks for navigationUse the AI Vision Sensor + AprilTags. See the AI Vision guide.

How These Three Compare

Port TypeGPS: Smart Port. Switches and Pot: 3-Wire (ADI) Port.
Cost & ComplexityGPS is the most expensive and complex of the three. Switches are the cheapest and simplest. Potentiometer is in between.
Output TypeGPS: floating-point X/Y/heading. Switches: digital boolean (pressed/released). Potentiometer: analog 0–330° angle.
Setup DifficultyGPS requires field code strips installed on the field perimeter (already present at official events). Switches and pots work out-of-box.
Override LikelihoodAll three are useful. Switches are nearly mandatory for any robot with end-of-travel mechanisms. Potentiometer is high-value for arm/lift position. GPS is optional but powerful for skills runs.
📋
Why this guide groups these three: They're all relatively simple sensors compared to vision. Switches and potentiometer use ADI ports (the 3-wire ports labeled A–H on the V5 Brain). The GPS uses a Smart Port like the vision sensors. Knowing all three is part of the basic V5RC sensor toolkit.
// Section 02
V5 GPS Sensor 📍
VEX's Game Positioning System — absolute X/Y coordinates and heading derived from camera-based reading of QR-like field code strips on the perimeter walls. Not satellite GPS.
For full details — field code strip mechanics, sensor fusion patterns, the auton-reset workflow, EZ-Template + LemLib integration, and the complete failure-mode matrix — see the dedicated V5 GPS Sensor Deep Dive. The section below is the introductory overview; the deep dive is what your team should read before committing to GPS in your auton.

Hardware Summary

VEX Part Number276-7405
Sensor TypeBlack-and-white camera + onboard processing. Reads the printed Field Code (a non-repeating checkerboard pattern) on the four field walls.
Coordinate SystemOrigin (0, 0) at center of field. Range approximately −1.8m to +1.8m on both X and Y axes. Reports in meters.
Heading Range0–360°. Brain screen displays as −180 to +180.
ConnectionOne V5 Smart Port via Smart Cable.
Reading DistanceCamera needs to see ~17″ of the field code strip to triangulate position. Robot too close to the wall => reading drops.
Mounting Height~10.5″ off the ground — in line with the field code strip (per Purdue SIGBots Wiki).
Built-in IMUYes, but per public forum discussion: the GPS will not transmit angle data unless it has seen the field code at least once every ~10 seconds. Cannot be used as a standalone IMU at home without field strips.
⚠️
The GPS is not a satellite GPS. Despite the name, it works by reading printed Field Code strips on the perimeter walls of an official competition field. If you don't have full field walls with the code strips installed, the sensor cannot localize. Plan for: official events have it, your home practice setup probably doesn't (unless you have polycarbonate panels with the printed code).

Mounting Recommendations (per Official VEX Best Practices)

PROS API Reference

Classpros::Gps
Header#include "pros/gps.hpp"
Constructorpros::Gps gps(uint8_t port);
Positionauto status = gps.get_status(); — struct with x, y, pitch, yaw, roll
X position onlydouble x = gps.get_position_x(); — meters
Y position onlydouble y = gps.get_position_y(); — meters
Headingdouble heading = gps.get_heading(); — 0–360°
Set initial positiongps.set_position(x, y, theta); — meters / degrees
Set offsetgps.set_offset(x_offset, y_offset); — sensor offset from robot center, meters
Position errordouble rms_err = gps.get_error(); — RMS error in meters
Update rategps.set_data_rate(ms); — affects internal IMU only

GPS Code Pattern (PROS C++)

// PROS C++ — basic GPS read
// EN4: rewrite in your own words for your notebook. #include "pros/gps.hpp" // GPS on Smart Port 7 pros::Gps gps(7); void initialize() { // Tell the GPS where the sensor sits on the robot // (relative to robot center, in METERS) // Example: sensor mounted 6 inches behind robot center = -0.152m on Y gps.set_offset(0.0, -0.152); // Optionally seed initial position if you know where you start // (only useful if GPS hasn't acquired the field code yet) // gps.set_position(-1.2, -0.6, 90.0); // x_m, y_m, heading_deg } void print_gps_status() { auto s = gps.get_status(); pros::lcd::print(0, "X: %.3f m", s.x); pros::lcd::print(1, "Y: %.3f m", s.y); pros::lcd::print(2, "Yaw: %.1f deg", s.yaw); pros::lcd::print(3, "Err: %.4f m", gps.get_error()); }

When the GPS Beats Encoder Odometry

Per the Purdue SIGBots Wiki and the VEX AI overview: the GPS is an absolute position system. It does not drift — the camera always reports where the field code says you are, regardless of how long you've been moving or how much wheel slip occurred.

Encoder/IMU-based odometry (used by EZ-Template and LemLib) is subject to drift — wheel slip, encoder error, and IMU integration error compound over time. After a 60-second skills run, encoder odometry can be off by several inches. GPS readings reset that error every frame.

When NOT to Trust the GPS

The pragmatic approach: combine GPS with encoder odometry. Use encoder odometry for moment-to-moment movement; use GPS to periodically reset accumulated drift when readings are reliable.

// Section 03
Limit & Bumper Switches 🔌
The simplest sensors VEX makes — SPST mechanical switches that return digital high (released) or low (pressed). Underrated for V5RC. Cheap, reliable, and the right tool for any "has the mechanism reached its endpoint" question.

Hardware Summary

Bumper Switch v2 (2-pack)VEX part 276-2159. Spring-loaded button. Two slotted mounting holes; the red button has a removable screw exposing an 8-32 mounting insert.
Bumper Switch 6N (2-pack)VEX part 276-8010. Lower-spring-force version. Activates on lighter touch. Use when the contact force is small (a falling lift arm, a rolling game element).
Limit SwitchSpring-steel arm version of the bumper. Arm can be cut shorter or bent. Activated at a 90° angle from the bumper button orientation. Useful when the contact direction is along a different axis than a button.
Port Type3-Wire ADI port (V5 Brain ports A through H). Three wires: black (ground), red (not connected), white (signal).
LogicSPST normally open. Released = digital HIGH (1). Pressed = digital LOW (0). Per VEX Library: low force needed to activate.
Per-Brain Limit8 ADI ports (A–H). Each port can host a switch. Use a 3-Wire Expander module if you need more.

Bumper vs Limit — Which to Use

Bumper Switch (red button)
Force is applied directly into the button face. Use when something pushes onto the switch (an arm coming down onto a backstop, a robot wall touching it). Lightly sprung, easy to mount, very reliable. Most common choice for V5RC.
Limit Switch (steel arm)
Force is applied perpendicular to the steel arm, which deflects to trigger. Use when contact is from the side or sweeping motion, and the bumper button face wouldn't naturally engage. The steel arm can be cut or bent for custom contact geometry. Per Purdue SIGBots Wiki: the limit switch is fragile — don't put it where opponents can entangle it.

Mounting

PROS API Reference

Classpros::adi::DigitalIn
Header#include "pros/adi.hpp"
Constructor (port letter)pros::adi::DigitalIn limit('A'); — ADI port A
Constructor (port number)pros::adi::DigitalIn limit(1); — numeric port 1–8 (A–H)
Read statebool pressed = !limit.get_value();note the negation: returns 0 when pressed, 1 when released, so flip to get "pressed" semantics
Edge detectionint new_press = limit.get_new_press(); — returns 1 only on the first cycle after a press

Code Patterns

// PROS C++ — lift soft-stop using limit switch
// EN4: rewrite in your own words for your notebook. #include "pros/motors.hpp" #include "pros/adi.hpp" pros::Motor lift(13); pros::adi::DigitalIn lift_top_limit('A'); // top of travel pros::adi::DigitalIn lift_bottom_limit('B'); // bottom of travel // Move lift up, but stop if top limit is hit void lift_up_to_limit() { lift.move(127); while (lift_top_limit.get_value() == 1) { // 1 = released; loop while NOT pressed pros::delay(10); } lift.move(0); lift.brake(); } // Use as zeroing reference for arm position tracking void zero_lift_at_bottom() { lift.move(-50); // gently move down while (lift_bottom_limit.get_value() == 1) { pros::delay(10); } lift.move(0); lift.tare_position(); // reset motor encoder to 0 here }
// PROS C++ — auton selector using a bumper switch
// EN4: rewrite in your own words for your notebook. pros::adi::DigitalIn auton_select('A'); // Each press of the button cycles to the next auton routine int selected_auton = 0; void auton_selector_task(void* p) { while (true) { if (auton_select.get_new_press()) { selected_auton = (selected_auton + 1) % 4; // 4 routines pros::lcd::print(0, "Selected auton: %d", selected_auton); } pros::delay(20); } }

What Switches Are Best For

// Section 04
Potentiometer V2 🔢
An analog rotation sensor for "limited rotation" mechanisms — arms, lifts, tilters. Measures the absolute angular position of a shaft. Position is preserved when the brain is powered off.

Hardware Summary

VEX Part Number276-7417 (Potentiometer V2 2-pack)
PredecessorOriginal Potentiometer (250° range). The V2 is the current model and is what you should use.
Rotation RangePotentiometer V2: 333° sensing range (per PROS docs); the central hub itself rotates 360° continuously, but only 333° of that produces usable readings (there's a 27° deadband).
Resolution12-bit ADC: 0–4095 raw range. ~12.3 ticks per degree on the V2 across its 333° range.
Update RatePer public VEX Forum discussion: 10ms refresh through the ADI port (faster than the V5 Rotation Sensor in default config).
Port Type3-Wire ADI port (A–H).
MountingThrough-hole design with a square shaft passing through the center hole. Two mounting arc slots allow ~90° of fine-tune adjustment after initial mounting.
PersistenceReading is based on absolute physical position. Survives brain power-off — if you rotate the shaft while the brain is off, the new reading reflects the new position when you turn back on.

When to Use a Potentiometer (vs. a Rotation Sensor)

🔮 Decision Logic
  • Use a Potentiometer V2 when: the mechanism rotates within a fixed angular range (under 333°), and you want absolute position that survives power cycles. Best for arms, lifts, tilters.
  • Use a V5 Rotation Sensor when: the shaft rotates continuously without limit (drivetrain wheels, flywheels, tracking wheels for odometry). Smart Port-based, higher precision.
  • Use a V5 Smart Motor's built-in encoder when: the shaft is directly driven by a Smart Motor and you don't need encoder data when the mechanism could be back-driven by an opponent or external force.

Per the VEX Library: do not force the Potentiometer past its mechanical stops. The V2 design is more durable than the original (conductive plastic resistive track instead of mechanical resistive material), but forcing past 333° can still damage the internal stops, leaving the sensor permanently unreliable.

Mounting

PROS API Reference

Classpros::adi::Potentiometer
Constructorpros::adi::Potentiometer pot('A', pros::E_ADI_POT_V2); — specify V2 type for 333° mode
Original pot typepros::E_ADI_POT_EDR for the legacy 250° potentiometer
Get angledouble angle = pot.get_angle(); — degrees (0 to 333 for V2)
Get raw valueint raw = pot.get_value(); — raw 12-bit ADC value (0–4095)
Calibrate (optional)pot.calibrate(); — collects 500 samples over 0.5s, accounts for sensor noise

Code Pattern: Arm Position Control

// PROS C++ — arm to target angle using potentiometer feedback
// EN4: rewrite in your own words for your notebook. #include "pros/motors.hpp" #include "pros/adi.hpp" pros::Motor arm(14); pros::adi::Potentiometer arm_pot('A', pros::E_ADI_POT_V2); // P-controller: drive arm to a target angle void arm_to_angle(double target_deg) { const double kP = 4.0; const double tolerance_deg = 1.0; while (true) { double current = arm_pot.get_angle(); double error = target_deg - current; if (std::abs(error) < tolerance_deg) { arm.move(0); arm.brake(); return; } double power = error * kP; // Clamp to motor range if (power > 127) power = 127; if (power < -127) power = -127; arm.move(power); pros::delay(10); } }

Calibration Procedure

Before competition, run a calibration to understand your mechanism's actual range and pot readings:

  1. Mount the potentiometer with the deadband out of normal mechanism travel.
  2. Move the mechanism to its physical lower limit (e.g., arm fully down). Record the pot angle. This is your ARM_DOWN_DEG.
  3. Move the mechanism to its physical upper limit. Record the angle. This is ARM_UP_DEG.
  4. Move to known intermediate positions. Record. Build a lookup of named positions (LOAD, SCORE_LOW, SCORE_MID, SCORE_HIGH).
  5. Use these values in your code as named constants. Don't assume the mechanism mounts identically across robots — mounting tolerances mean you re-calibrate per robot, sometimes per pot.

Tracking Wheel Use (Advanced)

Per a public VEX Forum discussion (July 2021): some teams use two Potentiometer V2s as tracking wheel encoders for odometry, alternating between them to avoid the deadband. The 333° range gives ~12× the resolution of older quadrature encoders, with 10ms refresh. This is an unusual approach — most teams use the V5 Rotation Sensor for tracking wheels because LemLib and EZ-Template have direct support for it. We mention it for completeness; it's not the recommended path for new teams.

// Section 05
EZ-Template & LemLib Integration 🔗
How GPS, switches, and potentiometers fit into chassis-library workflows. Same answer as the other sensor guides: these libraries don't wrap them — you compose them.

The Honest Picture

Same as for the AI Vision and Optical sensors:

GPS + EZ-Template: Position Reset Pattern

EZ-Template uses encoder-based odometry by default. That odometry drifts. The GPS doesn't. Combine them: let EZ-Template handle motion, then periodically reset its odometry from GPS readings.

// EZ-Template + GPS — reset chassis odom from GPS reading
// EN4: rewrite in your own words for your notebook. #include "EZ-Template/api.hpp" #include "pros/gps.hpp" extern Drive chassis; extern pros::Gps gps; // Convert GPS meters to inches (EZ-Template uses inches by default) constexpr double M_TO_IN = 39.3701; // Reset chassis odom from GPS, only if GPS reading is reliable bool reset_odom_from_gps() { if (gps.get_error() > 0.05) return false; // 5cm error tolerance auto s = gps.get_status(); double x_in = s.x * M_TO_IN; double y_in = s.y * M_TO_IN; double yaw_deg = s.yaw; chassis.odom_pose_set(x_in, y_in, yaw_deg); return true; } // In auton: drive somewhere with EZ-Template, then GPS-correct void auton_with_gps_correction() { chassis.pid_drive_set(48_in, DRIVE_SPEED, true); chassis.pid_wait(); pros::delay(150); // let GPS reading settle if (reset_odom_from_gps()) { // Now EZ-Template's odom matches reality chassis.pid_odom_set({{0_in, 24_in}, fwd, DRIVE_SPEED}); chassis.pid_wait(); } }

Note: The exact EZ-Template odometry-set function name may vary by version. Check the EZ-Template tutorials for the current API. The pattern is correct; the function name might be odom_pose_set, odom_xy_set, or similar in your installed version.

Limit Switch + EZ-Template: Drive-Until-Wall Pattern

Drive forward with EZ-Template PID, but exit early when a bumper switch triggers (e.g., when the robot bumps into a field wall or fixed structure).

// EZ-Template + bumper — drive-until-contact
// EN4: rewrite in your own words for your notebook. #include "EZ-Template/api.hpp" #include "pros/adi.hpp" extern Drive chassis; extern pros::adi::DigitalIn front_bumper; // Drive forward until bumper triggers, with safety distance cap void drive_until_bumper(double max_distance_in) { chassis.pid_drive_set(max_distance_in * 1_in, DRIVE_SPEED, true); while (chassis.pid_wait_quick_chain() == false) { if (front_bumper.get_value() == 0) { // 0 = pressed chassis.pid_targets_reset(); chassis.drive_set(0, 0); return; } pros::delay(10); } }

Potentiometer + EZ-Template: Async Subsystem Pattern

EZ-Template focuses on the chassis. Subsystems (arm, lift) run in parallel tasks. Use a potentiometer in your subsystem task to track and control its mechanism while EZ-Template handles driving.

// PROS task: arm position controller (runs alongside EZ-Template auton)
// EN4: rewrite in your own words for your notebook. extern pros::Motor arm; extern pros::adi::Potentiometer arm_pot; // Shared target; auton or opcontrol code sets it, task pursues it struct ArmState { pros::Mutex mutex; double target_deg = 0.0; bool active = false; }; ArmState arm_state; void arm_task_fn(void* p) { const double kP = 4.0; while (true) { arm_state.mutex.take(); bool active = arm_state.active; double target = arm_state.target_deg; arm_state.mutex.give(); if (active) { double error = target - arm_pot.get_angle(); double power = error * kP; if (power > 127) power = 127; if (power < -127) power = -127; arm.move(power); } pros::delay(10); } } // Helper to set the arm target from auton code void arm_set_target(double angle_deg) { arm_state.mutex.take(); arm_state.target_deg = angle_deg; arm_state.active = true; arm_state.mutex.give(); } void initialize() { pros::Task t(arm_task_fn, nullptr, "arm"); } // Auton can now do this: void example_auton() { arm_set_target(45.0); // arm to 45 deg, runs in background chassis.pid_drive_set(36_in, DRIVE_SPEED, true); chassis.pid_wait(); // Both done by here -- chassis arrived AND arm is at 45 deg }

LemLib Equivalents

EZ-Template chassis.pid_drive_setLemLib chassis.moveToPoint or chassis.moveTo
EZ-Template pid_targets_resetLemLib chassis.cancelMotion
EZ-Template pid_waitLemLib chassis.waitUntilDone
EZ-Template odom_pose_setLemLib chassis.setPose(x, y, theta)

Both libraries support the same composition patterns. LemLib's odometry sensor structure (lemlib::OdomSensors) takes pointers to your tracking wheels and IMU; you pass GPS-derived corrections to setPose() when you want absolute position resets.

// Section 06
Override Use Cases 🎯
Speculative until the manual drops Monday April 27. Below are likely high-value uses based on the kickoff trailer and standard V5RC patterns.
🔔
This section is pre-manual speculation. Re-read after Monday April 27, 2026.

GPS for Override

Limit/Bumper Switches for Override

Potentiometer for Override

Pre-Order Hardware List for Override

  1. Bumper Switches: Order at least 4–6 per robot. Cheap (276-2159 2-pack), versatile, you will use them.
  2. Limit Switches: 1–2 per robot. Use where the contact direction or sweep geometry favors the steel arm over the bumper button.
  3. Potentiometer V2: 1–2 per robot. One per major mechanism with limited rotation (arm, lift, tilter).
  4. GPS Sensor: 1 per robot. Most useful for skills runs. Optional for match autons (encoder odom is usually sufficient for 15s).
  5. Smart Cables & 3-Wire Extension Cables: Plenty of spares. The 3-wire cables are more failure-prone than Smart Cables.
// Section 07
Common Pitfalls & Skills/Driver Tips ⚠️
Things that will go wrong, and what to do about them.

GPS Pitfalls

📍 GPS Failure Modes
  • Mounted upside-down. VEX logo MUST be upright. Wrong orientation = wrong coordinates. Verify in the V5 brain Devices screen.
  • Mounted at wrong height. ~10.5″ off the ground is the target. Too high or low and the camera misses the field code strip.
  • Forward-facing. Game elements and your own scoring mechanism block the view. Mount rear-facing.
  • Practice without field walls. Without the printed field code strips, the GPS does NOT work. Plan accordingly — either invest in the strips for your practice setup, or do GPS testing only at competitions.
  • Trusting GPS during a pin. If an opponent shoves your robot, the GPS tracks accurately, but encoder odometry will diverge. Use the divergence as a pin-detection signal.

Switch Pitfalls

🔌 Switch Failure Modes
  • Forgetting the negation. get_value() returns 1 when released, 0 when pressed. Beginners frequently invert the logic and the switch "does nothing."
  • Cable loose in 3-wire port. 3-Wire ports are friction-fit. Cables can wiggle out during rough matches. Use cable management.
  • Limit switch arm bent. The steel arm can deform from hard impacts. Check all your switches at every pit stop. A bent arm gives wrong trigger geometry.
  • Mounting too rigid. If a bumper is mounted such that the mechanism slams into it at full speed, the switch breaks. Slow down before contact, or add a small foam buffer.
  • Wrong port assumption. ADI port 'A' is port 1, 'B' is port 2, etc. Make sure your code references match the wiring.

Potentiometer Pitfalls

🔢 Potentiometer Failure Modes
  • Rotating into the deadband. The 27° deadband (V2) returns garbage values. Use the body's arc slots to position the deadband out of mechanism travel.
  • Forcing past the mechanical stops. Damages internal stops, sensor becomes free-rotating and useless. Discard if this happens.
  • Wrong type in PROS constructor. If you pass E_ADI_POT_EDR for a V2 sensor, the angle range is reported as 250° instead of 333°. Always use the matching enum.
  • No calibration. Mounting tolerances vary. Two robots with identical mechanisms can read different pot angles for the same physical position. Calibrate each robot, each pot.
  • Hard-coded thresholds. If the pot drifts (mounting screws loosen, sensor body shifts), your hard-coded angle constants become wrong. Re-calibrate at every venue if you can.

Skills Run Tips

Driver Skills Tips

Related Guides

← ALL GUIDES