Hi, I'm somewhat new to Arduino and using Bluetooth so here's the problem I've been having: I'm trying to write a program that scans for other devices with a specific UUID when they are in a certain range and logs them. This information can then later be sent to a phone if one connects to the board. This functionality works, but the Arduino keeps freezing randomly, making me have to reset.
The scan function is with duplicates, so the Arduino will start outputting data to the Serial monitor when it finds a device and keeps doing so, but after anywhere from 10 to 30 seconds, it stops outputting to the Serial monitor even though the device is still powered on and in range. After this, I can no longer find the Arduino listed in my phone's list of BLE devices and cannot connect to it despite normally being able to. I can only conclude that something about scanning for devices is freezing the board.
Also, if I try finding a device in an environment with many Bluetooth connections, the device with the correct UUID won't be detected at all, despite this working in an environment with only a few Bluetooth connections. Is this issue because I'm trying to both scan and advertise simultaneously? Is it impossible for a board to successfully be both a central and a peripheral at different times? Any help is appreciated.
// ArduinoBLE - Version: Latest
#include <ArduinoBLE.h>
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service
// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEByteCharacteristic syncCharacteristic("19B10002-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite | BLENotify);
BLEByteCharacteristic dataCharacteristic("19B10003-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite | BLENotify);
const int ledPin = 9; // pin to use for the LED
const float measuredPower = -70; //built-in BLE value
const float nConstant = 5; //environmental factor
const int uniqueID = 0;
float rssiValue;
float distance;
float traceDistance = 1.829; //in meters
byte currentMaskID = 0;
byte contactList[20];
int contactListIndex = 0;
unsigned long lastTime;
void setup() {
Serial.begin(9600);
// set LED pin to output mode
pinMode(ledPin, OUTPUT);
// begin initialization
if (!BLE.begin())
{
Serial.println("starting BLE failed!");
while (1);
}
// set advertised local name and service UUID:
BLE.setLocalName("SmartMask0");
BLE.setAdvertisedService(ledService);
// add the characteristic to the service
ledService.addCharacteristic(switchCharacteristic);
ledService.addCharacteristic(syncCharacteristic);
ledService.addCharacteristic(dataCharacteristic);
// add service
BLE.addService(ledService);
// set the initial value for the characeristic:
switchCharacteristic.writeValue(0);
syncCharacteristic.writeValue(0);
dataCharacteristic.writeValue(0);
// start scanning for peripheral
BLE.scanForUuid("19B10003-E8F2-537E-4F6C-D104768A1214", true);
// start advertising
BLE.advertise();
Serial.println("BLE enabled");
}
void loop() {
// listen for BLE peripherals to connect:
BLEDevice central = BLE.central();
BLEDevice peripheral = BLE.available();
// if a central is connected to peripheral:
if (central)
{
BLE.stopScan();
Serial.print("Connected to central: ");
Serial.println(central.address()); // print the central's MAC address:
// while the central is still connected to peripheral:
while (central.connected())
{
// if the remote device wrote to the characteristic,
// use the value to control the LED:
if (switchCharacteristic.written())
{
if (switchCharacteristic.value()) // any value
{
Serial.println("LED on");
digitalWrite(ledPin, HIGH); // will turn the LED on
}
else
{ // a 0 value
Serial.println("LED off");
digitalWrite(ledPin, LOW); // will turn the LED off
}
}
if (syncCharacteristic.written())
{
if (syncCharacteristic.value()) //a value
{
for(int i = 0; i < 20; i++) //will send each ID one by one
{
lastTime = millis();
dataCharacteristic.writeValue(contactList[i]);
contactList[i] = 0;
while(millis() - lastTime < 200);
}
contactListIndex = 0;
Serial.println("List data has been sent.");
syncCharacteristic.writeValue(0);
}
}
}
// when the central disconnects, print it out:
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
BLE.scanForUuid("19B10003-E8F2-537E-4F6C-D104768A1214", true);
BLE.advertise();
}
if (peripheral) // find distance of other devices with matching UUID
{
rssiValue = peripheral.rssi();
distance = pow(10, (measuredPower - rssiValue)/(10 * nConstant));
Serial.print("Mask found. Distance: ");
Serial.println(distance);
if(distance < traceDistance) //if distance falls into threshold
{
digitalWrite(ledPin, HIGH); //turn on the LED
bool isInList = false;
currentMaskID = peripheral.localName().substring(9).toInt();
for(int i = 0; i < 20; i++)
{
if(contactList[i] == currentMaskID)
{
isInList = true;
Serial.println("Mask already in list."); //check if this mask is already logged
break;
}
}
if(!isInList) //add to list if not
{
contactList[contactListIndex] = currentMaskID;
Serial.print("Mask logged: ");
Serial.println(peripheral.localName());
contactListIndex++;
}
}
else
{
digitalWrite(ledPin, LOW); //not in threshold, turn off LED
}
}
}