Author(s): Rhys Davies
Last Updated: February 10th, 2026
The Bluetooth Device Address (sometimes referred to as a Bluetooth MAC address) is a unique 48-bit identifier assigned to each Bluetooth device by the manufacturer. Bluetooth Addresses are usually displayed as 6 bytes written in hexadecimal and separated by colons (example - 00:11:22:33:FF:EE). They are an essential part of Bluetooth-based protocols. The upper half of a Bluetooth Address (most-significant 24 bits) is the so-called Organizationally Unique Identifier (OUI). [1]
You can think of a MAC address as a unique identifier for a device, this is how your wifi router is connected to.
Think of a MAC address like a "serial number" for a device on a network, like a phone, laptop, or printer. It helps identify that device so other devices on the same network know who they're talking to.
Every device that connects to a network (like Wi-Fi or Ethernet) has one of these unique serial numbers. It's not something you see often, but it's always there in the background, helping devices communicate with each other.
So, if you're sending a message or file over a network, the MAC address makes sure the message goes to the right device. It's kind of like sending a letter with a unique ID to make sure it reaches the correct house.
Most of the CRFC teams use Playstation Dualsense bluetooth controllers connected to the microcontrollers that drive their robots via bluetooth. This begins to be a problem because both teams have up to 20 robots in total, especially as more teams join the conference. We recommend each team utilizes bluetooth filtering to ensure their robots will connect with their controllers. A filter can be easily set up if the team records each of their playstation or bluetooth compatible controllers and creates a lookup table, this can also be used to assign controllers to robots.
| Robot ID | Robot Name | Position | Controller Mac Address | Other robot-specific parameters |
|---|---|---|---|---|
| 0 | James Bond | Lineman | FF:FF:FF:FF:FF:00 | … |
| 1 | Hederman | Wide Receiver | FF:FF:FF:FF:FF:01 | … |
| 2 | Stonegoblin9 | Quarterback | FF:FF:FF:FF:FF:02 | … |
| 3 | Luke Skywalker | Lineman | FF:FF:FF:FF:FF:03 | … |
| 4 | KD6-3.7 | Kicker | FF:FF:FF:FF:FF:04 | … |
| 5 | Barry Allen | Runningback | FF:FF:FF:FF:FF:05 | … |
Language: C/C++
Applies a robot-specific configuration, assigning a controller to a configured robot. However, the downsides of this method are if a controller runs out of battery, code changes will be needed to update configured mac address.
#define NUM_ROBOTS 6
typedef enum robot_type {
lineman,
wide_receiver,
running_back,
center,
kicker,
quarter_back,
} robot_type_t;
typedef struct robot_config {
uint8_t index; // robot index in array (useful for writing to EEROM)
const char* robot_name; // string name of robot
robot_type_t bot_type; // robot field position
const char* controller_mac; // robot controller mac address
...
} robot_config_t;
// url to spreadsheet (recommend google sheets)
constexpr robot_config robot_configuration_array[NUM_ROBOTS] = {
// idx bot_name bot_type controller_mac other_params
{ 0, "James Bond", lineman, "FF:FF:FF:FF:FF:00", ... },
{ 1, "Hederman Wide", wide_receiver, "FF:FF:FF:FF:FF:01", ... },
{ 2, "Stonegoblin9", quarterback, "FF:FF:FF:FF:FF:02", ... },
{ 3, "Luke Skywalker", lineman, "FF:FF:FF:FF:FF:03", ... },
{ 4, "KD6-3.7", kicker, "FF:FF:FF:FF:FF:04", ... },
{ 5, "Barry Allen", runningback, "FF:FF:FF:FF:FF:05", ... }
};
Language C/C++
This example shows how you can potentially implement a searching strategy, where the microcontroller searches for devices within a predefined array of mac addresses
controller_array. This implementation allows you to allocate different controllers for a given robot, this is especially useful in competition settings.
Your implementation will heavily depend on the platform and bluetooth libraries
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#define NUM_ROBOTS 6
#define NUM_CONTROLLERS 12
BLEScan* pBLEScan;
bool controllerFound = false;
int foundRobotIndex = -1;
typedef enum robot_type {
lineman,
wide_receiver,
running_back,
center,
kicker,
quarter_back,
} robot_type_t;
typedef struct robot_config {
uint8_t index; // robot index in array (useful for writing to EEROM)
const char* robot_name; // string name of robot
robot_type_t bot_type; // robot field position
const char* controller_mac; // robot controller mac address
...
} robot_config_t;
constexpr const char* controller_array [NUM_CONTROLLERS] {
"FF:FF:FF:FF:FF:00",
"FF:FF:FF:FF:FF:01",
"FF:FF:FF:FF:FF:02",
"FF:FF:FF:FF:FF:03",
"FF:FF:FF:FF:FF:04",
"FF:FF:FF:FF:FF:05"
"FF:FF:FF:FF:FF:06",
"FF:FF:FF:FF:FF:07",
"FF:FF:FF:FF:FF:08",
"FF:FF:FF:FF:FF:09",
"FF:FF:FF:FF:FF:10",
"FF:FF:FF:FF:FF:11"
}
// url to spreadsheet (recommend google sheets)
constexpr robot_config robot_configuration_array[NUM_ROBOTS] = {
// idx bot_name bot_type other_params
{ 0, "James Bond", lineman, ... },
{ 1, "Hederman Wide", wide_receiver, ... },
{ 2, "Stonegoblin9", quarterback, ... },
{ 3, "Luke Skywalker", lineman, ... },
{ 4, "KD6-3.7", kicker, ... },
{ 5, "Barry Allen", runningback, ... }
};
class RobotAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
const char* foundMac = advertisedDevice.getAddress();
for (int i = 0; i < NUM_ROBOTS; i++) {
if (foundMac == controller_array[i]) {
controllerFound = true;
foundRobotIndex = i;
Serial.println("=== CONTROLLER FOUND ===");
Serial.printf("Index: %d\n", foundRobotIndex);
pBLEScan->stop();
break;
}
}
}
};
void setup() {
Serial.begin(115200);
Serial.println("Starting Bluetooth Device Search ...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new RobotAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); // better detection
pBLEScan->setInterval(100);
pBLEScan->setWindow(99);
}
void loop() {
if (!controllerFound) {
Serial.println("Re-scanning for controllers ...");
pBLEScan->start(5, false); // scan for 5 seconds
delay(2000);
} else {
Serial.println("Controller connected.");
// your robot code here
}
}