Skip to main content
The robotic arm system uses multiple VEX IQ sensors for environment perception, collision avoidance, and system feedback.

Sensor Overview

Distance Sensors

Two distance sensors for object detection and gripper positioning

Bumper Sensor

Collision detection for safety protocols

Inertial Sensor

Built-in heading tracking for base rotation

TouchLED

Visual status indicator with RGB control

Distance Sensors

The system uses two VEX IQ Distance Sensors for different purposes.

Gripper Distance Sensor (PORT7)

Purpose: Detects when the gripper is close enough to grasp an object. Initialization (vex_brain/src/main.py:67):
self.gripper_distance = Distance(Ports.PORT7)
Detection Range: 0-40mm Usage in Pick Sequence (vex_brain/src/main.py:437):
data = self.perception.process_sensor_distance(
    self.sensor.gripper_distance, 
    min_d=0, 
    max_d=40
)

if data['detected']:
    # Stop arm movement - object is in gripper range
    self.control.shoulder_motor.set_stopping(BRAKE)
    self.control.elbow_motor.set_stopping(BRAKE)
    return True
Why Short Range?
The gripper sensor uses a very short range (0-40mm) to ensure the gripper is precisely positioned before attempting to close. This prevents the gripper from closing on empty space.

Base Distance Sensor (PORT9)

Purpose: Scans the environment during 360° rotation to detect objects. Initialization (vex_brain/src/main.py:69):
self.base_distance = Distance(Ports.PORT9)
Detection Range: 50-345mm Usage in Scan Service (vex_brain/src/main.py:373):
data = self.perception.process_sensor_distance(
    self.sensor.base_distance, 
    min_d=50, 
    max_d=345
)

if data['detected']:
    # Pause rotation for camera capture
    self.control.base_motor.stop()
    self.comms.send_message('scan_service', {
        'state': 'detected',
        'angle': current_angle,
        'distance': data['distance'],
        'size': data['size']
    })
    wait(2, SECONDS)  # Allow Raspberry Pi to capture image
    self.control.base_motor.spin(FORWARD, speed, RPM)
Range Explanation:
  • Minimum 50mm: Filters out false positives from nearby structures
  • Maximum 345mm: Limits detection to workspace area

Distance Sensor Methods

Get Distance (vex_brain/src/main.py:84-85):
def get_distance(self, sensor):
    return sensor.object_distance(MM)
Get Object Size (vex_brain/src/main.py:87-88):
def get_object_size(self, sensor):
    return sensor.object_rawsize()
The object_rawsize() method returns a relative size measurement that increases as the object gets closer or is physically larger. This helps distinguish between small nearby objects and large distant objects.

Sensor Verification

Check Installation (vex_brain/src/main.py:96-101):
def check_sensors(self):
    return all([
        self.base_distance.installed(),
        self.gripper_distance.installed(),
        self.bumper.installed()
    ])
Run the check service to verify sensors:
# From Raspberry Pi
robot.serial_manager.send_message('check_service', {})

Bumper Sensor (PORT10)

Purpose: Safety collision detection for the shoulder joint. Initialization (vex_brain/src/main.py:70):
self.bumper = Bumper(Ports.PORT10)

Safety Protocol

The bumper sensor is integrated into the shoulder safety system (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():
        # EMERGENCY STOP
        self.control_module.general_stop()
        self.sensor_module.set_color(LED_COLORS['ERROR'])  # Red LED
        
        # RETRACT
        self.control_module.shoulder_motor.spin(REVERSE, speed_reverse)
        wait(2, SECONDS)
        self.control_module.shoulder_motor.stop(HOLD)
        return True
    else:
        # NORMAL OPERATION
        self.control_module.shoulder_motor.spin(FORWARD, speed_forward)
        self.sensor_module.set_color(LED_COLORS['WARNING'])  # Orange LED
        return False

Bumper Usage

1

Safety Service Initialization

During the safety service, the shoulder raises until the bumper is pressed:
while not shoulder_complete:
    shoulder_complete = safety.check_shoulder_safety(80, 10)
This establishes the upper limit of shoulder travel.
2

Runtime Protection

During operation, if the bumper is pressed unexpectedly, the system:
  1. Stops all motors immediately
  2. Sets LED to red (ERROR)
  3. Retracts the shoulder
  4. Logs the collision event
Mounting:
Mount the bumper sensor at the maximum shoulder extension point. It should be pressed only when the shoulder reaches its mechanical limit.

Inertial Sensor (Built-in)

The VEX IQ Brain has a built-in inertial sensor that provides heading information. Initialization (vex_brain/src/main.py:66):
self.inertial = Inertial()

Heading Tracking

Get Angle (vex_brain/src/main.py:81-82):
def get_angle(self):
    return self.inertial.heading()  # Returns 0-360 degrees

Base Motor Control

The inertial sensor enables precise angle positioning for the base motor (vex_brain/src/main.py:180-192):
def move_motor_to_angle(self, motor, target, speed):
    if motor == self.base_motor:
        current = self.sensor_module.get_angle()
        
        # Calculate shortest path
        delta = (target - current + 360) % 360
        if delta > 180: 
            delta -= 360
        
        direction = FORWARD if delta > 0 else REVERSE
        target_angle = (current + delta) % 360
        
        # Closed-loop control
        while abs(self.sensor_module.get_angle() - target_angle) > 2:
            motor.spin(direction, speed, RPM)
            wait(10, MSEC)
        motor.stop()

Scan Tracking

During scanning, the inertial sensor tracks total rotation (vex_brain/src/main.py:363-371):
current_angle = self.sensor.get_angle()

# Calculate angular delta with wraparound handling
delta = current_angle - self.scan_variables['last_angle']
if delta > 180: delta -= 360
elif delta < -180: delta += 360

self.scan_variables['accumulated_rotation'] += abs(delta)
self.scan_variables['last_angle'] = current_angle

# Stop when 360° complete
if self.scan_variables['accumulated_rotation'] >= 360:
    self.control.base_motor.stop()
    return True

Calibration

The inertial sensor auto-calibrates on boot. For best results, keep the robot stationary during the first 2-3 seconds after powering on.
Manual calibration (currently disabled in code):
# vex_brain/src/main.py:78-79
# def calibrate_inertial(self):
#     self.inertial.calibrate()

TouchLED (PORT8)

The TouchLED provides visual feedback about system status. Initialization (vex_brain/src/main.py:68):
self.touchled = Touchled(Ports.PORT8)

Color Definitions

LED Color Codes (vex_brain/src/main.py:17-23):
LED_COLORS = {
    'ERROR': (255, 0, 0),         # Red: Error/Stop
    'WARNING': (255, 150, 0),     # Orange: Warning
    'READY': (0, 255, 0),         # Green: Ready
    'RUNNING': (0, 0, 255),       # Blue: Process Running
    'INIT': (255, 255, 255)       # White: Initialization
}

Set Color Method

Usage (vex_brain/src/main.py:93-94):
def set_color(self, color):
    self.touchled.set_color(*color)  # Unpack RGB tuple

Status Indicators

ColorMeaningWhen It Appears
WhiteInitializationSystem startup
GreenReadyCheck passed, object detected
BlueRunningScanning active, motors moving
OrangeWarningShoulder moving, caution
RedErrorCollision, emergency stop

Sensor Data Processing

The PerceptionModule processes sensor data for decision-making. Distance Processing (vex_brain/src/main.py:111-122):
class PerceptionModule:
    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'])
        else:
            self.current_object_size = 0
            self.object_detected = False
            self.sensor.set_color(LED_COLORS['RUNNING'])
            
        return {
            'distance': dist, 
            'size': self.current_object_size, 
            'detected': self.object_detected
        }

Sensor Troubleshooting

Possible causes:
  1. Sensor not installed in correct port
  2. Object outside detection range
  3. Object surface not reflective enough
  4. Sensor obstructed
Solution:
# Check sensor installation
if not sensor.installed():
    print("Sensor not detected on port")

# Check raw distance reading
print(f"Distance: {sensor.object_distance(MM)}mm")
print(f"Size: {sensor.object_rawsize()}")
Possible causes:
  1. Bumper not pressed firmly enough
  2. Mechanical alignment issue
  3. Port connection loose
Solution:
# Test bumper reading
if bumper.pressing():
    print("Bumper PRESSED")
else:
    print("Bumper NOT pressed")
Possible causes:
  1. Robot moved during boot
  2. Long operation time (thermal drift)
  3. Need recalibration
Solution:
  1. Power cycle the VEX Brain
  2. Keep robot still during startup
  3. Uncomment calibration code if needed
Check:
# Test LED directly
touchled.set_color(255, 0, 0)  # Red
wait(1, SECONDS)
touchled.set_color(0, 255, 0)  # Green
wait(1, SECONDS)
touchled.set_color(0, 0, 255)  # Blue

Sensor Verification Checklist

1

Visual Inspection

  • All sensors firmly connected to correct ports
  • No physical obstructions
  • LED indicators on sensors (if present) are lit
2

Run Check Service

# From Raspberry Pi
robot.serial_manager.send_message('check_service', {})
Expected response:
{"type": "check_service", "data": {"state": "approved"}}
3

Test Individual Sensors

Modify main.py to print sensor values:
print(f"Base dist: {self.sensor.get_distance(self.sensor.base_distance)}")
print(f"Gripper dist: {self.sensor.get_distance(self.sensor.gripper_distance)}")
print(f"Bumper: {self.sensor.is_bumper_pressed()}")
print(f"Angle: {self.sensor.get_angle()}")
4

Run Safety Service

This tests bumper sensor integration:
robot.serial_manager.send_message('safety_service', {})

Next Steps

Wiring Diagram

See complete port assignments and connections

Communication

Learn how sensor data is transmitted to Raspberry Pi

Perception Module

Understand sensor data processing and object detection

Build docs developers (and LLMs) love