Bluetooth Low Energy (BLE) is a powerful way to communicate wirelessly between your CodeCell and other devices like smartphones, tablets, and even other microcontrollers. In this guide, we’ll set up BLE on CodeCell, allow it to receive commands from a BLE client, and control its RGB LED based on the received data.
BLE is an energy-efficient version of Bluetooth that allows devices to exchange small amounts of data with low power consumption. Here are it's key concepts:
Before we start testing, your need to download an app to send BLE data on your smartphone. So start by downloading a BLE scanner app:
To make CodeCell advertise itself as a BLE device, we need to initialize BLE, create a service and characteristic, and start advertising.
This code creates a BLE server, advertises a service, and sets up a characteristic that can be read and written by a connected device. The CodeCell will receive the button characteristic and control its onboard RGB LED:
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
#include <CodeCell.h>
CodeCell myCodeCell;
BLECharacteristic *pButtonCharacteristic = NULL;
#define BUTTON_UUID "abcd1234-abcd-1234-abcd-123456789012"
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer *pServer) override {
Serial.println("BLE Connected");
delay(1000);
}
void onDisconnect(BLEServer *pServer) override {
Serial.println("BLE Disconnected");
delay(500);
BLEDevice::startAdvertising(); // Restart advertising
}
};
// Callback class for handling button writes
class ButtonCallback : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) override {
String value = pCharacteristic->getValue();
if (value.length() > 0) {
int buttonState = value[0];
Serial.print("Button State: ");
Serial.println(buttonState);
if (buttonState == 1) {
myCodeCell.LED(255, 0, 0); // Red LED when button is 1
} else {
myCodeCell.LED(0, 255, 0); // Green LED when button is not 1
}
}
}
};
void setup() {
Serial.begin(115200);
myCodeCell.Init(LIGHT); // Initializes the light sensor
BLEDevice::init("CodeCell_BLE"); // Set BLE device name
BLEServer *bleServer = BLEDevice::createServer();
bleServer->setCallbacks(new MyServerCallbacks());
BLEService *bleService = bleServer->createService(BLEUUID("12345678-1234-5678-1234-56789abcdef0"));
// Create BLE characteristic for button state
pButtonCharacteristic = bleService->createCharacteristic(
BUTTON_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
);
pButtonCharacteristic->addDescriptor(new BLE2902());
pButtonCharacteristic->setCallbacks(new ButtonCallback());
bleService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID("12345678-1234-5678-1234-56789abcdef0");
BLEDevice::startAdvertising();
}
void loop() {
// No need to continuously check, LED updates only on BLE write
}
"CodeCell_BLE"
."CodeCell_BLE"
in the BLE Scanner app.BUTTON_UUID
) and send the value:
1
→ LED turns red 🔴0
→ LED turns green 🟢Next we'll define a new BLE characteristic that allows CodeCell to send sensor values to a connected device.
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
#include <CodeCell.h>
CodeCell myCodeCell;
BLECharacteristic *pSensorCharacteristic = NULL;
#define SENSOR_UUID "abcd5678-abcd-5678-abcd-56789abcdef0"
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer *pServer) override {
Serial.println("BLE Connected");
delay(1000);
}
void onDisconnect(BLEServer *pServer) override {
Serial.println("BLE Disconnected");
delay(500);
BLEDevice::startAdvertising(); // Restart advertising
}
};
void setup() {
Serial.begin(115200);
myCodeCell.Init(LIGHT); // Initialize light and proximity sensor
BLEDevice::init("CodeCell_BLE"); // Name the BLE device
BLEServer *bleServer = BLEDevice::createServer();
bleServer->setCallbacks(new MyServerCallbacks());
BLEService *bleService = bleServer->createService(BLEUUID("12345678-1234-5678-1234-56789abcdef0"));
// Create BLE characteristic for sensor data
pSensorCharacteristic = bleService->createCharacteristic(
SENSOR_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY
);
pSensorCharacteristic->addDescriptor(new BLE2902());
bleService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID("12345678-1234-5678-1234-56789abcdef0");
BLEDevice::startAdvertising();
}
void loop() {
if (myCodeCell.Run(10)) { // Read every 100ms (10Hz)
uint16_t proximity = myCodeCell.Light_ProximityRead();
Serial.print("Proximity: ");
Serial.println(proximity);
// Convert proximity value to string and send over BLE
String proximityStr = String(proximity);
pSensorCharacteristic->setValue(proximityStr.c_str());
pSensorCharacteristic->notify(); // Notify connected device
}
}
SENSOR_UUID
) that clients can read and get real-time updates:
We convert the number to a string and send it to the BLE client.
Now that CodeCell is sending proximity sensor data over BLE, you can view it on a phone.
"CodeCell_BLE"
and connectSENSOR_UUID
)
Move an object near the sensor and see how values change!
Now that you can control CodeCell via BLE, try:
Join our Community ~ Be the first to know about new products and get exciting deals!
© 2025 Microbots.