How to use BLE in the seeedstudio xiao sense to connect and transfer data to mobile device

I need to connect my seeedstudio nrf52840 to my mobile device and transfer data to it , without applications like Lightblue etc. How do I connect it with the inbuilt Bluetooth application in mobile devices, Are there any libraries or GitHub repos, or how can I achieve this?.

This is for transmitting audio captured on the board to my mobile device, is it possible?

or is it possible to create a web application that could transfer and connect to the BLE module?

Hi there,
Not sure what you mean, but You can compile code with things like

#include <ArduinoBLE.h>

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Bluetooth® Low Energy LED Service
// Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

to communicate over BLE with mobile devices, Creating services the you can connect to to pass data to or read data, strings, binary or booleans… :grinning:
Are you mentioning the PDM microphone onboard the Xiao Sense , Is it the data you want to send to a near by mobile over BLE to hear the sound? Is this what you wish ?
HTH
GL :slight_smile: PJ

1 Like

Yeah that 's exactly what I want to do , I will attach the code I have been working on

,In this the connection is established and when connection is established ,it starts recoding aswell .But the services is not displayed in my mobile device, I can’t access the data that’s transmitted .I can view the data in the serial ploter and in the serial monitor .

#include <ArduinoBLE.h>
#include <mic.h> // Assuming this is your microphone library

// Microphone Settings (Unchanged)
#define DEBUG 1
#define SAMPLES 100

mic_config_t mic_config = {
  .channel_cnt = 1,
  .sampling_rate = 16000,
  .buf_size = 1600,
  .debug_pin = LED_BUILTIN
};

NRF52840_ADC_Class Mic(&mic_config);
int16_t recording_buf[SAMPLES];
volatile static bool record_ready = false;

// BLE UUIDs
#define SERVICE_UUID "12347778-1984-1234-1234-123456789012"
#define CHARACTERISTIC_UUID_AUDIO "87654321-4321-7777-4321-210987654321"

// BLE Service and Characteristic
BLEService audioService(SERVICE_UUID);
BLECharacteristic audioDataCharacteristic(CHARACTERISTIC_UUID_AUDIO, BLERead | BLENotify, 2 * SAMPLES); // 2 * SAMPLES to accommodate the size of the audio buffer

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

  // Microphone initialization
  Mic.set_callback(audio_rec_callback);
  if (!Mic.begin()) {
    Serial.println("Mic initialization failed");
    while (1);
  }
  Serial.println("Mic initialization done.");

  // BLE initialization
  if (!BLE.begin()) {
    Serial.println("Starting BLE failed!");
    while (1);
  }

  BLE.setLocalName("SCT Audio");
  BLE.addService(audioService);
  audioService.addCharacteristic(audioDataCharacteristic);
  BLE.advertise();
  Serial.println("BLE Peripheral is now advertising");
}

void loop() {
  BLEDevice central = BLE.central();

  if (central) {
    Serial.println("Connected to central device");
    
    while (central.connected()) {
      if (record_ready) {
        // Plot the audio data in the Serial Plotter
        for (int i = 0; i < SAMPLES; i++) {
          Serial.println(recording_buf[i]);
        }

        // Transmit the audio data
        audioDataCharacteristic.writeValue((uint8_t*)recording_buf, 2 * SAMPLES);
        Serial.println("Audio data transmitted over BLE");
        record_ready = false;
      }
    }

    Serial.println("Disconnected from central device");
  }
}

static void audio_rec_callback(uint16_t *buf, uint32_t buf_len) {
  static uint32_t idx = 0;
  
  for (uint32_t i = 0; i < buf_len; i++) {
    recording_buf[idx++] = buf[i];
    if (idx >= SAMPLES){ 
      idx = 0;
      record_ready = true;
      break;
    } 
  }
}

I am using Light Blue in my mobile device for connection,also the product is seesdstudio nrf52840 xiao sense tinyml ,the one with inbuilt PDM micro phone and BLE

Hi there,
What Mobile phone you using , If it’s older Iphone , NO BLE compatible.
I’m using Samsung S9+ AOK. With Light blue or NrfConnect.
HTH
GL :slight_smile: PJ

I am using Iphone X with LightBlue

Is there anything wrong with the code, I am using iphone X with LightBlue

Hi there,
Code compiles fine, It’s definitely not following the BLE connection setup standards,
It advertises an Empty service?
I’m using Nrf connect both on Android phone Sammy S9+ and the Windows PC with a Nrf52 USB Dongle. (a must have for any serious BLE type dev effort , it’s $10.btw) Here is what I see


and this is the serial port;

Mic initialization done.
BLE Peripheral is now advertising

If you connect to it,


its an unknown service that is empty?

you need to finish the sketch by adding the proper write value and Service UUID’s that make sense,
you made yours up?

Here is what a REAL set looks like:

String statusString;
//Create a instance of class BLE services & characteristics
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214");  // Bluetooth® Low Energy LED Service
// Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

BLEService fallService("19B10002-E8F2-537E-4F6C-D104768A1214");
BLEStringCharacteristic fallCharacteristic("19B10003-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify, 20);//4E-6F-20-46-61-6C-6C"No Fall"(READ), Notify ON, 46414c4c "FALL"
BLEFloatCharacteristic impactLevelCharacteristic("19B10004-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEBoolCharacteristic enableFallDetectionCharacteristic("19B10008-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
// BLE Service and Characteristics
BLEService motionService("19B10005-E8F2-537E-4F6C-D104768A1214");
BLEStringCharacteristic motionCharacteristic("19B10006-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify, 20);//4E-6F-20-4D-6F-74-69-6F-6E"No Motion", (READ), Notify ON, 4d4f54494f4e "MOTION"
BLEFloatCharacteristic motionSensitivityCharacteristic("19B10007-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEBoolCharacteristic enableMotionDetectionCharacteristic("19B10009-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

BLEService systemStatusService("19B1000C-E8F2-537E-4F6C-D104768A1214"); // UUID for the service
BLEStringCharacteristic systemStatusCharacteristic("19B1000B-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite, 200 ); // UUID for the characteristic

the numbers need to make sense to not take up too much dimension. Look at some of the streaming IMU data over BLE examples. closer to what you want. But your on the right path.
I wouldn’t write everything to the serial monitor either.just the connection and status information. you need all the time for the BLE peripheral data.
you can’t just BLAST the Data out you need some buffering… to stream it consistently to the BLE client
either low latency or or high through put, you can adjust the methods , use DMA or a FIFO.
HTH
GL :slight_smile: PJ
here is the Nrf connect for desktop with the BLE dongle connected. Red arrow is pointing to empty service with no Data? You need to fix that either with a string or the hex or something.


You have a good start look at those other examples and you’ll find one similar forsure.
search here for "IMU’ BLE data type keywords.
HTH
GL :slight_smile: PJ

Does that mean ,BLE service uuid is different for each services and it’s predefined ?

String statusString;
//Create a instance of class BLE services & characteristics
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214");  // Bluetooth® Low Energy LED Service
// Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

BLEService fallService("19B10002-E8F2-537E-4F6C-D104768A1214");
BLEStringCharacteristic fallCharacteristic("19B10003-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify, 20);//4E-6F-20-46-61-6C-6C"No Fall"(READ), Notify ON, 46414c4c "FALL"
BLEFloatCharacteristic impactLevelCharacteristic("19B10004-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEBoolCharacteristic enableFallDetectionCharacteristic("19B10008-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
// BLE Service and Characteristics
BLEService motionService("19B10005-E8F2-537E-4F6C-D104768A1214");
BLEStringCharacteristic motionCharacteristic("19B10006-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify, 20);//4E-6F-20-4D-6F-74-69-6F-6E"No Motion", (READ), Notify ON, 4d4f54494f4e "MOTION"
BLEFloatCharacteristic motionSensitivityCharacteristic("19B10007-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEBoolCharacteristic enableMotionDetectionCharacteristic("19B10009-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

BLEService systemStatusService("19B1000C-E8F2-537E-4F6C-D104768A1214"); // UUID for the service
BLEStringCharacteristic systemStatusCharacteristic("19B1000B-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite, 200 ); // UUID for the characteristic

is there a BLEservice UUID for audio service or mic .

I have actually updated my code,and I am getting some out put ,but since I am someone from IT background ,I am not able to make sense of the data I am reciving on the other end,I am reciving around 5 hex when i select notifyed .

#include <ArduinoBLE.h>
#include <mic.h> // Assuming this is your microphone library

// Microphone Settings
#define DEBUG 1
#define SAMPLES 100

mic_config_t mic_config = {
  .channel_cnt = 1,
  .sampling_rate = 16000,
  .buf_size = 1600,
  .debug_pin = LED_BUILTIN
};

NRF52840_ADC_Class Mic(&mic_config);
int16_t recording_buf[SAMPLES];
volatile static bool record_ready = false;

// Updated UUIDs
#define SERVICE_UUID "19B10000-E8F2-537E-4F6C-D104768A1214"
#define CHARACTERISTIC_UUID_AUDIO "19B10001-E8F2-537E-4F6C-D104768A1214"

// BLE Service and Characteristic
BLEService audioService(SERVICE_UUID);
// Corrected initialization with explicit value size and fixed length flag
BLECharacteristic audioDataCharacteristic(CHARACTERISTIC_UUID_AUDIO, BLERead | BLENotify | BLEWrite, sizeof(recording_buf), true);

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

  Serial.println("Initializing microphone...");
  Mic.set_callback(audio_rec_callback);
  if (!Mic.begin()) {
    Serial.println("Mic initialization failed");
    while (1);
  }
  Serial.println("Mic initialized.");

  Serial.println("Initializing BLE...");
  if (!BLE.begin()) {
    Serial.println("Failed to start BLE!");
    while (1);
  }

  BLE.setLocalName("SCT Audio");
  BLE.setAdvertisedService(audioService);
  
  audioService.addCharacteristic(audioDataCharacteristic);
  BLE.addService(audioService);

  // Corrected writeValue call with explicit casting
  audioDataCharacteristic.writeValue((uint8_t)0);
  
  BLE.advertise();
  Serial.println("BLE Peripheral is now advertising");
}

void loop() {
  BLEDevice central = BLE.central();

  if (central) {
    Serial.println("Connected to central device");
    
    while (central.connected()) {
      if (record_ready) {
        // Plot the audio data in the Serial Plotter
        for (int i = 0; i < SAMPLES; i++) {
          Serial.println(recording_buf[i]);
        }

        // Transmit the audio data
        audioDataCharacteristic.writeValue((uint8_t*)recording_buf, 2 * SAMPLES);
        Serial.println("Audio data transmitted over BLE");
        record_ready = false;
      }
    }

    Serial.println("Disconnected from central device");
  }
}

static void audio_rec_callback(uint16_t *buf, uint32_t buf_len) {
  static uint32_t idx = 0;
  
  for (uint32_t i = 0; i < buf_len; i++) {
    recording_buf[idx++] = buf[i];
    if (idx >= SAMPLES){ 
      idx = 0;
      record_ready = true;
      break;
    } 
  }
}

This is my updated code ,Is there a guide or documentation for the usage of BLE  and pdm audio capture and transmission in xiao 52840 sense. 

Hi there,
Good, I did see a youtube video of a Streaming BLE Potentiometer data.
Look for that, There is a list of Services and UUiD’s but You can use the Generic ones for testing.
Later you can generate you own on-line. Have a Look here

HTH
GL :slight_smile: PJ
:sleeping: :v:

okay thank you, I will checkout the video

I have gone through that blog before,Now of it mention how to transfer the audio recorded through ble .I am confused on how to transfer the reading through ble, what to give for the uuid s, how to decide the size of transmission data packets and all.