|
Now that I got logging up and running, I see that the connection process is timing out on the device I want to connect to. It has the advertising type of indirect advertising (BLE_HCI_ADV_TYPE_ADV_IND), which should still be connectable per the standard. Increasing the timeout also doesn't changes anything. I am able to connect to the device through the nRF Connect App on my phone, so it should be connectable. Another thing is that after the connection fails, I am not able to restart the scanning process. I get the following error: Unable to scan - connection in progress. I try running cancelConnect() and disconnect() before rerunning the scan's start() command, but still shows the same error. Any ideas on how to fix these issues? |
Replies: 1 comment 2 replies
|
Here's a portion of my code that is related to the BLE stuff: #include <Arduino.h>
#include <NimBLEDevice.h>
// Settings
NimBLEScan* pBLEScan;
NimBLEClient* pClient;
bool isConnected = false;
// UUID
NimBLEUUID serviceUUID("0000dcba-1212-efde-1523-785fef13d123");
NimBLEUUID configCharacteristicUUID("00000004-1212-efde-1523-785fef13d123");
NimBLEUUID configValueCharacteristicUUID("00000005-1212-efde-1523-785fef13d123");
NimBLEUUID statusCharacteristicUUID("00000006-1212-efde-1523-785fef13d123");
NimBLEUUID commandCharacteristicUUID("0000000b-1212-efde-1523-785fef13d123");
// Characteristics
NimBLERemoteCharacteristic* configCharacteristic;
NimBLERemoteCharacteristic* configValueCharacteristic;
NimBLERemoteCharacteristic* statusCharacteristic;
NimBLERemoteCharacteristic* commandCharacteristic;
// Data
float inlet = 0.0f;
float outlet = 0.0f;
float dp = 0.0f;
bool isFlushing = false;
// put function declarations here:
void startScan();
bool connectToServer(const NimBLEAdvertisedDevice* address);
void pingStatus();
void processSerial();
String handleConfigCommand(String command, bool isGet);
// Scan Callback
class ScanCallback: public NimBLEScanCallbacks {
void onResult(const NimBLEAdvertisedDevice *advertisedDevice) override {
// Check Name
if (!advertisedDevice->haveName() || advertisedDevice->getName().length() < 4 || advertisedDevice->getName().substr(0, 4) != "ADIX")
return;
// Debugging Stuff
Serial.println(advertisedDevice->toString().c_str());
Serial.printf("%d\n", advertisedDevice->getAdvType());
Serial.printf("%d\n", advertisedDevice->getAddressType());
Serial.println(advertisedDevice->isScannable()?"1":"0");
Serial.println(advertisedDevice->isLegacyAdvertisement()?"1":"0");
// Start Connection
Serial.println("FNDS");
pBLEScan->stop(); //Scan can be stopped, we found what we are looking for
isConnected = connectToServer(advertisedDevice);
// Restart if needed
if (!isConnected)
startScan();
}
};
// Client Callback for handling successful connections
class ClientCallback : public NimBLEClientCallbacks {
void onConnectFail(NimBLEClient *pClient, int reason) override {
Serial.println("DCNT");
isConnected = false;
startScan();
}
void onDisconnect(NimBLEClient *pClient, int reason) override {
Serial.println("DCNT");
isConnected = false;
startScan();
}
};
void setup() {
Serial.begin(115200);
NimBLEDevice::init("");
NimBLEDevice::setSecurityAuth(false, false, false);
pBLEScan = NimBLEDevice::getScan(); //create new scan
pBLEScan->setScanCallbacks(new ScanCallback());
pBLEScan->setInterval(50);
pBLEScan->setWindow(50); // less or equal setInterval value
pBLEScan->setActiveScan(true);
pClient = NimBLEDevice::createClient();
pClient->setConnectionParams(12, 12, 0, 250);
pClient->setConnectTimeout(5000);
pClient->setClientCallbacks(new ClientCallback()); // Protect against disconnects
pClient->setSelfDelete(false, false);
// Start
startScan();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
// Flashing LED Indicator for Scanning
if (pBLEScan->isScanning())
digitalWrite(LED_BUILTIN, digitalRead(LED_BUILTIN) ? LOW : HIGH);
// LED for Connection
else
digitalWrite(LED_BUILTIN, isConnected ? HIGH : LOW);
// Handle any serial
processSerial();
// Ping status
pingStatus();
// Delay a bit
delay(500);
}
void startScan() {
int countdown = 0;
while(!pBLEScan->start(0) && countdown < 5) {
delay(1000);
countdown++;
}
}
bool connectToServer(const NimBLEAdvertisedDevice* pDevice) {
// Connection Safety
if (pClient->isConnected())
pClient->disconnect();
// Connect to the remove BLE Server.
if (!pClient->connect(pDevice)) {
pClient->cancelConnect();
pClient->disconnect();
Serial.println("NCTD");
return false;
}
// Obtain a reference to the service we are after in the remote BLE server
NimBLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.println("NSER");
pClient->disconnect();
return false;
}
// Obtain a reference to the characteristics in the service of the remote BLE server.
configCharacteristic = pRemoteService->getCharacteristic(configCharacteristicUUID);
configValueCharacteristic = pRemoteService->getCharacteristic(configValueCharacteristicUUID);
statusCharacteristic = pRemoteService->getCharacteristic(statusCharacteristicUUID);
commandCharacteristic = pRemoteService->getCharacteristic(commandCharacteristicUUID);
if (configCharacteristic == nullptr || configValueCharacteristic == nullptr || statusCharacteristic == nullptr || commandCharacteristic == nullptr) {
Serial.println("NCHR");
pClient->disconnect();
return false;
}
// Success
Serial.println("CNTD");
return true;
} |
You should not be calling connect or scan start from the scan result callback, this holds up the stack and is why you are getting those errors. Set a flag or use a queue of sorts to initiate the connection process in a another task, or in loop.