I am using an Arduino nano 33 BLE as my peripheral device and a Bluefruit Feather nRF51832. I wanted to learn more about BLE, so I am making a project for passive keyless entry for my early 2000's car. The idea is that I want the peripheral device in my car, constantly broadcasting itself. I am using the Arduino nano 33 BLE for this. In my backpack, I want the central device to be constanly scanning for the module in my car (by the means of MAC address and service uuid). I am using the Bluefruit Feather nRF51832 for this.
I am having a couple of issues with this. The central will always pick up the presence of the peripheral, then connect, but often, it is unable to find the service and/or characteristic where I am storing the "key". Once it does find the service and characteristic, the transaction goes smoothly and as expected.
I am using the BLE scanner to constantly scan for peripheral devices, and when it finds the device with the specified mac address and service uuid, connect. From there if it can't "discover" (not sure exaclty how that works) the service and characteristic, it disconnects and continues scanning.
The problems I am having is that it will find the peripheral, connect, fail to find services and characteristics, then disconnect. It does this about 5 or 6 times, then the entire board freezes, presumably because it ran out of ram? I am no c++ developer, nor embedded systems engineer, so I am not any good at memory management, if that is the issue I am facing.
If my central never finds a valid mac address or service uuid, it will scan forever without any problems. It's only the consective connect and disconnect actions that seems to cause it to freeze.
My questions are:
- What can I do to keep the board from freezing, requiring a restart in the case of multiple connects and disconnects due to failing to find services and characteritics of a peripheral device?
- Why is my scanner finding the mac address and service uuid, then fail to find the service and characteristic and what can I do to ideally make it find the service and characteritic on the first connection process.
Here is the code for my Central:
#include <bluefruit.h>
#include "decryption.h"
BLEClientService greetingService("180C"); // Service UUID
BLEClientCharacteristic greetingCharacteristics("2A56"); // Characteristic UUID
void notifyCallback(BLEClientCharacteristic* chr, uint8_t* data, uint16_t len)
{
// Serial.println("Received: ");
Serial.println(data[0]);
uint8_t decryptedKey = decrypt(data[0]);
// Serial.println("Decrypted.. sending back: ");
Serial.println(decryptedKey);
greetingCharacteristics.write8_resp(decryptedKey);
// Serial.println("Sent back");
greetingCharacteristics.disableNotify();
}
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
(void) conn_handle;
(void) reason;
// Serial.println("Disconnected");
}
void connect_callback(uint16_t conn_handle)
{
// Serial.print("Discovering service...");
if(!greetingService.discover(conn_handle))
{
Bluefruit.disconnect(conn_handle);
}
// Serial.println("Found service");
// Serial.print("Discovering characteristic...");
if(!greetingCharacteristics.discover())
{
Bluefruit.disconnect(conn_handle);
}
// Serial.println("Found characteristic");
// Serial.println("Writing to characteristic...");
greetingCharacteristics.write8_resp(69);
// Serial.println("Enabling notify...");
greetingCharacteristics.enableNotify();
// Serial.println("Enabled notify");
// Serial.println("Ready to receive data");
}
void scan_callback(ble_gap_evt_adv_report_t* report)
{
//const uint8_t reversed_mac[] = {0x97, 0x46, 0xBB, 0x45, 0x2F, 0xDD}; // Mac address of module in car
//Serial.printBufferReverse(report->peer_addr.addr, 6, ':');
// Serial.print("\n");
if (Bluefruit.Scanner.checkReportForService(report, greetingService))
{
Bluefruit.Scanner.useActiveScan(false);
Bluefruit.Central.setConnectCallback(connect_callback);
Bluefruit.Central.setDisconnectCallback(disconnect_callback);
//Bluefruit.Central.setConnInterval(9, 12); // 7.5ms to 10ms
// Serial.println("Found target device");
// Serial.println("Connecting...");
Bluefruit.Central.connect(report);
} else
{
// Serial.println("Not found... trying again");
delay(2000);
Bluefruit.Scanner.resume();
}
// if (memcmp(report->peer_addr.addr, reversed_mac, 6) == 0)
// {
// Serial.println("Found target device");
// Serial.println("Connecting...");
// Bluefruit.Central.setConnectCallback(connect_callback);
// Bluefruit.Central.setDisconnectCallback(disconnect_callback);
// Bluefruit.Central.connect(report);
// }
}
void setup()
{
Serial.begin(9600);
while (!Serial) {
delay(10);
}
Bluefruit.begin(0,1);
Bluefruit.setTxPower(0);
Bluefruit.setName("KeyFob");
Bluefruit.setConnLedInterval(250);
greetingService.begin();
greetingCharacteristics.setNotifyCallback(notifyCallback);
greetingCharacteristics.begin();
Bluefruit.Scanner.setRxCallback(scan_callback);
Bluefruit.Scanner.restartOnDisconnect(true);
Bluefruit.Scanner.filterUuid(greetingService.uuid);
Bluefruit.Scanner.setInterval(160, 80);
Bluefruit.Scanner.useActiveScan(false);
// Serial.println("Scanning...");
Bluefruit.Scanner.start(0);
}
void loop()
{
// Do nothing
}