🚀 After the Beginner Guide

Level Up:
Advanced Text Coding

You know the basics. Now let's close the gaps that trip up every new text coder — errors, debugging, and writing code that doesn't break.

1
Errors
2
Debugging
3
Order
4
Formatting
5
Exercises
// Section 01
Error Messages Are Your Friends 🔴
Blocks never showed you errors. Text code does — and that's actually a good thing.
🔍
Errors are like spell-check, not a failing grade
When your code has a mistake, the compiler tells you exactly which line the problem is on. That's way more helpful than a robot that just... doesn't work and you have no idea why. Errors are information — learn to read them calmly.

How to Read an Error Message

When you run pros build, errors look like this in the terminal:

src/main.cpp:14:5: error: expected ';' before 'pros' ↑file ↑line ↑column ↑what's wrong

Every error has three parts: file name, line number, and description. Always start by clicking to line 14 — the fix is almost always right there.

The 6 Most Common Errors (and How to Fix Them)

❌  error: expected ';' before ...

You forgot a semicolon at the end of a line.

motor.move_voltage(12000) ← missing semicolon!
motor.move_voltage(12000); ← fixed ✓
❌  error: expected '}' at end of input

You opened a curly brace { but never closed it with }. Count your braces — they must match.

while(true) { chassis.opcontrol_tank(); pros::delay(20); ← missing closing brace!
while(true) { chassis.opcontrol_tank(); pros::delay(20); } ← fixed ✓
❌  error: 'motorName' was not declared in this scope

You're using a variable or object name that doesn't exist — usually a typo or you forgot to declare it in robot-config.cpp.

intaek.move_voltage(12000); ← typo: "intaek"
intake.move_voltage(12000); ← fixed ✓
❌  error: too many / too few arguments

The function expects a certain number of values inside ( ) and you gave it the wrong count.

pros::delay(); ← forgot to pass the time!
pros::delay(20); ← fixed ✓
❌  warning: unused variable 'x'

Not a crash — just a heads-up. You created a variable but never used it. Either use it or delete it.

💡
Warnings (yellow) won't stop your code from running. Errors (red) will. Fix errors first, then clean up warnings.
❌  Lots of errors at once — 50+ lines of red

Don't panic! Usually one small mistake (a missing { or ; early in the file) causes a cascade of fake errors below it.

⚠️
Fix the FIRST error only. Rebuild. The other 49 errors often disappear automatically because they were all caused by that one mistake.
You get 30 error messages after building. What should you do first?
⬜ Fix all 30 errors one by one from the bottom up
⬜ Fix only the very first error, then rebuild
⬜ Delete everything and start over
⬜ Upload anyway and hope it works
// Section 02
Debugging — See Inside Your Robot 🔬
In VEXcode blocks you could watch values on screen. In PROS, you use print statements and the terminal.
📡
printf is like a walkie-talkie from your robot
While your robot is running, it can send messages back to your laptop over the USB cable. You use printf() to send those messages and pros terminal to receive them. It's how you see what's actually happening inside your code.

Step 1 — Add printf to Your Code

void opcontrol() { while (true) { chassis.opcontrol_tank(); // Print the arm motor's current position every loop printf("Arm position: %d\n", arm.get_position()); // Print a controller button state (1=pressed, 0=not) printf("R1 pressed: %d\n", controller.get_digital(DIGITAL_R1)); pros::delay(50); // slow the prints so they're readable } }

Step 2 — Open the Terminal to Read Them

// In VS Code terminal, after uploading: pros terminal

You'll see your messages scrolling in real time as the robot runs. When you're done debugging, press Ctrl+C to stop.

printf Format Cheatsheet

printf("Speed: %d\n", speed); // %d = whole number (int) printf("Angle: %.2f\n", angle); // %.2f = decimal (2 places) printf("Button: %d\n", btnState); // 1 = true, 0 = false printf("Hello from loop!\n"); // \n = new line

The "Comment Out" Debug Trick

Not sure which line is causing a problem? Temporarily disable lines by turning them into comments with Ctrl+/:

while(true) { chassis.opcontrol_tank(); // arm_control(); ← disabled to test if this causes the bug // intake_control(); ← also disabled pros::delay(20); }

Re-enable lines one at a time until the bug reappears — that's your culprit.

Brain Screen Debugging (No Cable Needed!)

You can also print to the V5 Brain's screen — useful at competitions when you can't plug in a laptop:

pros::lcd::initialize(); // put this in initialize() // In your loop: pros::lcd::print(0, "Arm: %d", arm.get_position()); pros::lcd::print(1, "R1: %d", controller.get_digital(DIGITAL_R1)); // ↑ line 0 = top of screen, line 1 = below it
Pro debugging habit: Before every match, add printf("CODE STARTED\n"); at the very beginning of autonomous. If you open the terminal and don't see it, your code never ran — which tells you it's a hardware/upload problem, not a code problem.
// Section 03
Order Matters — Code Runs Top to Bottom ⬇️
In blocks you could drag things anywhere. Text code executes in strict order — this trips up almost every new coder.
🍳
Code is like a recipe — every step happens in sequence
If a recipe says "crack the eggs, then add flour," you can't do it backwards. C++ works the same way. Line 1 runs first, then line 2, then line 3 — exactly in order, every single time.

Autonomous Order Example

void my_auton() { // Step 1 — drive forward chassis.pid_drive_set(24_in, 110); chassis.pid_wait(); ← MUST wait before next move! // Step 2 — turn right chassis.pid_turn_set(90_deg, 90); chassis.pid_wait(); // Step 3 — run intake intake.move_voltage(12000); pros::delay(1000); ← wait 1 second intake.brake(); }
⚠️
Forgetting pid_wait() is the #1 autonomous mistake. Without it, the robot starts the next movement immediately — before the first one finishes — and everything goes wrong.

Declaring Before Using

In C++, you must declare (create) a variable before you use it. The compiler reads top to bottom, so if you try to use something it hasn't seen yet, it will error:

motor.move_velocity(speed); ← ERROR: 'speed' used before it exists! int speed = 200;
int speed = 200; ← declare first ✓ motor.move_velocity(speed); ← then use it ✓

The Compilation Step — Why There's a Delay

✏️
You write code
Your .cpp files are human-readable text that you edit in VS Code.
🏭
Compiler translates it
pros build converts your text into machine code the V5 Brain can actually execute.
📤
Upload runs it
pros upload sends the compiled binary to the Brain over USB. Then your robot runs it.
💡
This is why blocks feel "instant" — VEXcode compiles and uploads automatically. In PROS you control when it happens, which means more power but one extra step.
In autonomous, your robot turns and then immediately drives without waiting. What did you most likely forget?
⬜ A semicolon
⬜ chassis.pid_wait() after the turn
⬜ To declare a variable
⬜ To upload the code
// Section 04
Formatting Habits That Prevent Bugs 🧹
Blocks auto-indented for you. In text code, good formatting is your responsibility — and it prevents more bugs than you'd think.

Indentation — Your Best Friend

Everything inside { } should be indented one level (2 or 4 spaces, or one Tab). VS Code does this automatically when you press Enter after a {.

// ❌ BAD — impossible to see what belongs where void opcontrol(){ while(true){ if(controller.get_digital(DIGITAL_R1)){ intake.move_voltage(12000); }pros::delay(20);}}
// ✅ GOOD — easy to read, easy to spot missing braces void opcontrol() { while (true) { if (controller.get_digital(DIGITAL_R1)) { intake.move_voltage(12000); } pros::delay(20); } }
⌨️
In VS Code, press Shift+Alt+F (Windows) or Shift+Option+F (Mac) to auto-format the entire file instantly. Use this constantly!

Naming Things Clearly

int x = 200; ← what is x? Nobody knows bool b = false; ← b for what?
int armSpeed = 200; ← clear ✓ bool intakeToggleOn = false; ← obvious ✓

Use camelCase for variable names: first word lowercase, each new word capitalized. armTargetPosition, intakeRunning, pneumaticExtended.

One Job Per Function

Don't cram everything into opcontrol(). Break it into helper functions — one per mechanism:

// Each mechanism gets its own function: void drive_control() { chassis.opcontrol_tank(); } void arm_control() { /* arm code here */ } void intake_control() { /* intake code here */ } // opcontrol just calls them all — clean and readable: void opcontrol() { while (true) { drive_control(); arm_control(); intake_control(); pros::delay(20); } }

Comment Your Intent, Not What's Obvious

// ❌ BAD comments — states the obvious intake.move_voltage(12000); // moves intake at 12000
// ✅ GOOD comments — explains WHY intake.move_voltage(12000); // full speed — tested at 10000 but kept slipping
// Section 05
Practice Exercises 💪
Try these in VS Code. Each one is a small challenge that builds a real skill.
📋
These exercises assume you have the EZ Template project open in VS Code. Work in src/main.cpp unless told otherwise.

Exercise 1 — Fix the Broken Code

Find and fix all the errors in this code block (there are 4):

void opcontrol() { while (true) { chassis.opcontrol_tank() if (controller.get_digital(DIGITAL_R1) { intaek.move_voltage(12000); } pros::delay(20); }
▶ SHOW ANSWERS
Fix 1: Line 3 — missing ; after opcontrol_tank() Fix 2: Line 4 — missing closing ) in the if condition Fix 3: Line 5 — typo intaek should be intake Fix 4: Line 9 — missing closing } for while loop

Exercise 2 — Add a Print Statement

In your opcontrol() loop, add a printf that prints the left joystick's Y-axis value every 100ms. Then open pros terminal and move the stick to see it change.

▶ SHOW SOLUTION
printf("Left Y: %d\n", controller.get_analog(ANALOG_LEFT_Y)); pros::delay(100);

Exercise 3 — Write a Custom Function

Create a function called score_game_element() that: spins the intake for 600ms, stops it, drives forward 6 inches, then stops. Call it from autonomous.

▶ SHOW SOLUTION
void score_game_element() { intake.move_voltage(12000); pros::delay(600); intake.brake(); chassis.pid_drive_set(6_in, 90); chassis.pid_wait(); }

Exercise 4 — Format This Mess

Use Shift+Alt+F to auto-format, then manually improve the variable names:

int a=200;bool b=false;void x(){if(b){arm.move_velocity(a);}}
🏆
You've completed the Level Up guide! You now know how to read errors, debug with printf, understand execution order, and write clean formatted code. You're ready to tackle the Advanced Robot Programming guide.
⚙ STEM Highlight Computer Science: Compilation Pipeline & Error Taxonomy
The PROS build process has four distinct phases: preprocessing (expand #include and #define macros), compilation (C++ source to object files), assembly (object files to binary), linking (combine all object files + libraries). Errors from each phase look different: preprocessor errors on include paths, compilation errors on syntax/type mismatches, linker errors on undefined symbols. Understanding which phase produced your error tells you exactly where to look — a linker error means the code compiles but a function is missing its implementation.
🎤 Interview line: “The build pipeline has four stages — preprocessing, compilation, assembly, linking. Each produces different error types. A linker error means all individual files compiled but a function was declared in a header without being defined anywhere. Knowing the pipeline tells you exactly where to look for each error.”
🔬 Check for Understanding
You get the error: undefined reference to ‘armControl’. This is most likely a:
Syntax error — you forgot a semicolon in armControl
Linker error — armControl is declared (probably in a header) but not defined (implemented) in any .cpp file
Runtime error — armControl crashes when it runs
Preprocessor error — the #include for armControl is missing
▶ Keep Going

Ready for real robot code? The next step is writing a full competition program with drive, arm, intake, and autonomous.

🤖 Advanced Robot Programming → 📄 Organizing Code → 🏷 Naming Conventions →
Related Guides
🤖 Advanced Robot Code → 📄 Organizing Code → 🔬 PID Diagnostics →
← ALL GUIDES