I would like to port this code that I use successfully on an ESP32-S3 to the Nano Matter...
#include <ArduinoBLE.h>
uint8_t probeStatusData[50] = {};
bool CPTscanning = false;
void setup() {
Serial.begin(9600);
Serial.print(millis());
Serial.println(" - here we go...");
BLE.begin();
BLE.setEventHandler(BLEDiscovered, CPTscanned);
}
void loop() {
if (!CPTscanning) {
Serial.println("Scanning...");
BLE.scanForAddress("xx:xx:xx:xx:xx:xx"); // Enter CPT MAC Address Here
CPTscanning = true;
}
BLE.poll();
delay(10);
}
void CPTscanned(BLEDevice CPTprobe) {
BLE.stopScan();
Serial.println("CPT Found");
CPTscanning = false;
if (!CPTprobe.connect()) {
Serial.println("Returning...");
return;
}
Serial.println("Connected");
if (!CPTprobe.discoverService("00000100-caab-3792-3d44-97ae51c1407a")) {
Serial.println("Returning...");
CPTprobe.disconnect();
return;
}
Serial.println("Discovered");
BLEService CPTservice = CPTprobe.service("00000100-caab-3792-3d44-97ae51c1407a");
BLECharacteristic CPTcharacteristic = CPTservice.characteristic("00000101-caab-3792-3d44-97ae51c1407a");
if (!CPTcharacteristic.subscribe()) {
Serial.println("Returning...");
CPTprobe.disconnect();
return;
}
Serial.println("Subscribed!!!");
while (CPTprobe.connected()) {
if (CPTcharacteristic.valueUpdated()) {
CPTcharacteristic.readValue(&probeStatusData, 50);
if (!bitRead(probeStatusData[21], 0)) { // Check for Normal vs. Instant Mode
printData(probeStatusData, 50);
} else {
Serial.println("Instant Read");
}
}
}
}
void printData(const unsigned char data[], int length) {
Serial.print(millis());
Serial.print(" - ");
for (int i = 0; i < length; i++) {
unsigned char c = data[i];
if (c < 16) {
Serial.print("0");
}
Serial.print(c, HEX);
}
Serial.println();
}
On the ESP32-S3 probe disconnects are handled very robustly, it just starts scanning again and reconnects and subscribes.
On the Nano Matter using the Arduino BLE stack, it doesn't recognize if the connection is lost...the while (CPTprobe.connected()) just doesn't seem to work.
I tried replacing the while (CPTprobe.connected()) with a Boolean, but it strangely only works for one disconnection...
#include <ArduinoBLE.h>
uint8_t probeStatusData[50] = {};
bool CPTscanning = false;
bool CPTsubscribed = false;
void setup() {
delay(1000);
Serial.begin(9600);
delay(1000);
Serial.print(millis());
Serial.println(" - here we go...");
if (!BLE.begin()) {
Serial.println("BLE Not Started");
while (1)
;
}
BLE.setEventHandler(BLEDiscovered, CPTscanned);
}
void loop() {
if (!CPTscanning) {
Serial.println("Scanning...");
BLE.scanForAddress("xx:xx:xx:xx:xx:xx"); // Enter CPT MAC Address Here
CPTscanning = true;
}
BLE.poll();
delay(10);
}
void CPTscanned(BLEDevice CPTprobe) {
BLE.stopScan();
Serial.println("CPT Found");
CPTscanning = false;
if (!CPTprobe.connect()) {
Serial.println("Returning...");
return;
}
Serial.println("Connected");
if (!CPTprobe.discoverService("00000100-caab-3792-3d44-97ae51c1407a")) {
Serial.println("Returning...");
CPTprobe.disconnect();
return;
}
Serial.println("Discovered");
BLEService CPTservice = CPTprobe.service("00000100-caab-3792-3d44-97ae51c1407a");
BLECharacteristic CPTcharacteristic = CPTservice.characteristic("00000101-caab-3792-3d44-97ae51c1407a");
if (!CPTcharacteristic.subscribe()) {
Serial.println("Returning...");
CPTprobe.disconnect();
return;
}
CPTsubscribed = true;
Serial.println("Subscribed!!!");
while (CPTsubscribed) {
if (CPTcharacteristic.valueUpdated()) {
CPTcharacteristic.readValue(&probeStatusData, 50);
printData(probeStatusData, 50);
}
if (!CPTprobe.connected()){
CPTsubscribed = false;
return;
}
}
}
void printData(const unsigned char data[], int length) {
Serial.print(millis());
Serial.print(" - ");
for (int i = 0; i < length; i++) {
unsigned char c = data[i];
if (c < 16) {
Serial.print("0");
}
Serial.print(c, HEX);
}
Serial.println();
}
It reconnects and subscribes after the first disconnection, then just scans forever if the probe disconnects a second time.
I just can't figure out how to make recovery from disconnections (which can happen often) more robust on the Nano Matter.
I assume the Arduino BLE stack is correct for this.
If I try to compile with the SiLabs BLE stack I get the error...
fatal error: sl_hci_common_transport.h: No such file or directory
27 | #include "sl_hci_common_transport.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
exit status 1
I tried to play with the the Silicon Labs BLE scan example sketch using the SiLabs BLE stack and I can figure out how to check for the MAC address and stop the scan...
void setup() {
Serial.begin(9600);
}
void loop() {
;
}
void sl_bt_on_event(sl_bt_msg_t* evt) {
sl_status_t sc;
switch (SL_BT_MSG_ID(evt->header)) {
// This event is received when the BLE device has successfully booted
case sl_bt_evt_system_boot_id:
// Print a welcome message
Serial.begin(9600);
Serial.println();
Serial.println("Silicon Labs BLE scan example");
Serial.println("BLE stack booted");
// Start scanning for other BLE devices
sc = sl_bt_scanner_set_parameters(sl_bt_scanner_scan_mode_active, // mode
16, // interval (value * 0.625 ms)
16); // window (value * 0.625 ms)
app_assert_status(sc);
sc = sl_bt_scanner_start(sl_bt_scanner_scan_phy_1m,
sl_bt_scanner_discover_generic);
app_assert_status(sc);
Serial.println("Started scanning...");
break;
// This event is received when we scan the advertisement of another BLE device
case sl_bt_evt_scanner_legacy_advertisement_report_id:
if (evt->data.evt_scanner_legacy_advertisement_report.address.addr[5] == 0
&& evt->data.evt_scanner_legacy_advertisement_report.address.addr[4] == 0
&& evt->data.evt_scanner_legacy_advertisement_report.address.addr[3] == 0
&& evt->data.evt_scanner_legacy_advertisement_report.address.addr[2] == 0
&& evt->data.evt_scanner_legacy_advertisement_report.address.addr[1] == 0
&& evt->data.evt_scanner_legacy_advertisement_report.address.addr[0] == 0) {
sc = sl_bt_scanner_stop();
app_assert_status(sc);
Serial.println("Found");
}
break;
}
}
#ifndef BLE_STACK_SILABS
#error "This example is only compatible with the Silicon Labs BLE stack. Please select 'BLE (Silabs)' in 'Tools > Protocol stack'."
#endif
...but then can go no further as there are no examples that I can find of how how to use the SiLabs BLE stack to make the connection, discover the GATT service and then subscribe.
It seems like the SiLabs BLE stack would be the better way to go, but only for users with very advanced knowledge (not me).
I just need to subscribe to a known update service on a known MAC address and forward the 50 byte payload.
Thank you for any advice.