Black Friday Offer 🔥 Use code BLKFRI at checkout to get 15% OFF on orders above €60!
Bluetooth Low Energy (BLE) is a popular way to communicate wirelessly between electronic devices. It 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!
Join our Community ~ Be the first to know about new products and get exciting deals!
© 2025 Microbots.