XIAO ESP32C3 Bluetooth and Serial Weirdness

I have a Seeed XIAO ESP32C3 board. It has a bluetooth module embedded in it. I'm using the Arduino IDE 2.3.2. I set up my IDE by following Seeed's set up instructions here.

I'm playing with the Example code UART, located in the BLE folder for the XIAO_ESP32C3

When the code runs, it creates a BLE server that will register call backs, then creates a service with a characteristic. When a client connects to the server, the value (txValue) of the characteristic should start increasing by 1 every so many milliseconds, and the server notifies the client each time the value is changed.
When I test this with a phone, the value does start changing, but it doesn't start counting up. Instead, the value changes to a variety of seemingly random characters and symbols.

To try and figure out why the value isn't counting up, I added the line

Serial.println("Value: " + txValue);

so that I'd be able to see what's going on with the value.

Here is my code:

/*
    Video: https://www.youtube.com/watch?v=oCMOYS71NIU
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
    Ported to Arduino ESP32 by Evandro Copercini

   Create a BLE server that, once we receive a connection, will send periodic notifications.
   The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
   Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" 
   Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with  "NOTIFY"

   The design of creating the BLE server is:
   1. Create a BLE Server
   2. Create a BLE Service
   3. Create a BLE Characteristic on the Service
   4. Create a BLE Descriptor on the characteristic
   5. Start the service.
   6. Start advertising.

   In this example rxValue is the data received (only accessible inside that function).
   And txValue is the data to be sent, in this example just a byte incremented every second. 
*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t txValue = 0;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"


class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      String rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++)
          Serial.print(rxValue[i]);

        Serial.println();
        Serial.println("*********");
      }
    }
};


void setup() {
  Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("UART Service");

  // Create the BLE Server
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pTxCharacteristic = pService->createCharacteristic(
                    CHARACTERISTIC_UUID_TX,
                    BLECharacteristic::PROPERTY_NOTIFY
                  );

  pTxCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_RX,
                      BLECharacteristic::PROPERTY_WRITE
                    );

  pRxCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service
  pService->start();

  // Start advertising
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void loop() {

  if (deviceConnected) {
    Serial.println("Value: " + txValue);
    pTxCharacteristic->setValue(&txValue, 1);
    pTxCharacteristic->notify();
    txValue++;
    delay(10); // bluetooth stack will go into congestion, if too many packets are sent
  }

  // disconnecting
  if (!deviceConnected && oldDeviceConnected) {
    delay(500); // give the bluetooth stack the chance to get things ready
    pServer->startAdvertising(); // restart advertising
    Serial.println("start advertising");
    oldDeviceConnected = deviceConnected;
  }
  // connecting
  if (deviceConnected && !oldDeviceConnected) {
    // do stuff here on connecting
    oldDeviceConnected = deviceConnected;
  }
}

When I ran the code, what I actually got was just... weird. The value of the characteristic somehow seems to become the text that I put into the Serial connection. And then with each iteration, one letter gets removed from the start of the string.

Once my initial text is gone, other strings start appearing as the value and I have no idea where they came from! After "Value: " is gone, the string "start advertising" shows up and then starts disappearing the same way, but the section of code where "start advertising" is put in the Serial connection shouldn't even be activated.

Here is the output from the serial monitor:

Waiting a client connection to notify...
Value: 
alue: 
lue: 
ue: 
e: 
: 
 

start advertising
tart advertising
art advertising
rt advertising
t advertising
 advertising
advertising
dvertising
vertising
ertising
rtising
tising
ising
sing
ing
ng

Can anyone explain what's going on here? What needs to change in the code so that txValue becomes a number that actually starts counting up?

This is not valid syntax. txValue is declared as uint8_t and not String.

Serial.println("Value: " + txValue);

Replace with what you have with this, and the value will count up and will be received in the central.

if (deviceConnected) {
    Serial.print("Value: ");
    Serial.println(txValue);
    pTxCharacteristic->setValue(&txValue, 1);
    pTxCharacteristic->notify();
    txValue++;
    delay(500); // bluetooth stack will go into congestion, if too many packets are sent
  }

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.