I see you have several “dummy” UUIDs in that code. In my code I only had that many UUID versions to illustrate the buggy treatment of short UUIDs and UUIDs directly based on the Bluetooth_Base_Uuid
.
For your use case you should get rid of all these dummies.
With regards to this
const BleUuid charLong0("00000000-0000-0000-0000-000000002a6e"); //Is there anyway to make this the short UUID as I see this is the long version
That is exactly one of the instances where the bug comes into play.
You could use const BleUuid shortUUID(0x2A6E, )
but when comparing that with longUUID("00002A6E-0000-1000-8000-00805F9B34FB").shorted()
they won’t match although they should.
It’s also wrong that you get these characteristics without the 0000-1000-8000-00805F9B34FB
part but shifted 96 bits to the left.
As long these bugs exist, you need to workaround the issue as shown in my initial issue report code.
I tried to reduced your code to what’s really needed.
Since you already know the address of your desired peripheral the entire scanning block can be omitted. I also kicked out the dummy UUIDs and so I’m left with this.
Give this a try.
#include "Particle.h"
#include <math.h>
SYSTEM_MODE(MANUAL)
SYSTEM_THREAD(ENABLED)
SerialLogHandler logger(LOG_LEVEL_INFO);
const uint16_t vendor = 0x2A23;
const uint8_t BLE_PEER_ADDRESS[] = {0xDF, 0x11, 0xFE, 0xD7, 0x6B, 0x08}; // MAC address of the peripheral device
const BleAddress bleAddress(BLE_PEER_ADDRESS);
const BleUuid serviceUuidRoot("7881CD3D-2F35-6AFA-7C3E-963A648DF526");
const BleUuid charTempUuidLong("00002A6E-0000-1000-8000-00805F9B34FB"); // probably the long UUID reported by nRF Connect App
const BleUuid charTempUuidShort(0x2A6E); // probably the short UUID reported by Bluefruit App
const uint16_t charTempUuidNumeric(0x2A6E); // number literal to work around the current bug
BlePeerDevice peerDevice;
BleCharacteristic charTemp;
uint32_t loopDelay = 1000; // cadence for void loop()
uint16_t rawTemp = 0;
float temp = 0;
bool attachPeer(BleAddress addr, BlePeerDevice& peer, int maxCharacteristics = 20);
void setup()
{
Serial.begin();
}
void loop() {
static uint32_t ms = 0;
if (millis() - ms < loopDelay) return;
ms = millis();
if (!BLE.connected() && !attachPeer(bleAddress, peerDevice)) { // first check connection, if not already connected, try to
Log.warn("could not connect to peer device - retry in 5 seconds"); // when both checks fail log a warning
loopDelay = 5000;
}
else if (charTemp.valid()) {
loopDelay = 1000; // when connected read every second
// could be modulated via delta temp
// more volatile temperature may warrant a lower loop cadance
charTemp.getValue(&rawTemp); // request temperature from BLE peripheral
temp = rawTemp / 100.0; // convert from 100ths, although too simple
Serial.printlnf("Temp %.1f °C (raw: %d)", temp, rawTemp);
}
}
bool attachPeer(BleAddress addr, BlePeerDevice& peer, int maxCharacteristics) {
charTemp = BleCharacteristic(); // invalidate characteristic
if (peer.connected())
peer.disconnect();
peer = BLE.connect(addr);
if (!peer.connected()) {
Log.warn("Couldn't connect to device");
return false;
}
Log.info("Found device and connected to it");
// *** BUG: peer.getCharacteristicByUUID() is currently not guaranteed to actually find the characteristic even when it's there ***
// *** depending on the original UUID the long the short or neither UUID can be found, in the latter case full scan is required ***.
if(!peer.getCharacteristicByUUID(charTemp, charTempUuidLong) && !peer.getCharacteristicByUUID(charTemp, charTempUuidShort)) {
BleCharacteristic chars[maxCharacteristics];
int foundChar = peer.discoverAllCharacteristics(chars, maxCharacteristics); // discover its exposed characteristics
Log.info("Found %d of %d characteristics", foundChar, maxCharacteristics);
for (int c = 0; c < foundChar; c++) {
Serial.printlnf("%d. Characteristic: %s (%04x)", c + 1, (const char *)chars[c].UUID().toString(), chars[c].UUID().shorted());
for (int i = 0; i < 16; i++)
Serial.printlnf(" %02x", chars[c].UUID().rawBytes()[i]);
if (chars[c].UUID() == charTempUuidLong
|| chars[c].UUID().shorted() == charTempUuidLong.shorted()
|| chars[c].UUID().shorted() == charTempUuidShort.shorted()
|| chars[c].UUID().shorted() == charTempUuidNumeric)
{ // check against expected value
charTemp = chars[c];
// alternatively we could just hook up a callback handler to deal with new data
break; // already found what we are looking for, so we can stop here
}
}
}
return charTemp.valid();
}