Menu
Microbots
0
  • Learn
    • Getting Started
    • Maker Builds
    • Education
  • Shop
    • Modules & Parts
    • Tools & Gears
    • Robots & Displays
  • About
    • Our Story
    • Reach Out
    • FAQs
  • Sign in
  • English
  • Your Cart is Empty
Microbots
  • Learn
    • Getting Started
    • Maker Builds
    • Education
  • Shop
    • Modules & Parts
    • Tools & Gears
    • Robots & Displays
  • About
    • Our Story
    • Reach Out
    • FAQs
  • Language

  • 0 0

CodeCell: Connecting with BLE

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:

  • BLE Server → CodeCell acts as a server, advertising itself to other devices.
  • BLE Client → A phone, tablet, or another microcontroller that connects to CodeCell.
  • BLE Service → A collection of characteristics that define the data being sent.
  • BLE Characteristic → A specific data point (e.g., button presses, sensor readings).

Viewing BLE Data on a Smartphone

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:

  • Android → nRF Connect or "BLE Scanner"
  • iOS → nRF Connect

Setting Up BLE on CodeCell

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:

  • If the button value is 1, the LED turns red.
  • If the button value is 0, the LED turns green.
#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
}

How This Code Works

  • BLE Initialization → CodeCell advertises itself as a BLE device called "CodeCell_BLE".
  • BLE Service & Characteristic → A service with a button characteristic is created.
  • BLE Callbacks → The server prints "BLE Connected" when a client connects and "BLE Disconnected" when it disconnects.
  • Advertising Restart → When disconnected, BLE automatically starts advertising again so new devices can connect.

Testing the LED Control  

  • Connect to "CodeCell_BLE" in the BLE Scanner app.
  • Select the service you created - typically displayed as Unknown Service
  • Find the button characteristic (BUTTON_UUID) and send the value:
    • Write 1 → LED turns red 🔴
    • Write 0 → LED turns green 🟢

Sending Sensor Data

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
    }
}

How it works?

  • This code sets up a new characteristic (SENSOR_UUID) that clients can read and get real-time updates:
    • PROPERTY_READ → Allows the client to read the value manually.
    • PROPERTY_NOTIFY → Automatically sends updates when new data is available.
  • The Light_ProximityRead() function gets a value from the onboard light sensor that detects nearby objects. We convert the number to a string and send it to the BLE client.

Try it out

Now that CodeCell is sending proximity sensor data over BLE, you can view it on a phone.

  • Open a BLE app like nRF Connect (Android/iOS)
  • Scan for "CodeCell_BLE" and connect
  • Find the sensor characteristic (SENSOR_UUID)
  • Enable notifications and watch the proximity data update in real-time!
  • Your Serial Monitor data should match the data sent to your phone

Move an object near the sensor and see how values change!


 

  • Share:

Follow

Github

  • About
  • Software
  • Education
  • Contact
  • FAQs
  • Terms
  • Refund Policy
  • Privacy Policy

Join our Community ~ Be the first to know about new products and get exciting deals!

© 2026 Microbots.

★ Reviews

Let customers speak for us

41 reviews
Write a review
80%
(33)
5%
(2)
2%
(1)
5%
(2)
7%
(3)
21
37
A
CodeCell C6
Anonymous

Love it

L
CoilCell
Laszlo Hasenau

Nice to have the drivers integrated, sufficient for very small units, where low force needed.

User picture
L
CodeCell C6 Drive
Leon

Love this thing! The coding for controlling the integrated drivers is extremely intuitive, the chip is fast as always and all the other sensors work like a charm. If there were 6 stars id give all of em but theres only 5 XD

A
CodeCell C6 Drive
Anonymous

Pequeno e esperto. TEM projetos com câmera 📷🎥?
DVR PARA MOTO 🛵?

A
CodeCell C3
Anonymous

Busy developing something that has been a very popular topic in the maker space. Once complete I will share it all with you including the coding.I am really impressed with the punch this little C3 packs. Really a great piece of engineering. Keep up the brilliant work and thank you for making this little giant!!!!!!

123