Example sketch for connecting Sparkfun Thing Plus ESP32-C6 to macOS via bluetooth

Hoping someone has a working sketch for this combination.

Take a peek over here Kimi | ESP32-C6 Bluetooth Sketch

Getting these errors on compile:

/private/var/folders/z9/m1hk15kd0qnc3j3pmls72fj00000gn/T/.arduinoIDE-unsaved2026426-6860-e0d2sc.hcmyn/sketch_may26a/sketch_may26a.ino: In member function ā€˜virtual void MyCallbacks::onWrite(BLECharacteristic*)’:
/private/var/folders/z9/m1hk15kd0qnc3j3pmls72fj00000gn/T/.arduinoIDE-unsaved2026426-6860-e0d2sc.hcmyn/sketch_may26a/sketch_may26a.ino:44:54: error: conversion from ā€˜String’ to non-scalar type ā€˜std::string’ {aka ā€˜std::__cxx11::basic_string’} requested
44 | std::string rxValue = pCharacteristic->getValue();
| ~~~~~~~~~~~~~~~~~~~~~^~
/private/var/folders/z9/m1hk15kd0qnc3j3pmls72fj00000gn/T/.arduinoIDE-unsaved2026426-6860-e0d2sc.hcmyn/sketch_may26a/sketch_may26a.ino:54:36: error: no matching function for call to ā€˜BLECharacteristic::setValue(std::string&)’
54 | pTxCharacteristic->setValue(response);
| ~^
~
In file included from /Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLEServer.h:50,
from /Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLEDevice.h:57,
from /private/var/folders/z9/m1hk15kd0qnc3j3pmls72fj00000gn/T/.arduinoIDE-unsaved2026426-6860-e0d2sc.hcmyn/sketch_may26a/sketch_may26a.ino:10:
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:214:8: note: candidate: ā€˜void BLECharacteristic::setValue(const uint8_t*, size_t)’
214 | void setValue(const uint8_t *data, size_t size);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:214:8: note: candidate expects 2 arguments, 1 provided
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:215:8: note: candidate: ā€˜void BLECharacteristic::setValue(const String&)’
215 | void setValue(const String &value);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:215:31: note: no known conversion for argument 1 from ā€˜std::string’ {aka ā€˜std::__cxx11::basic_string’} to ā€˜const String&’
215 | void setValue(const String &value);
| ^
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:216:8: note: candidate: ā€˜void BLECharacteristic::setValue(uint16_t)’
216 | void setValue(uint16_t data16);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:216:26: note: no known conversion for argument 1 from ā€˜std::string’ {aka ā€˜std::__cxx11::basic_string’} to ā€˜uint16_t’ {aka ā€˜short unsigned int’}
216 | void setValue(uint16_t data16);
| ~^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:217:8: note: candidate: ā€˜void BLECharacteristic::setValue(uint32_t)’
217 | void setValue(uint32_t data32);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:217:26: note: no known conversion for argument 1 from ā€˜std::string’ {aka ā€˜std::__cxx11::basic_string’} to ā€˜uint32_t’ {aka ā€˜long unsigned int’}
217 | void setValue(uint32_t data32);
| ~^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:218:8: note: candidate: ā€˜void BLECharacteristic::setValue(int)’
218 | void setValue(int data32);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:218:21: note: no known conversion for argument 1 from ā€˜std::string’ {aka ā€˜std::__cxx11::basic_string’} to ā€˜int’
218 | void setValue(int data32);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:219:8: note: candidate: ā€˜void BLECharacteristic::setValue(float)’
219 | void setValue(float data32);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:219:23: note: no known conversion for argument 1 from ā€˜std::string’ {aka ā€˜std::__cxx11::basic_string’} to ā€˜float’
219 | void setValue(float data32);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:220:8: note: candidate: ā€˜void BLECharacteristic::setValue(double)’
220 | void setValue(double data64);
| ^~
/Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE/src/BLECharacteristic.h:220:24: note: no known conversion for argument 1 from ā€˜std::string’ {aka ā€˜std::__cxx11::basic_string’} to ā€˜double’
220 | void setValue(double data64);
| ~~~^~
Multiple libraries were found for ā€œBLEDevice.hā€
Used: /Users/kmu/Library/Arduino15/packages/esp32/hardware/esp32/3.3.8/libraries/BLE
Not used: /Users/kmu/Documents/Arduino/libraries/ArduinoBLE
exit status 1

Compilation error: conversion from ā€˜String’ to non-scalar type ā€˜std::string’ {aka ā€˜std::__cxx11::basic_string’} requested

The errors are because ESP32 Arduino Core v3.x (you have 3.3.8) changed BLECharacteristic to use the Arduino String type instead of std::string. Here’s the corrected sketch:

/*
  SparkFun Thing Plus ESP32-C6 BLE UART Example
  Compatible with ESP32 Arduino Core v3.x
*/

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

// Nordic UART Service UUIDs
#define SERVICE_UUID        "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

BLEServer *pServer = NULL;
BLECharacteristic *pTxCharacteristic = NULL;
BLECharacteristic *pRxCharacteristic = NULL;

bool deviceConnected = false;

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("Client connected");
    }

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("Client disconnected");
      delay(500);
      pServer->startAdvertising();
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      // v3.x returns String, not std::string
      String rxValue = pCharacteristic->getValue();
      
      if (rxValue.length() > 0) {
        Serial.print("Received from macOS: ");
        Serial.println(rxValue);
        
        // Echo back using String concatenation
        String response = "Echo: " + rxValue;
        pTxCharacteristic->setValue(response);
        pTxCharacteristic->notify();
      }
    }
};

void setup() {
  Serial.begin(115200);
  while (!Serial) { ; }
  delay(1000);
  Serial.println("Starting BLE on Thing Plus ESP32-C6...");

  BLEDevice::init("ThingPlus-C6");

  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);

  // TX: ESP32 -> macOS (Notify)
  pTxCharacteristic = pService->createCharacteristic(
                        CHARACTERISTIC_TX,
                        BLECharacteristic::PROPERTY_NOTIFY
                      );
  pTxCharacteristic->addDescriptor(new BLE2902());

  // RX: macOS -> ESP32 (Write)
  pRxCharacteristic = pService->createCharacteristic(
                        CHARACTERISTIC_RX,
                        BLECharacteristic::PROPERTY_WRITE
                      );
  pRxCharacteristic->setCallbacks(new MyCallbacks());

  pService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  
  BLEDevice::startAdvertising();
  
  Serial.println("Ready! Look for 'ThingPlus-C6' in macOS Bluetooth.");
}

void loop() {
  if (deviceConnected) {
    static unsigned long lastSend = 0;
    if (millis() - lastSend > 2000) {
      lastSend = millis();
      
      String msg = "Heartbeat: " + String(millis() / 1000) + "s";
      pTxCharacteristic->setValue(msg);
      pTxCharacteristic->notify();
      
      Serial.println("Sent: " + msg);
    }
  }
  delay(10);
}

What Changed

  • std::string → String everywhere in BLE callbacks

  • pCharacteristic->getValue() now returns String directly

  • setValue() accepts String directly

Library Note

I also noticed you have both ArduinoBLE and the ESP32 built-in BLE library installed. The ESP32 one is correct for this board. If you want to avoid the ā€œMultiple libraries foundā€ warning, you can temporarily rename or remove /Users/kmu/Documents/Arduino/libraries/ArduinoBLE — but the compiler is already picking the right one, so it won’t block compilation.

Wonderful! Thank you so very much for your kind assistance with this. It compiled and uploaded successfully, but it did not show up on my Mac Bluetooth? However, it did appear on the BLE Controller - Arduino ESP32 app on both my iPad and iPhone.

Now to figure out how to send multiple types of sensor data to Unity 6!

Cheers -

Kevin

Kevin M. Ulmer, Ph.D.
Founder & C.E.O.
ulmer@nu-boats.com
Woods Hole, MA 20543
617•320•4861
nU-Boats.com

Signature logo.png

I thought I would be able to disconnect the USB cable to the Mac now that the sketch has been uploaded and power the Thing Plus from a LiPo battery but it no longer shows up?

Kevin M. Ulmer, Ph.D.
Founder & C.E.O.
ulmer@nu-boats.com
Woods Hole, MA 20543
617•320•4861
nU-Boats.com

Signature logo.png

It should…double check that the other device has ā€˜connect automatically’ checked and its default bluetooth mode matches