// Section 01

Print Debugging

The fastest way to understand what your robot is actually doing — not what you think it is doing.
💡
Print first, guess never. Every hour spent guessing at the cause of a bug is an hour you could have spent printing the actual value and knowing.

Printing to the Serial Console

1
Include the PROS API and use printf
#include "api.h" then use printf("motor temp: %f ", motor.temperature()); — output appears in the PROS terminal in VS Code when the robot is connected via USB.
2
Print in a loop with a delay
Wrap sensor prints in a 20ms delay: while(true){ printf("heading: %f ", imu.heading()); pros::delay(20); } — without the delay, the output floods faster than you can read it.
3
Label every value you print
Write "heading: %f" not just "%f". When you are looking at a stream of numbers, labels are the difference between understanding and confusion.

What to Print When

ProblemWhat to Print
Auton driftsimu.heading(), left and right motor velocity
Motor not movingmotor.temperature(), motor.current(), motor.get_port()
Sensor reading wrongRaw sensor value + expected range every 50ms
PID not settlingError, integral, derivative, and output each cycle
Code path not reachedPrint a unique string at each branch: "branch A taken"
// Section 02
Brain Screen Debugging
When a USB cable is not available — use the brain screen. Works at competition, in the queue, and during a match.

Basic Brain Screen Output

1
Print on a specific row
Brain.Screen.setCursor(row, col); then Brain.Screen.print(value); — rows 1-8 fit on screen. Use one row per variable so output does not scroll.
2
Clear before printing
Brain.Screen.clearScreen(); at the top of your display loop prevents old values from overlapping new ones.
3
Use a dedicated display task
Run display code in a separate PROS task so it does not block your main control loop: pros::Task display_task(display_fn);

Useful Display Template

📄 Display Task Template
void display_fn() {
  while(true) {
    Brain.Screen.clearScreen();
    Brain.Screen.setCursor(1,1);
    Brain.Screen.print("Heading: %.1f", imu.heading());
    Brain.Screen.setCursor(2,1);
    Brain.Screen.print("L motor: %d", left_motor.current());
    Brain.Screen.setCursor(3,1);
    Brain.Screen.print("Battery: %d%%", Brain.Battery.capacity());
    pros::delay(50);
  }
}
💡
Pre-match display: Show battery percentage, auton slot selected, and IMU calibration status on the brain screen. Your drive team can confirm readiness without a laptop.
// Section 03
Systematic Isolation
Change one thing at a time. The biggest debugging mistake is changing three things simultaneously and not knowing which one worked.
⚠️
One variable at a time. When debugging, change exactly one thing between each test run. If you change three things and the bug disappears, you do not know which fix worked — and the other two are now unverified changes in your code.

Isolation Protocol

1
Reproduce the bug reliably
If you cannot reproduce it consistently, you cannot fix it consistently. Find the exact conditions that cause it — battery level, starting position, which auton, which match type.
2
Isolate the failing subsystem
Test each subsystem independently. If the drive works alone and the lift works alone but the combined routine fails, the interaction between them is the bug — not either subsystem.
3
Binary search the code
Comment out the second half of your auton. Does it still fail? If yes, the bug is in the first half. If no, it is in the second half. Repeat until you find the exact line.
4
Verify the fix actually fixes the root cause
After fixing, run the full routine 5 times in a row. If it succeeds all 5, the root cause is fixed. One success is not enough — the original bug might have been intermittent.

Hardware vs Software Checklist

Before debugging code, rule out hardware. Most "software bugs" in VRC are hardware faults in disguise.

  • Re-seat all motor and sensor smart cables
  • Swap the suspect motor to a known-good port
  • Check for mechanical binding by turning the mechanism by hand
  • Verify all wheel screws are tight and wheels are not slipping on axles
  • Check battery terminals for corrosion or a loose connection
// Section 04
Common PROS Errors
Reference for the most frequent PROS and EZ Template error messages and how to resolve them.
Error / SymptomCauseFix
ENODEV on motor/sensorWrong port number or cable not seatedRe-seat cable; verify port number in constants file matches physical port
Motor runs at full power non-stopMotor voltage set instead of velocity; no control loopUse motor.move_velocity(speed) not motor.move(127) for controlled motion
IMU always reads 0IMU not calibrated or on wrong portAdd imu.reset(); at startup and wait for calibration: while(imu.is_calibrating()) pros::delay(20);
Code compiles but nothing movesDriver control task not started, or wrong competition stateVerify your opcontrol() function runs; check brain shows "Driver Control" not "Disabled"
Task crashes with stack overflowRecursive function or very large stack allocationIncrease task stack size: pros::Task task(fn, nullptr, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT * 2, "Task");
Auton runs in driver controlCompetition switch or field control signal issueTest with the PROS competition template; verify the brain receives field control signal
undefined reference linker errorFunction declared in header but not defined in any .cppAdd the function body to the appropriate .cpp file; check for typos between declaration and definition
💡
When all else fails: Create a minimal reproduction — a new project with only the code that demonstrates the bug. Stripping away everything irrelevant usually reveals the cause immediately, and makes it easier to ask for help on the VEX Forum.
← ALL GUIDES