Skip to main content
The VEX IQ Brain (2nd Generation) serves as the real-time control unit for motors and sensors, running MicroPython to handle low-level operations.

Specifications

Processor

ARM Cortex processor optimized for real-time control

Ports

12 smart ports for sensors and motors (PORT1-PORT12)

Programming

MicroPython support with VEX library

Display

Built-in touchscreen for status and debugging

System Architecture

The VEX Brain runs a modular Python architecture defined in vex_brain/src/main.py:

Core Modules

CommunicationManager

Handles JSON-based serial communication with the Raspberry Pi. Implementation (vex_brain/src/main.py:26-60):
class CommunicationManager:
    def __init__(self):
        self.serial_port = None
        self.buffer = bytearray()
        self.message_end = b'\n'
        
    def initialize(self):
        self.serial_port = open('/dev/serial1', 'rb+')
The VEX Brain opens /dev/serial1 for serial communication. This corresponds to the USB connection on the Raspberry Pi side (/dev/ttyACM1).
Message Format:
{
  "type": "scan_service",
  "data": {
    "speed": 20
  }
}

SensorModule

Manages all sensor initialization and reading. Port Assignments (vex_brain/src/main.py:63-71):
SensorPortVariable NamePurpose
InertialBuilt-inself.inertialHeading (0-360°)
DistancePORT7self.gripper_distanceGripper proximity
TouchLEDPORT8self.touchledStatus indicator
DistancePORT9self.base_distanceEnvironment scan
BumperPORT10self.bumperCollision detection
Key Methods:
get_angle() -> float          # Returns 0-360° heading
get_distance(sensor) -> int   # Distance in MM
is_bumper_pressed() -> bool   # Collision detection
set_color(color: tuple)       # LED status (R,G,B)
LED Color Codes (vex_brain/src/main.py:17-23):

INIT

White (255,255,255)System initialization

READY

Green (0,255,0)Ready for operation

RUNNING

Blue (0,0,255)Process active

WARNING

Orange (255,150,0)Caution state

ERROR

Red (255,0,0)Error/Emergency stop

ControlModule

Manages all motor operations with safety limits. Motor Configuration (vex_brain/src/main.py:169-178):
class ControlModule:
    def __init__(self, sensor_module: SensorModule):
        self.base_motor = Motor(Ports.PORT1, True)
        self.shoulder_motor = Motor(Ports.PORT2, True)
        self.elbow_motor = Motor(Ports.PORT3, True)
        self.gripper_motor = Motor(Ports.PORT4, True)
        
        # Safety torque limits
        self.elbow_motor.set_max_torque(95, PERCENT)
        self.shoulder_motor.set_max_torque(95, PERCENT)
Base Motor Control (vex_brain/src/main.py:180-192): The base motor uses inertial sensor feedback for precise angle positioning:
def move_motor_to_angle(self, motor, target, speed):
    if motor == self.base_motor:
        current = self.sensor_module.get_angle()
        delta = (target - current + 360) % 360
        if delta > 180: 
            delta -= 360  # Shortest path
        
        direction = FORWARD if delta > 0 else REVERSE
        target_angle = (current + delta) % 360
        
        while abs(self.sensor_module.get_angle() - target_angle) > 2:
            motor.spin(direction, speed, RPM)
            wait(10, MSEC)
        motor.stop()

SafetyModule

Implements collision avoidance and safe operation protocols. Shoulder Safety (vex_brain/src/main.py:225-237):
def check_shoulder_safety(self, speed_forward: int, speed_reverse: int):
    if self.sensor_module.is_bumper_pressed():
        self.control_module.general_stop()          # Emergency stop
        self.sensor_module.set_color(LED_COLORS['ERROR'])
        self.control_module.shoulder_motor.spin(REVERSE, speed_reverse)
        wait(2, SECONDS)                            # Retract
        self.control_module.shoulder_motor.stop(HOLD)
        return True
    else:
        self.control_module.shoulder_motor.spin(FORWARD, speed_forward)
        self.sensor_module.set_color(LED_COLORS['WARNING'])
        return False
Gripper Current Sensing (vex_brain/src/main.py:239-248): The gripper uses current feedback to detect when it has grasped an object:
def gripper_action(self, action, service):
    threshold = 0.5 if service == 'pick' else 0.3
    self.control_module.gripper_motor.spin(
        FORWARD if action == 'open' else REVERSE, 20
    )
    if self.control_module.get_current(self.control_module.gripper_motor) > threshold:
        self.control_module.gripper_motor.stop(
            HOLD if service == 'pick' else BRAKE
        )
        return True

PerceptionModule

Processes sensor data for object detection during scanning. Distance Processing (vex_brain/src/main.py:111-122):
def process_sensor_distance(self, sensor, min_d, max_d):
    dist = self.sensor.get_distance(sensor)
    if min_d <= dist <= max_d:
        self.current_object_size = self.sensor.get_object_size(sensor)
        self.object_detected = True
        self.sensor.set_color(LED_COLORS['READY'])  # Green
    else:
        self.current_object_size = 0
        self.object_detected = False
        self.sensor.set_color(LED_COLORS['RUNNING']) # Blue
        
    return {
        'distance': dist, 
        'size': self.current_object_size, 
        'detected': self.object_detected
    }

MappingModule

Tracks detected objects during 360° scan. Object Tracking (vex_brain/src/main.py:131-165):
class MappingModule:
    def __init__(self):
        self.objects_map = []
        self.current_object = (0.0, 0.0, 0, 0, False)
    
    def process_object_detection(self, angle, size, dist):
        if size > 0:
            if not self.current_object[4]:  # Start tracking
                self.current_object = (angle, angle, size, dist, True)
            else:  # Update tracking
                self.current_object = (
                    self.current_object[0],
                    angle,
                    max(self.current_object[2], size),
                    self.current_object[3],
                    True
                )
        elif self.current_object[4]:  # End tracking
            self._save_object(angle)
Each detected object is stored with:
  • center_angle: Center of object in degrees
  • width: Angular width of object
  • distance: Distance in mm
  • max_size: Maximum sensor reading

Services

The VEX Brain responds to service requests from the Raspberry Pi.

Check Service

Verifies all sensors and motors are installed. Usage:
# Send from Raspberry Pi
send_message('check_service', {})

# Response
{'type': 'check_service', 'data': {'state': 'approved'}}

Safety Service

Executes safety initialization sequence:
  1. Raise shoulder until bumper pressed
  2. Retract shoulder
  3. Open gripper fully
Implementation (vex_brain/src/main.py:299-316):

Scan Service

Performs 360° rotation while detecting objects. Parameters:
{'speed': 20}  # RPM for base rotation
Process (vex_brain/src/main.py:318-335):
  1. Start base rotation
  2. Continuously check distance sensor (50-345mm range)
  3. When object detected, pause for 2 seconds
  4. Send real-time detection data to Raspberry Pi
  5. Continue until 360° complete
  6. Return complete objects map
Real-time Message (vex_brain/src/main.py:378-383):
{
  "type": "scan_service",
  "data": {
    "state": "detected",
    "angle": 127.5,
    "distance": 180,
    "size": 342
  }
}

Pick/Place Service

Executes picking and placing operations. Base Movement:
{'joint': 'base', 'angle': 90, 'speed': 30}
Arm Movement:
{'joint': 'arm', 'distance': 180, 'action': 'pick'}
{'joint': 'arm', 'distance': 180, 'action': 'place'}
{'joint': 'arm', 'action': 'up'}
Gripper Control:
{'joint': 'gripper', 'action': 'close'}
{'joint': 'gripper', 'action': 'open'}

Programming Environment

VEX Code Studio

The VEX Brain is programmed using VEX Code Studio with Python support. Project Configuration (.vscode/vex_project_settings.json):
{
  "project": {
    "name": "robotic_arm",
    "platform": "IQ2",
    "language": "python"
  }
}

Uploading Code

1

Connect VEX Brain

Connect VEX Brain to computer via USB cable
2

Open VEX Code Studio

Open arm_system/vex_brain/src/main.py in VEX Code Studio
3

Build and Download

Click “Download” to upload the program to the VEX Brain
4

Run Program

The program starts automatically when serial connection is established

Main Loop

The VEX Brain runs a continuous message processing loop (vex_brain/src/main.py:488-505):
def run(self):
    self.comms.initialize()
    self.sensor.set_color(LED_COLORS['INIT'])  # White LED
    
    while True:
        try:
            msg = self.comms.read_message()
            
            if msg:
                self.process_message(msg)
                
                # Execute active services
                if self.states['check_active']: 
                    self.run_service('check')
                if self.states['safety_active']: 
                    self.run_service('safety')
                if self.states['scan_active']: 
                    self.run_service('scan')
                    
        except Exception as e:
            self.sensor.print_screen(f"Error: {str(e)[:20]}", 1, 95)
            self.control.general_stop()

Debugging

Screen Output

Use the built-in screen for debugging:
self.sensor.clear_screen()
self.sensor.print_screen("Status: OK", x=1, y=1)

LED Status

Monitor the TouchLED on PORT8 for system status:
  • White: Starting up
  • Green: Ready and waiting
  • Blue: Scanning active
  • Orange: Moving arm
  • Red: Error or collision detected

Next Steps

Sensor Details

Learn about sensor configuration and calibration

Wiring Guide

Complete port assignments and connections

Communication Protocol

Understand the serial communication protocol

Build docs developers (and LLMs) love