Hi all,
Full disclosure--I'm brand new to networking. I'm doing my best to fumble through the code, but after nearly 10 hours of troubleshooting, I can't figure out how to solve my issue.
The overview of my project is that I will have 20 centrals, and one peripheral. The peripheral will have one read | write String characteristic. The String characteristic will be updated 3 times per second. The centrals will read the characteristic 1 to 2 times per second, and will occasionally write to the characteristic.
Based on my understanding of how peripherals and centrals work, only one central can be connected at any given time. Therefore, my centrals need to connect, read the characteristic, and then immediately disconnect to allow the other centrals to connect.
I want the central to do the following:
step 1) discover the peripheral,
step 2) write a new number to the peripheral's characteristics,
step 3) disconnect, and
step 4) do steps 1-3 all over again infinitely.
Instead if at any point the central has failed to connect to the peripheral (when the serial monitor reports "Connecting ..." then, "Failed to connect!"), it will never be able to discover the peripheral again: (the serial monitor will report "No peripheral discovered" infinitely).
Please see below for my code and for the central's serial output.
Here's my peripheral code:
// Taken from this post: https://forum.arduino.cc/index.php?topic=672382.0
/*
String Characteristic
This example creates a BLE peripheral with a service that contains String
characteristics that can be read and written.
The length of the String characteristic needs to be fixed.
The circuit:
- Arduino Nano 33 BLE Sense board.
You can use a generic BLE central app, like LightBlue (iOS and Android) or
nRF Connect (Android), to interact with the services and characteristics
created in this sketch.
This example code is in the public domain.
*/
#include <ArduinoBLE.h>
//----------------------------------------------------------------------------------------------------------------------
// BLE UUIDs
//----------------------------------------------------------------------------------------------------------------------
#define BLE_UUID_TEST_SERVICE "9A48ECBA-2E92-082F-C079-9E75AAE428B1"
#define BLE_UUID_FILE_NAME "2D2F88C4-F244-5A80-21F1-EE0224E80658"
//----------------------------------------------------------------------------------------------------------------------
// BLE
//----------------------------------------------------------------------------------------------------------------------
BLEService testService( BLE_UUID_TEST_SERVICE );
BLEStringCharacteristic botPosCharacteristic( BLE_UUID_FILE_NAME, BLERead | BLEWrite, 20 );
String botPos = "0123456789ABCDEF";
void setup() {
Serial.begin( 9600 );
//while ( !Serial );
BLE.begin();
// set advertised local name and service UUID:
BLE.setDeviceName( "Arduino Nano 33 BLE Peripheral" );
BLE.setLocalName( "String Characteristic Board" );
BLE.setAdvertisedService( testService );
testService.addCharacteristic( botPosCharacteristic ); // BLE add characteristics
BLE.addService( testService ); // add service
botPosCharacteristic.writeValue( botPos ); // set the initial value for the characeristic:
BLE.advertise(); // start advertising
}
void loop() {
// listen for BLE peripherals to connect:
BLEDevice central = BLE.central();
if ( central )
{
Serial.print( "Connected to central: " );
Serial.println( central.address() );
while ( central.connected() )
{
if ( botPosCharacteristic.written() )
{
botPos = botPosCharacteristic.value();
Serial.print( "New file name: " );
Serial.println( botPos );
}
}
Serial.print( F( "Disconnected from central: " ) );
Serial.println( central.address() );
}
}
And here's my central code:
/*
String Characteristic
This example scans for BLE peripherals until one with the advertised service
"19b10000-e8f2-537e-4f6c-d104768a1214" UUID is found. Once discovered and connected,
it will remotely control the BLE Peripheral's LED, when the button is pressed or released.
The circuit:
- Arduino Nano 33 BLE Sense board.
You can use it with another board that is compatible with this library and the
Peripherals.
This example code is in the public domain.
*/
#include <ArduinoBLE.h>
int count = 2;
void setup() {
Serial.begin(9600);
while (!Serial);
BLE.begin(); // initialize the BLE hardware
Serial.println("BLE Central - Read String");
BLE.scanForUuid("9A48ECBA-2E92-082F-C079-9E75AAE428B1"); // start scanning for peripherals
}
void loop() {
BLEDevice peripheral = BLE.available(); // check if a peripheral has been discovered
delay(400);
if (peripheral) { // discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
if (peripheral.localName() != "String Characteristic Board") {
return;
}
BLE.stopScan(); // stop scanning
readPeriphString(peripheral);
BLE.scanForUuid("9A48ECBA-2E92-082F-C079-9E75AAE428B1"); // start scanning for peripherals
} else { // No peripheral discovered
Serial.println("No peripheral discovered");
}
}
void readPeriphString(BLEDevice peripheral) {
Serial.println("Connecting ..."); // connect to the peripheral
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
peripheral.disconnect();
return;
}
// discover peripheral attributes
Serial.println("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
BLECharacteristic botPosCharacteristic = peripheral.characteristic("2D2F88C4-F244-5A80-21F1-EE0224E80658"); // retrieve the Robot Position characteristic
if (!botPosCharacteristic) {
Serial.println("Peripheral does not have Robot Position Characteristic!");
peripheral.disconnect();
return;
} else if (!botPosCharacteristic.canWrite()) {
Serial.println("Peripheral does not have a writable Robot Position Characteristic!");
peripheral.disconnect();
return;
}
while (peripheral.connected()) { // while the peripheral is connected
Serial.println("Writing to peripheral");
if (count == 2) {
botPosCharacteristic.writeValue((byte)0x02);
count = 4;
}
if (count == 4) {
botPosCharacteristic.writeValue((byte)0x04);
count = 6;
}
if (count == 6) {
botPosCharacteristic.writeValue((byte)0x04);
count = 2;
}
peripheral.disconnect();
return;
}
Serial.println("Peripheral disconnected");
}
Here's an example readout:
16:01:30.896 -> BLE Central - Read String
16:01:31.320 -> No peripheral discovered
16:01:31.735 -> No peripheral discovered
16:01:32.135 -> Found e6:fa:d5:93:80:81 'String Characteristic Board' 9a48ecba-2e92-082f-c079-9e75aae428b1
16:01:32.135 -> Connecting ...
16:01:32.317 -> Connected
16:01:32.317 -> Discovering attributes ...
16:01:32.788 -> Attributes discovered
16:01:32.788 -> Writing to peripheral
16:01:33.364 -> No peripheral discovered
16:01:33.751 -> Found e6:fa:d5:93:80:81 'String Characteristic Board' 9a48ecba-2e92-082f-c079-9e75aae428b1
16:01:33.789 -> Connecting ...
16:01:34.002 -> Connected
16:01:34.002 -> Discovering attributes ...
16:01:34.472 -> Attributes discovered
16:01:34.472 -> Writing to peripheral
16:01:35.040 -> No peripheral discovered
16:01:35.464 -> Found e6:fa:d5:93:80:81 'String Characteristic Board' 9a48ecba-2e92-082f-c079-9e75aae428b1
16:01:36.477 -> Connecting ...
16:01:37.461 -> Failed to connect!
16:01:39.876 -> No peripheral discovered
16:01:40.263 -> No peripheral discovered
16:01:40.680 -> No peripheral discovered
16:01:41.071 -> No peripheral discovered
16:01:41.456 -> No peripheral discovered
16:01:41.872 -> No peripheral discovered
16:01:42.257 -> No peripheral discovered
Thanks for any insights