NRF52840 Express Unable to Connect to Multiple Peripherals

For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
rob1999
 
Posts: 3
Joined: Thu Apr 07, 2022 6:25 pm

NRF52840 Express Unable to Connect to Multiple Peripherals

Post by rob1999 »

I have a Feather nRF52840 Express that I'm to set up as a Central that will connect to multiple peripheral Bluetooth LE devices.

The problem that I'm having is that after it connects to one device, then it stops scanning for any other devices until the first device is disconnected.
When the first device is disconnected, then it will continue scanning and connect to the next device and connect to that one.

I would like it to continue scanning after each device is connected so that multiple peripherals can be connected at the same time.

Here is the code that I'm using:

Code: Select all

#include <Arduino.h>
#include <bluefruit.h>

/**
 * Callback invoked when an connection is established
 * @param conn_handle
 */
void connect_callback(uint16_t conn_handle) {
  BLEConnection* connection = Bluefruit.Connection(conn_handle);
  char peer_name[32] = { 0 };

  connection->getPeerName(peer_name, sizeof(peer_name));

  Serial.print("Connected to ");
  Serial.println(peer_name);
  Serial.println("Done Connecting.");
}

/**
 * Callback invoked when a connection is terminated.
 * @param conn_handle
 * @param reason
 */
void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
  (void) conn_handle;
  (void) reason;

  Serial.println("Disconnected!");
}

/**
 * Callback invoked when scanner finds a device.
 * @param report
 */
void scan_callback(ble_gap_evt_adv_report_t* report) {
  uint8_t buffer[32];
  memset(buffer, 0, sizeof(buffer));

  if(Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, buffer, sizeof(buffer))) {
    // Check to see if device name is what we want to connect to.
    if ((char) buffer[0] == 'V' && (char)buffer[1] == '7') {
      Serial.printf("%14s %s\n", "Found Device ", buffer);

      // MAC is in little endian --> print reverse
      Serial.printBufferReverse(report->peer_addr.addr, 6, ':');
      Serial.print("\n");

      Serial.println("Attempting to connect...");
      Bluefruit.Central.connect(report);
    }
  }

  // For Softdevice v6: after received a report, scanner will be paused
  // We need to call Scanner resume() to continue scanning
  Bluefruit.Scanner.resume();
}

void setup() {
  Serial.begin(115200);
  while ( !Serial ) delay(10);   // for nrf52840 with native usb

  // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 4
  // SRAM usage required by SoftDevice will increase dramatically with number of connections
  Bluefruit.begin(0, 4);
  Bluefruit.setName("Bluefruit52");

  // Start Central Scan
  Bluefruit.setConnLedInterval(250);
  Bluefruit.Scanner.setRxCallback(scan_callback);
  Bluefruit.Central.setConnectCallback(connect_callback);
  Bluefruit.Central.setDisconnectCallback(disconnect_callback);
  Bluefruit.Scanner.restartOnDisconnect(true);
  Bluefruit.Scanner.setInterval(160, 80);       // in units of 0.625 ms
  Bluefruit.Scanner.useActiveScan(true);
  Bluefruit.Scanner.start(0);

  Serial.println("Scanning ...");
}

void loop() {
  // nothing to do
}

User avatar
mikeysklar
 
Posts: 14194
Joined: Mon Aug 01, 2016 8:10 pm

Re: NRF52840 Express Unable to Connect to Multiple Periphera

Post by mikeysklar »

Did you try the full example code for a Central BLEUART?

https://learn.adafruit.com/introducing- ... al-bleuart

Code: Select all

 /*********************************************************************
 This is an example for our nRF52 based Bluefruit LE modules

 Pick one up today in the adafruit shop!

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/

/*
 * This sketch demonstrate the central API(). A additional bluefruit
 * that has bleuart as peripheral is required for the demo.
 */
#include <bluefruit.h>

BLEClientBas  clientBas;  // battery client
BLEClientDis  clientDis;  // device information client
BLEClientUart clientUart; // bleuart client

void setup()
{
  Serial.begin(115200);
//  while ( !Serial ) delay(10);   // for nrf52840 with native usb

  Serial.println("Bluefruit52 Central BLEUART Example");
  Serial.println("-----------------------------------\n");
  
  // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1
  // SRAM usage required by SoftDevice will increase dramatically with number of connections
  Bluefruit.begin(0, 1);
  
  Bluefruit.setName("Bluefruit52 Central");

  // Configure Battery client
  clientBas.begin();  

  // Configure DIS client
  clientDis.begin();

  // Init BLE Central Uart Serivce
  clientUart.begin();
  clientUart.setRxCallback(bleuart_rx_callback);

  // Increase Blink rate to different from PrPh advertising mode
  Bluefruit.setConnLedInterval(250);

  // Callbacks for Central
  Bluefruit.Central.setConnectCallback(connect_callback);
  Bluefruit.Central.setDisconnectCallback(disconnect_callback);

  /* Start Central Scanning
   * - Enable auto scan if disconnected
   * - Interval = 100 ms, window = 80 ms
   * - Don't use active scan
   * - Start(timeout) with timeout = 0 will scan forever (until connected)
   */
  Bluefruit.Scanner.setRxCallback(scan_callback);
  Bluefruit.Scanner.restartOnDisconnect(true);
  Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms
  Bluefruit.Scanner.useActiveScan(false);
  Bluefruit.Scanner.start(0);                   // // 0 = Don't stop scanning after n seconds
}

/**
 * Callback invoked when scanner pick up an advertising data
 * @param report Structural advertising data
 */
void scan_callback(ble_gap_evt_adv_report_t* report)
{
  // Check if advertising contain BleUart service
  if ( Bluefruit.Scanner.checkReportForService(report, clientUart) )
  {
    Serial.print("BLE UART service detected. Connecting ... ");

    // Connect to device with bleuart service in advertising
    Bluefruit.Central.connect(report);
  }else
  {      
    // For Softdevice v6: after received a report, scanner will be paused
    // We need to call Scanner resume() to continue scanning
    Bluefruit.Scanner.resume();
  }
}

/**
 * Callback invoked when an connection is established
 * @param conn_handle
 */
void connect_callback(uint16_t conn_handle)
{
  Serial.println("Connected");

  Serial.print("Dicovering Device Information ... ");
  if ( clientDis.discover(conn_handle) )
  {
    Serial.println("Found it");
    char buffer[32+1];
    
    // read and print out Manufacturer
    memset(buffer, 0, sizeof(buffer));
    if ( clientDis.getManufacturer(buffer, sizeof(buffer)) )
    {
      Serial.print("Manufacturer: ");
      Serial.println(buffer);
    }

    // read and print out Model Number
    memset(buffer, 0, sizeof(buffer));
    if ( clientDis.getModel(buffer, sizeof(buffer)) )
    {
      Serial.print("Model: ");
      Serial.println(buffer);
    }

    Serial.println();
  }else
  {
    Serial.println("Found NONE");
  }

  Serial.print("Dicovering Battery ... ");
  if ( clientBas.discover(conn_handle) )
  {
    Serial.println("Found it");
    Serial.print("Battery level: ");
    Serial.print(clientBas.read());
    Serial.println("%");
  }else
  {
    Serial.println("Found NONE");
  }

  Serial.print("Discovering BLE Uart Service ... ");
  if ( clientUart.discover(conn_handle) )
  {
    Serial.println("Found it");

    Serial.println("Enable TXD's notify");
    clientUart.enableTXD();

    Serial.println("Ready to receive from peripheral");
  }else
  {
    Serial.println("Found NONE");
    
    // disconnect since we couldn't find bleuart service
    Bluefruit.disconnect(conn_handle);
  }  
}

/**
 * Callback invoked when a connection is dropped
 * @param conn_handle
 * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
 */
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
  (void) conn_handle;
  (void) reason;
  
  Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
}

/**
 * Callback invoked when uart received data
 * @param uart_svc Reference object to the service where the data 
 * arrived. In this example it is clientUart
 */
void bleuart_rx_callback(BLEClientUart& uart_svc)
{
  Serial.print("[RX]: ");
  
  while ( uart_svc.available() )
  {
    Serial.print( (char) uart_svc.read() );
  }

  Serial.println();
}

void loop()
{
  if ( Bluefruit.Central.connected() )
  {
    // Not discovered yet
    if ( clientUart.discovered() )
    {
      // Discovered means in working state
      // Get Serial input and send to Peripheral
      if ( Serial.available() )
      {
        delay(2); // delay a bit for all characters to arrive
        
        char str[20+1] = { 0 };
        Serial.readBytes(str, 20);
        
        clientUart.print( str );
      }
    }
  }
}


User avatar
rob1999
 
Posts: 3
Joined: Thu Apr 07, 2022 6:25 pm

Re: NRF52840 Express Unable to Connect to Multiple Periphera

Post by rob1999 »

The peripheral devices I'm connecting to do not have UART services so I can't use the full example that you linked to.

My peripheral devices are gauges supplied by a different manufacturer that have their own service and characteristics. I know that the peripheral devices are working correctly since I can communicate with them using nRF Connect as well as a custom C# mobile app that I've written.

I have also just tried a modified version of the Sensor Tag example from here: https://github.com/adafruit/Adafruit_nR ... ptical.ino

I substituted the service and characteristic UUID's in the Sensor Tag example code for the correct values that my gauges use.
The Feather will connect to the gauge (the gauge Bluetooth connection indicator lights up), but it cannot find the specified services or characteristics.

It also stops scanning until after the first gauge is disconnected. I would like it to continue scanning while the first gauge is connected and connect any additional gauges that are found.

User avatar
austin944
 
Posts: 12
Joined: Sun Jan 17, 2021 8:45 pm

Re: NRF52840 Express Unable to Connect to Multiple Periphera

Post by austin944 »

central_scanning.jpg
central_scanning.jpg (76.32 KiB) Viewed 142 times
rob1999 wrote: It also stops scanning until after the first gauge is disconnected. I would like it to continue scanning while the first gauge is connected and connect any additional gauges that are found.
I thought that was the way the BLE standard worked. Once the Central device initiates a connection to a Peripheral device, it should first stop scanning. See the attached flowchart from the Bluetooth spec version 5.2.

User avatar
rob1999
 
Posts: 3
Joined: Thu Apr 07, 2022 6:25 pm

Re: NRF52840 Express Unable to Connect to Multiple Periphera

Post by rob1999 »

austin944 wrote:I thought that was the way the BLE standard worked. Once the Central device initiates a connection to a Peripheral device, it should first stop scanning. See the attached flowchart from the Bluetooth spec version 5.2.
Possibly, I'm not sure.
With our C# mobile app, we are able to continue scanning after the device(s) have been connected.
We have some older devices that need an actual connection, and some others that just send their measurements in the Manufacturer Specific Data of the advertising packet. When the older devices are connected, the app needs to continue scanning to receive the advertising data from the other devices.

For this Arduino device, I don't really need to keep listening for the advertising data, so I could probably just try scanning for a while and collect all of the devices in an array before connecting to them. It just seems cleaner to be able to connect to them as it finds them.

I still need figure out the issue I'm having of the Arduino code not being able to find the services after it does connect even though all of my other app are able to find them.

Locked
Please be positive and constructive with your questions and comments.

Return to “Wireless: WiFi and Bluetooth”