Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Communication of One Central Device and More than One Peripheral Device #50

Closed
vyohai opened this issue Jan 12, 2020 · 13 comments
Closed
Labels
status: waiting for information More information must be provided before work can proceed

Comments

@vyohai
Copy link

vyohai commented Jan 12, 2020

Does the library support connection and communication between one central device and more than one peripheral device?
And how could it be implemented?

@vyohai vyohai changed the title Communication of One Central Devicel and One Peripheral Devices Communication of One Central Devicel and More then One Peripheral Devices Jan 12, 2020
@vyohai vyohai changed the title Communication of One Central Devicel and More then One Peripheral Devices Communication of One Central Device and More then One Peripheral Devices Jan 12, 2020
@vyohai vyohai changed the title Communication of One Central Device and More then One Peripheral Devices Communication of One Central Device and More than One Peripheral Devices Jan 12, 2020
@vyohai vyohai changed the title Communication of One Central Device and More than One Peripheral Devices Communication of One Central Device and More than One Peripheral Device Jan 12, 2020
@polldo
Copy link
Contributor

polldo commented Aug 11, 2020

Hi @vyohai ,
yes, it is possible.
Each central device can be connected to more peripherals and each peripheral can be connected to more centrals.
However, at the moment the library doesn't expose the functions to retrieve the connected devices, so the handling of multiple devices must be done at application level.
To deal with this I've implemented some possible functions that allow to loop through all the connected devices. You can see it here #105 , let me know what you think could be added or improved.
Here are two examples of how to use these additional functions to manage multiple connected devices.

--- Peripheral device handling more centrals:

#include <ArduinoBLE.h>

BLEService batteryService("180F");
BLEUnsignedCharCharacteristic batteryLevelChar("2A19", BLERead | BLEWrite); 

void setup() {
  Serial.begin(115200);    
  pinMode(LED_BUILTIN, OUTPUT); 
  // Start BLE
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }
  BLE.debug(Serial);

  // Configure peripheral
  BLE.setLocalName("peripheral");
  BLE.setAdvertisedService(batteryService); 
  batteryService.addCharacteristic(batteryLevelChar); 
  BLE.addService(batteryService);
  BLE.advertise();

  Serial.println("peripheral configured - central connected: 0");
}

void loop() {
  BLE.poll();
  // Led on if some central is connected
  if (BLE.centralCount() > 0) {
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
  }

  // Check number of connected devices and enable advertising
  static auto timeRef = millis();
  if (millis() - timeRef >= 5000) {
    timeRef = millis();
    auto count = BLE.centralCount();
    Serial.print("Central count: ");
    Serial.println(count);
    if (count < 3) {
      BLE.advertise();
    }
  }
}

--- Central device handling more peripherals:

#include <ArduinoBLE.h>

void setup() {
  Serial.begin(115200);
  BLE.begin();
  BLE.scanForName("peripheral");
}

void connectionLoop() 
{
  // If not already connected to 2 peripherals, try to connect to a new found peripheral.
  if (BLE.peripheralCount() < 2) {

    BLEDevice peripheral = BLE.available();
    if (peripheral) {
      BLE.stopScan();

      if (!peripheral.connect()) {
        Serial.println("Failed to connect!");
        return;
      }

      if (!peripheral.discoverAttributes()) {
        Serial.println("Attribute discovery failed!");
        peripheral.disconnect();
        return;
      }
    }
  }
}

auto timeRef = millis();
void loop() {
  connectionLoop();

  if (millis() - timeRef >= 5000) {
    timeRef = millis();

    int periphCount = BLE.peripheralCount();
    Serial.print(" Peripheral connected: ");
    Serial.println(periphCount);

    if (periphCount < 2) {
      BLE.scanForName("peripheral");
    }

    // Loop through all connected peripherals
    for (int periphIdx = 0; periphIdx < periphCount; periphIdx++) {
      BLEDevice peripheral = BLE.peripheral(periphIdx);
      if (peripheral) {
        BLECharacteristic batteryLevelChar = peripheral.characteristic("2A19");

        if (!batteryLevelChar) {
          Serial.println("Peripheral does not have battery level characteristic!");
          peripheral.disconnect();
        } else {
          Serial.print("Peripheral connected, value: ");
          batteryLevelChar.read();
          Serial.println(*batteryLevelChar.value());
        }
      }
    }
  }
}

@polldo polldo added the status: waiting for information More information must be provided before work can proceed label Aug 11, 2020
@vyohai
Copy link
Author

vyohai commented Aug 18, 2020

Hi Polldo
thank you for all of your work
the example code doesn't work.
the error is :
'class BLELocalDevice' has no member named 'peripheralCount'
and in general when I try to scan for 2 peripherals and then connect to them one by one the 2nd one can't connect.
could that work?
am I doing something wrong?

@polldo
Copy link
Contributor

polldo commented Aug 18, 2020

@vyohai to compile the example you should checkout the multi-connection branch: https://github.com/arduino-libraries/ArduinoBLE/tree/multi-connection
Also, are you using a nano 33 ble? In that case there is an open issue that addresses the problem of connecting a central to many peripherals #108

@vyohai vyohai closed this as completed Aug 21, 2020
@vyohai
Copy link
Author

vyohai commented Aug 21, 2020

thank you it seems like it's working

@sprasadkrish
Copy link

Hi Polldo
thank you for all of your work
the example code doesn't work.
the error is :
'class BLELocalDevice' has no member named 'peripheralCount'
and in general when I try to scan for 2 peripherals and then connect to them one by one the 2nd one can't connect.
could that work?
am I doing something wrong?

thank you it seems like it's working

Hi @vyohai
how you solved this issue , i am also facing same kind of issue .

@polldo
Copy link
Contributor

polldo commented Sep 8, 2020

Hi @sprasadkrish ,
can you describe the issue you are facing?
Have you tried this #50 (comment) ?
Also, if you are using a nano33ble have a look at this #108
Thanks

@sprasadkrish
Copy link

sprasadkrish commented Sep 8, 2020

Hi @sprasadkrish ,
can you describe the issue you are facing?
Have you tried this #50 (comment) ?
Also, if you are using a nano33ble have a look at this #108
Thanks

Hi @vyohai
Thank you , my issue : MKR1010 BLE - Timeout issue #109
i tried above code , but only one device connecting .

@vyohai
Copy link
Author

vyohai commented Sep 8, 2020

this is part of my code that runs on the master, hope you will find it halpfull

{
     connecting("per1", 0);
     connecting("per2", 1);
     BLE.stopScan();
}`
`void connecting(String namee, int num)
{
  //check if peripheral1 connected
  BLEDevice p0 = BLE.peripheral(num);
  //loop until peripheral1 is connected
  BLE.scanForName(namee);
  BLEDevice a0 = BLE.available();
  while (!a0.connected())
  {
    if (Debug)
      Serial.println("scaning...");
    while (!a0)
    {
      a0 = BLE.available();
    }
    if (a0.connect())
    {
      if (Debug)
      {
        Serial.print("conected");
        Serial.println(num + 1);
      }
    }
    else
    {
      if (Debug)
      {
        Serial.print("failed to connect");
        Serial.println(num + 1);
      }
    }
  }
}

and than when you want to use it

int periphCount = BLE.peripheralCount();

BLEDevice p0 = BLE.peripheral(0);

initChar( p0, "0101", "0102","0103", valC0, tssC0, tsmC0);

BLEDevice p1 = BLE.peripheral(1);

BLECharacteristic valC1 , tsC1;

initChar( p0, "0101", "0102","0103", valC0, tssC0, tsmC0);

void initChar(BLEDevice &p0, const char* Char1name, const char* Char2name, const char* Char3name, BLECharacteristic &valC0, BLECharacteristic &tsC0, BLECharacteristic &tmC0)
{
p0.discoverAttributes();
valC0 = p0.characteristic(Char1name);
tsC0 = p0.characteristic(Char2name);
tmC0 = p0.characteristic(Char3name);
}

@sprasadkrish
Copy link

sprasadkrish commented Sep 8, 2020

this is part of my code that runs on the master, hope you will find it halpfull

Hi @vyohai ,
Thanks a lot , i will try this and update you.

@sprasadkrish
Copy link

Hi @vyohai
i am getting this error 'Debug' was not declared in this scope ,
if i disable Debug , i am unable to connect any peripherals .

@vyohai
Copy link
Author

vyohai commented Sep 9, 2020

I will upload the whole master code:

#include <ArduinoBLE.h>
#include <String>
//config
//0-timing 1 slave 1 master communication
//1-1 slave 1 master send to matlab
//2-2 slaves 1 master send to matlab
//3-2 slaves 1 master send to matlab 2 way communication
bool Debug = HIGH;
byte numSlaves = 3;
int WHAT=0;
//functions
void connecting(String, int);
void initChar(BLEDevice & , const char* , const char*, const char* , BLECharacteristic &, BLECharacteristic &, BLECharacteristic &);
void sendData(BLECharacteristic, BLECharacteristic,bool,int,int);
void sendMasterData(bool Debug);
uint16_t sync(BLECharacteristic ,BLECharacteristic ,bool ,int );
void setup() {
  //setup serial
  Serial.begin(115200);
  //  setup ble
  BLE.begin();
  //BLE.debug(Serial);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
  int periphCount = BLE.peripheralCount();
  BLEDevice p0 = BLE.peripheral(0);
  BLECharacteristic valC0 , tssC0 , tsmC0;//s means slave m means master
  switch (numSlaves) {
    case 0:
      {
        if (periphCount < 1)
        {
          connecting("per1", 0);
          BLE.stopScan();
        }
        //define charachtiristics
        initChar( p0, "0101", "0102","0103", valC0, tssC0, tsmC0);
        //while the slaves connected send data
        while (p0.connected() )
        {
          uint32_t t0 = millis();
          uint16_t ts, a;
          valC0.readValue(a);
          tssC0.readValue(ts);
          Serial.print( "dt is ");
          Serial.println(millis() - t0);
          digitalWrite(LED_BUILTIN, HIGH);
        }
        break;
      }
    case 1:
      {
        if (periphCount < 1)
        {
          connecting("per1", 0);
          BLE.stopScan();
        }
        //define charachtiristics
       initChar( p0, "0101", "0102","0103", valC0, tssC0, tsmC0);
        //while the slaves connected send data
        while (p0.connected() )
        {
          uint32_t t0 = millis();
          sendData(tssC0, valC0, Debug, 0,numSlaves);
          Serial.print( "dt is ");
          Serial.println(millis() - t0);
          digitalWrite(LED_BUILTIN, HIGH);
        }
        break;
      }
    case 2:
      {
        if (periphCount < 2)
        {
          connecting("per1", 0);
          connecting("per2", 1);
          BLE.stopScan();
        }
        //define charachtiristics
        initChar( p0, "0101", "0102","0103", valC0, tssC0, tsmC0);
        BLEDevice p1 = BLE.peripheral(1);
        BLECharacteristic valC1 , tsC1;
        initChar( p0, "0101", "0102","0103", valC0, tssC0, tsmC0);
        //while the slaves connected send data
        while (p0.connected() && p1.connected())
        {
          uint32_t t0 = millis();
          sendData(tssC0, valC0, Debug,numSlaves, 0);
          sendData(tsC1, valC1, Debug,numSlaves, 1);
//          Serial.println(BLE.peripheralCount());
//          Serial.print( "dt is ");
//          Serial.println(millis() - t0);
          digitalWrite(LED_BUILTIN, HIGH);
        }
        break;
      }
    case 3:
      {
        if (periphCount < 2)
        {
          connecting("per1", 0);
          connecting("per2", 1);
          BLE.stopScan();
        }
        //define charachtiristics
        initChar( p0, "0101", "0102","0103", valC0, tssC0, tsmC0);
        BLEDevice p1 = BLE.peripheral(1);
        BLECharacteristic valC1 , tssC1,tsmC1;
        //delay(5000);
        initChar( p1, "1101", "1102","1103", valC1, tssC1, tsmC1);
        //while the slaves connected send data
        while (p0.connected() && p1.connected())
        {
          uint32_t t0 = millis();
          //exchanging time stamps with slave1
          uint32_t dt0=sync(tssC0,tsmC0,Debug,0);
          uint32_t dt1=sync(tssC1,tsmC1,Debug,1);
          //sample data and time of saw tooth and send it to matlab
          sendMasterData(Debug);
          sendData(tssC0, valC0, Debug,numSlaves, 0);         
          sendData(tssC1, valC1, Debug,numSlaves, 1);
          digitalWrite(LED_BUILTIN, HIGH);
        }
        break;
      }
  }
  //connecting to the slaves
  digitalWrite(LED_BUILTIN, LOW);
}
void connecting(String namee, int num)
{
  //check if peripheral1 connected
  BLEDevice p0 = BLE.peripheral(num);
  //loop until peripheral1 is connected
  BLE.scanForName(namee);
  BLEDevice a0 = BLE.available();
  while (!a0.connected())
  {
    if (Debug)
      Serial.println("scaning...");
    while (!a0)
    {
      a0 = BLE.available();
    }
    if (a0.connect())
    {
      if (Debug)
      {
        Serial.print("conected");
        Serial.println(num + 1);
      }
    }
    else
    {
      if (Debug)
      {
        Serial.print("failed to connect");
        Serial.println(num + 1);
      }
    }
  }
}
void initChar(BLEDevice &p0, const char* Char1name, const char* Char2name, const char* Char3name, BLECharacteristic &valC0, BLECharacteristic &tsC0, BLECharacteristic &tmC0)
{
  p0.discoverAttributes();
  valC0 = p0.characteristic(Char1name);
  tsC0 = p0.characteristic(Char2name);
  tmC0 = p0.characteristic(Char3name);
}
void sendData(BLECharacteristic tsC, BLECharacteristic valC, bool Debug, int numSlaves ,int slaveNum)
{
  uint32_t tss,tse, a ,ts;
  switch(numSlaves ){
    case 0:
    {     
    }
    case 1:
    {
      tss=0;
      valC.readValue(a);
      tsC.readValue(ts);
      tse=ts;
      break;
    }
    case 2:
    {
      tss=millis();
      valC.readValue(a);
      //tsC.readValue(ts);
      tse=millis();
      break;
    }
    case 3:
    {
      tss=0;
      valC.readValue(a);
      //tsC.readValue(ts);
      tse=ts;
      tse=millis();
      break;
    }
  }  
  if (Debug)
  {
    Serial.print ("hello from sendData ");
    Serial.println(slaveNum);
    Serial.print("a is ");
    Serial.println(a);
    Serial.print("dts is ");
    Serial.println((tse-tss));
  }
  else
  {
    Serial.write(a);
    Serial.write(a >> 8);
    Serial.write(a >> 16);
    Serial.write(a >> 24);
    Serial.write(tse-tss);
    Serial.write((tse-tss) >> 8);
    Serial.write((tse-tss) >> 16);
    Serial.write((tse-tss) >> 24);
  }
}
void sendMasterData(bool Debug)
{
  uint16_t val;
   switch(WHAT)
      {
        case 0:
        {
          val=analogRead(A0);
        }
        case 1:
        {
          val=digitalRead(A0);
        }
      }
  uint32_t ts=millis();
  if (Debug)
  {
     Serial.println("hello from send2master");
    Serial.print("a is ");
    Serial.println(val);
    Serial.print("ts is ");
    Serial.println(ts);
    Serial.println();
  }
  else
  {
    Serial.write(val);
    Serial.write(val >> 8);
    Serial.write(val >> 16);
    Serial.write(val >> 24);
    Serial.write(ts);
    Serial.write((ts) >> 8);
    Serial.write(ts >> 16);
    Serial.write(ts >> 24);
  }
  
}
uint16_t sync(BLECharacteristic tssC0,BLECharacteristic tsmC0,bool Debug,int slave)
{
  //this function send tm1 in char tsmC0 and read ts2 in char tssC0 and than measure tm2
  //and than print all of them
  uint32_t ts2 ,tm2 ,tm1,dt;
  //send to slave
  tm1=millis();
  tsmC0.writeValue(tm1); 
  //read from slave
  tssC0.readValue(ts2);
  tm2=millis();
  dt=tm1/2-ts2+tm2/2;
  if (Debug)
  {
    Serial.print("hello from sync");
    Serial.println(slave);
    Serial.print("tm1 is ");
    Serial.println(tm1);
    Serial.print("tm2 is ");
    Serial.println(tm2);
    Serial.print("ts2 is ");
    Serial.println(ts2);
    Serial.print("bye from sync");
    Serial.println(slave);
  }
  else
  {
    Serial.write(dt);
    Serial.write(dt >> 8);
    Serial.write(dt >> 16);
    Serial.write(dt >> 24); 
  }
}

@sprasadkrish
Copy link

Hi @vyohai
Thank you , by using this code , i will do changes in my code.

@Prashant123-lab
Copy link

Prashant123-lab commented Jun 14, 2021

I will upload the whole master code:

Hey @vyohai
How did you resolve this issue 'class BLELocalDevice' has no member named 'peripheralCount'?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting for information More information must be provided before work can proceed
Projects
None yet
Development

No branches or pull requests

4 participants