-
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? |
Beta Was this translation helpful? Give feedback.
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;
} |
Beta Was this translation helpful? Give feedback.
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.