• VEXcode Robotics Logo VEX Robotics Logo
  • VEX API Home Button VEX API Home Button
  • VEX 123 logo in purple VEX 123 logo in white
  • VEX GO logo in lime green VEX GO logo in white
  • VEXcode AIM logo in blue VEXcode AIM logo in white
  • VEX IQ logo in blue VEX IQ logo in white
  • VEX EXP logo in red VEX EXP logo in white
  • VEX V5 logo in red VEX V5 logo in white
  • VEX CTE logo in green VEX CTE logo in white
  • VEX AIR logo in orange VEX AIR logo in white
  • VEXcode VR logo in gold VEXcode VR logo in white
Skip to main content
Ctrl+K

< Back to Platform Select

  • VEX V5
  • VEXlink
  • Serial Link
English
  • Spanish
  • 简体中文
  • VEXcode Robotics Logo

Section Navigation

  • Blocks
  • Python
  • C++
    • Drivetrain
    • Motors and Motor Controller
    • Controller
    • Brain
    • Competition
    • Smart Port Devices
    • 3-Wire Devices
    • Console
    • Logic
    • VEXlink
      • Message Link
      • Serial Link
    • CTE Workcell

Platform Navigation

  • VEX 123 logo in purple VEX 123 logo in white
  • VEX GO logo in lime green VEX GO logo in white
  • VEXcode AIM logo in blue VEXcode AIM logo in white
  • VEX IQ logo in blue VEX IQ logo in white
  • VEX EXP logo in red VEX EXP logo in white
  • VEX V5 logo in red VEX V5 logo in white
  • VEX CTE logo in green VEX CTE logo in white
  • VEX AIR logo in orange VEX AIR logo in white
  • VEXcode VR logo in gold VEXcode VR logo in white

Serial Link#

  • Introduction

  • Class Constructors

  • Class Destructor

  • Parameters

  • Notes

  • Example

  • Member Functions

    • isLinked

    • send

    • receive

    • received

Introduction#

The serial_link class allows for a stream of raw bytes to be sent between robots. It’s designed for robot-to-robot communication where the transmitting and receiving robot both understand the contents of the data stream.

Every usage of send adds data to the linked V5 Brain’s queue, and the queue is read first-in, first-out (FIFO). If multiple messages are sent before the other V5 Brain uses receive, they will be stored and returned one at a time in the order they were sent. Because messages can queue, repeatedly sending the same status every loop may create backlog; for time-critical logic, send only when values change.

Important: Both robots must be running projects that use serial_link at the same time, or no data will be sent/received.

Class Constructors#

serial_link(
 int32_t index,
 const char *name,
 linkType type,
 bool isWired = false );

Class Destructor#

Destroys the serial_link object and releases associated resources.

~serial_link();

Parameters#

Parameter

Type

Description

index

int32_t

The Smart Port that the message link is connected to, written as PORTx, where x is the port number (for example, PORT1).

name

const char*

The name of this link. It is recommended that this unique string is long enough that when hashed by vexos it will create a unique ID. A bad link name would be something generic such as “vexlink” as it may be used by another team.

type

linkType

The type of link, either linkType::manager or linkType::worker. This information is used to correctly configure the radio and also determines available bandwidth for transmission and reception. A manager robot has double the available bandwidth (1040 bytes/second) to send information to the worker robot (520 bytes/second).

  • linkType::manager — The serial_link object is a manager
  • linkType::worker — The serial_link object is a worker

isWired

bool

Whether the serial_link object is wired (defaults to false):

  • true — The serial_link object is wired
  • false — The serial_link object is wireless

Notes#

  • VEXlink supports both wireless and wired communication, with wired connections recommending a modified smart cable to prevent power routing issues.

  • For wireless communication, each robot needs a V5 Robot Radio connected to a Smart Port.

  • The VEXlink Radio can be used alongside a V5 Controller’s VEXnet radio, which should be connected to the highest numbered Smart Port to avoid conflicts.

  • To create a VEXlink, both V5 Brains must be connected to a V5 Robot Radio.

Example#

Code for Robot 1

// Create a wireless link in Port 1
serial_link link = serial_link(
  PORT1, // index
  "VEXRoboticsLink123456789", // name
  linkType::manager, // type
  true); // isWired

Code for Robot 2

// Create a wireless link in Port 1
serial_link link = serial_link(
  PORT1, // index
  "VEXRoboticsLink123456789", // name
  linkType::worker, // type
  true); // isWired

Member Functions#

The serial_link class includes the following member functions:

  • isLinked — Checks if the V5 Brains are paired and communicating on this link.

  • send — Sends a message to the paired Brain.

  • receive — Waits for and returns the next incoming message.

  • received — Registers a function to be called whenever a new message is received.

Before calling any serial_link member functions, a serial_link instance must be created, as shown below:

Code for Robot 1

// Create a wireless link in Port 1
serial_link link = serial_link(
  PORT1, // index
  "VEXRoboticsLink123456789", // name
  linkType::manager, // type
  true); // isWired

Code for Robot 2

// Create a wireless link in Port 1
serial_link link = serial_link(
  PORT1, // index
  "VEXRoboticsLink123456789", // name
  linkType::worker, // type
  true); // isWired

isLinked#

Returns whether the V5 Brains on a serial link are paired with one another.

Available Functions
bool isLinked();

Parameters

This function does not have any parameters.

Return Values

Returns a Boolean indicating whether the V5 Brains are linked:

  • true — The two V5 Brains are paired and communicating on this link.
  • false — The two V5 Brains are not paired on this link.
Notes
  • It is good practice to always check to ensure the V5 Brains are linked at the start of a project before running any further code.

Examples

Code for Robot 1

// Create the link
  serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true);

  // Do not run code UNTIL the Brains are linked
  while (!link.isLinked()) {
    wait(0.1, seconds);
  }

  Brain.Screen.print("Robot 1 - Manager");
  Brain.Screen.newLine();
  Brain.Screen.print("Sending message...");

  // Message to send
  const char* message = "Hello Robot 2";

  // Send the message
  link.send((uint8_t*)message, strlen(message));

Code for Robot 2

// Create the link
  serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true);

  // Do not run code UNTIL the Brains are linked
  while (!link.isLinked()) {
    wait(0.1, seconds);
  }
  
  Brain.Screen.print("Robot 2 - Worker");
  Brain.Screen.newLine();
  Brain.Screen.print("Waiting...");

  // Buffer to store incoming bytes
  uint8_t buffer[32] = {0};

  int32_t n = link.receive(buffer, sizeof(buffer) - 1);

  // Null-terminate
  if (n > 0) {
    buffer[n] = 0;

    // Display the message that was sent
    Brain.Screen.clearScreen();
    Brain.Screen.setCursor(1, 1);
    Brain.Screen.print("Robot 2 - Worker");
    Brain.Screen.newLine();
    Brain.Screen.print((char*)buffer);
  }
  else {
    Brain.Screen.newLine();
    Brain.Screen.print("No message received");
  }

send#

Sends a message to the paired Brain.

Available Functions

1 — Sends a message using a byte buffer.

int32_t send( 
  uint8_t *buffer, 
  int32_t  length );

2 — Sends a message using a character buffer.

int32_t send( 
  const char *buffer, 
  int32_t     length );

Parameters

Parameter

Type

Description

buffer

uint8_t* or const char*

The buffer to send to the other linked V5 Brain.

length

int32_t

The length of the buffer to send.

Return Values

Returns an int32_t representing the number of bytes sent.

Examples

Code for Robot 1

// Create the link
  serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true);

  // Do not run code UNTIL the Brains are linked
  while (!link.isLinked()) {
    wait(0.1, seconds);
  }

  Brain.Screen.clearScreen();
  Brain.Screen.setCursor(1, 1);
  Brain.Screen.print("Robot 1 - Manager");

  // Track last sent state
  uint8_t lastState = 255;  // impossible initial value

 // Tell Robot 2 when the screen is being pressed
  while (true) {
    uint8_t state = Brain.Screen.pressing() ? 1 : 0;

    // Only send if state changed
    if (state != lastState) {
      link.send(&state, 1);
      lastState = state;
    }

    wait(0.02, seconds);
  }

Code for Robot 2

// Create the link
  serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true);

  // Do not run code UNTIL the Brains are linked
   while (!link.isLinked()) {
    wait(0.1, seconds);
  }

  Brain.Screen.clearScreen();
  Brain.Screen.setCursor(1, 1);
  Brain.Screen.print("Robot 2 - Worker");
  Brain.Screen.newLine();
  Brain.Screen.print("Waiting...");

  // Track the last state
  uint8_t lastShown = 255;

  while (true) {
    // Variable stores 1 - pressed, 0 - not pressed 
    uint8_t state = 0;
    int32_t n = link.receive(&state, 1, 200);

    // Only update screen if state changes
    if (n == 1 && state != lastShown) {
      Brain.Screen.clearScreen();
      Brain.Screen.setCursor(1, 1);
      Brain.Screen.print("Robot 2 - Worker");
      Brain.Screen.newLine();

      // Display text if Robot 1's screen is being pressed
      if (state == 1) {
        Brain.Screen.print("Manager IS being pressed!");
      } else {
        Brain.Screen.print("Manager is NOT being pressed");
      }

      lastShown = state;
    }
    wait(0.02, seconds);
  }

receive#

Waits for and returns the next incoming message.

Available Functions

1 — Receives a message into a character buffer with optional timeout.

int32_t receive( 
  char    *buffer, 
  int32_t  length, 
  int32_t  timeoutMs = 500);

Parameters

Parameter

Type

Description

buffer

char*

The buffer to store the received message.

length

int32_t

The length of the buffer.

timeoutMs

int32_t

How long in milliseconds receive will wait for a new message only if the queue is empty (defaults to 500ms).

Return Values

Returns an int32_t representing the number of bytes received.

Notes
  • receive returns the next queued message from the other linked V5 Brain.

  • Messages are read in FIFO order (oldest unread first).

  • If the queue is empty when receive is called, it waits up to the specified timeoutMs for a new message.

  • If no message arrives in that window, receive returns 0, and any message sent afterward remains in the queue to be read the next time receive is used.

Examples

Code for Robot 1

// Create the link
  serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true);

  // Do not run code UNTIL the Brains are linked
  while (!link.isLinked()) {
    wait(0.1, seconds);
  }

  Brain.Screen.clearScreen();
  Brain.Screen.setCursor(1, 1);
  Brain.Screen.print("Robot 1 - Manager");

  // Track last sent state
  uint8_t lastState = 255;  // impossible initial value

 // Tell Robot 2 when the screen is being pressed
  while (true) {
    uint8_t state = Brain.Screen.pressing() ? 1 : 0;

    // Only send if state changed
    if (state != lastState) {
      link.send(&state, 1);
      lastState = state;
    }

    wait(0.02, seconds);
  }

Code for Robot 2

// Create the link
  serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true);

  // Do not run code UNTIL the Brains are linked
   while (!link.isLinked()) {
    wait(0.1, seconds);
  }

  Brain.Screen.clearScreen();
  Brain.Screen.setCursor(1, 1);
  Brain.Screen.print("Robot 2 - Worker");
  Brain.Screen.newLine();
  Brain.Screen.print("Waiting...");

  // Track the last state
  uint8_t lastShown = 255;

  while (true) {
    // Variable stores 1 - pressed, 0 - not pressed 
    uint8_t state = 0;
    int32_t n = link.receive(&state, 1, 200);

    // Only update screen if state changes
    if (n == 1 && state != lastShown) {
      Brain.Screen.clearScreen();
      Brain.Screen.setCursor(1, 1);
      Brain.Screen.print("Robot 2 - Worker");
      Brain.Screen.newLine();

      // Display text if Robot 1's screen is being pressed
      if (state == 1) {
        Brain.Screen.print("Manager IS being pressed!");
      } else {
        Brain.Screen.print("Manager is NOT being pressed");
      }

      lastShown = state;
    }
    wait(0.02, seconds);
  }

received#

Registers a function to be called whenever the V5 Brain receives a sent message.

Available Functions

1 — Registers a callback function for every received messages.

void received( 
  void (* callback)(const char *, const char *, double) );

2 — Registers a callback invoked for every received message that includes an additional int32_t field.

void received( 
  void (* callback)(const char *, const char *, int32_t, double) );

3 — Registers a callback invoked only for received messages whose name matches message.

void received( 
  const char *message, void (* callback)(const char *, const char *, double) );

4 — Registers a callback invoked only for received messages whose name matches message, where the message payload includes an additional int32_t field.

void received( 
  const char *message, void (* callback)(const char *, const char *, int32_t, double) );

Parameters

Parameter

Type

Description

message

const char

The message name (string) to match. When a received message’s name matches this value, the callback function is called.

callback

function

A previously defined function that runs when the V5 Brain receives a message matching message.

Return Values

This function does not return a value.

Notes
  • received callbacks are called with four arguments:

Callback Signature

callback(message, linkname, index, value)

Argument

Description

message

The message name that was received (for example, “add”).

linkname

The link name the message was received from.

index

The integer value sent with the message (if provided).

value

The float value sent with the message (if provided).

Examples

Code for Robot 1

// Send left or right when pressed
void screen_pressed() {
  if (Brain.Screen.xPosition() < 240) {
    link.send((uint8_t*)"left", 4);
  } else {
    link.send((uint8_t*)"right", 5);
  }
}

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

// Create the link
serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true);

// Do not run code UNTIL the Brains are linked
  while (!link.isLinked()) {
    wait(0.1, seconds);
  }

  Brain.Screen.print("Robot 1 - Manager");


  Brain.Screen.pressed(screen_pressed);
}

Code for Robot 2

// Called when message received
void received_callback(uint8_t *buffer, int32_t length) {
  char msg[32];

  // Copy safely and null terminate
  int n = (length < 31) ? length : 31;
  memcpy(msg, buffer, n);
  msg[n] = '\0';

  Brain.Screen.clearScreen();
  Brain.Screen.setCursor(1,1);
  Brain.Screen.print("Robot 2 - Worker");
  Brain.Screen.newLine();

  // Display if Robot 1's screen is pressed on left or right
  if (strcmp(msg, "left") == 0) {
    Brain.Screen.print("Manager pressed LEFT");
  }
  else if (strcmp(msg, "right") == 0) {
    Brain.Screen.print("Manager pressed RIGHT");
  }
}

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

// Create the link
serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true);

// Do not run code UNTIL the Brains are linked
  while (!link.isLinked()) {
    wait(0.1, seconds);
  }

  link.received(received_callback);

  Brain.Screen.clearScreen();
  Brain.Screen.setCursor(1,1);
  Brain.Screen.print("Robot 2 - Worker");
  Brain.Screen.newLine();
  Brain.Screen.print("Waiting...");
}

previous

Message Link

next

CTE Workcell

On this page
  • Introduction
  • Class Constructors
  • Class Destructor
  • Parameters
  • Notes
  • Example
  • Member Functions
    • isLinked
    • send
    • receive
    • received
Innovation First, International

VEX and VEX Robotics are trademarks or service marks of Innovation First, Inc. Copyright ©2026. All Rights Reserved. VEX Robotics, Inc. is a subsidiary of Innovation First International, Inc. All other product names / marks of others are the property of their respective owners. Patents and / or Patents Pending - innovationfirst.com/patents
Site Privacy Policy / Site Terms of Use / Cookie Policy / Software Privacy Policy

Visit the VEX Robotics Facebook Page Visit the VEX Robotics Twitter Page Visit the VEX Robotics Instagram Page Visit the VEX Robotics YouTube Page
VEX API Feedback Form

We value your feedback! Use this form to share suggestions, compliments, or report errors with the VEX API. Your input helps us enhance the VEX API documentation.

If you are experiencing technical issues or require customer support, please visit support.vex.com.

  • Send Happy Feedback
  • Send Sad Feedback

Note: the current URL will be shared with your message

By including your email address, you agree that VEX may send you email emails if we have questions about your feedback.
Privacy Policy >
Please provide your feedback. Feedback submitted successfully!
Choose Which VEX IQ Generation to View

VEX IQ (1st gen)

VEX IQ (2nd gen)