Black Lives Matter - Action and Equality. ... Adafruit is open and shipping.
0

BLE data FROM central TO peripheral?
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

BLE data FROM central TO peripheral?

by Eromlignod on Tue Jul 28, 2020 8:51 pm

Guys:

I have a project that communicates between two Adafruit Feather Express nRF52840 boards via Bluetooth. I'm converting code that I had originally written for two Arduino Nano 33 BLE's (I switched to Adafruit because they have a provision for a 3.7V Lipo battery & charger). Both the Adafruits and the Arduinos run on a Nordic nRF52840.

I figured out how to get the UUID's set up for the service and my seven characteristics and I get the two boards to connect just fine. Six of the characteristics are sensor data posted by the peripheral and read by the central; the last characteristic is a simple on/off bit from the central to the peripheral to tell it to turn on the sensors.

I can send the sensor data to the central and read it, but I'm having a terrible time getting the on/off signal to transmit to the peripheral. With the Arduino, I figured out that it was necessary to read the on/off byte at the peripheral by using:

onoff = RADIO_onoff.value();

Where onoff is the variable that the data is read into and RADIO_onoff represents the characteristic. The key was to use ".value()" instead of "readValue()" on the peripheral end.

With the Adafruit code, the data is written at the central by

RADIO_onoff.write8(switch);

Where "switch" is the variable written into the characteristic. At the peripheral end I have tried

onoff = RADIO_onoff.read8();

But it doesn't work. The Adafruit example program only shows how to transfer data from peripheral to central. Does anyone know the correct syntax to get this value transferred? Thanks for any help you can provide.

Don

Eromlignod
 
Posts: 11
Joined: Thu Jun 25, 2020 8:00 pm

Re: BLE data FROM central TO peripheral?

by Eromlignod on Fri Jul 31, 2020 11:56 am

No one knows?

Eromlignod
 
Posts: 11
Joined: Thu Jun 25, 2020 8:00 pm

Re: BLE data FROM central TO peripheral?

by Eromlignod on Sat Aug 01, 2020 12:41 pm

OK, I was trying to be concise. Perhaps I need to post more detail.

The central is an Adafruit Clue nRF52840. Here is the pertinent CENTRAL code I use for the BLE:

Code: Select all | TOGGLE FULL SIZE
#include <bluefruit.h>

float a = 0;                 
float b = 0;
float c = 0;
float d = 0;
float e = 0;
float f = 0;
byte onoff = 0;

BLEClientService UService(0xcba174a9aed54c2f8ea998de50b2bb38);
BLEClientCharacteristic RADIO_a(0x4007f5d26d384249b4b2c48062eaf30a); 
BLEClientCharacteristic RADIO_b(0x6d813cfd2937495dbc1be91aa6742eca);
BLEClientCharacteristic RADIO_c(0xeb00def4f7e94bb4a1d148dd87098f13);
BLEClientCharacteristic RADIO_d(0x143641017d9149edb28d676e39e04cc1);
BLEClientCharacteristic RADIO_e(0xcb27777ba33f42ae841b00fa979077f5);
BLEClientCharacteristic RADIO_f(0xf4b9032407324873a04ebc8b970b567b);
BLEClientCharacteristic RADIO_onoff(0xbe14c89cc6154fc18f892188db954709);

void setup(){
  Bluefruit.begin(0, 1);                                       
  Bluefruit.setName("A central");
  UService.begin();                                           
  RADIO_a.begin();                                         
  RADIO_b.begin();
  RADIO_c.begin();
  RADIO_d.begin();
  RADIO_e.begin();
  RADIO_f.begin();
  RADIO_onoff.begin();

  Bluefruit.setConnLedInterval(250);                           
  Bluefruit.Central.setDisconnectCallback(disconnect_callback);
  Bluefruit.Central.setConnectCallback(connect_callback);
  Bluefruit.Scanner.setRxCallback(scan_callback);               
  Bluefruit.Scanner.restartOnDisconnect(true);                 
  Bluefruit.Scanner.setInterval(160, 80);                       
  Bluefruit.Scanner.filterUuid(UService.uuid);               
  Bluefruit.Scanner.useActiveScan(false);                     
  Bluefruit.Scanner.start(0); 
 
}

void loop() {
  if(Bluefruit.connected()){
    onoff = 1;
    RADIO_onoff.write8(onoff);                                                       
    if(onoff){                                                                           
      a = (float)RADIO_a.read32() / 1000;           
      b = (float)RADIO_b.read32() / 1000;
      c = (float)RADIO_c.read32() / 1000;
      d = (float)RADIO_d.read32() / 1000;
      e = (float)RADIO_e.read32() / 1000;
      f = (float)RADIO_f.read32() / 1000;
    }
  }
}

void disconnect_callback(uint16_t conn_handle, uint8_t reason){
  (void) conn_handle;
  (void) reason; 
}

void connect_callback(uint16_t conn_handle){
}

void scan_callback(ble_gap_evt_adv_report_t* report){
  Bluefruit.Central.connect(report);
}


This reads six numbers, via BLE, from the peripheral. It also attempts to send a "1" to the peripheral to turn on an LED.

The peripheral is an Adafruit Feather Express nRF52840. The PERIPHERAL code looks like this:

Code: Select all | TOGGLE FULL SIZE
#include <bluefruit.h>

BLEService UService = BLEService(0xcba174a9aed54c2f8ea998de50b2bb38);
BLECharacteristic RADIO_a = BLECharacteristic(0x4007f5d26d384249b4b2c48062eaf30a);
BLECharacteristic RADIO_b = BLECharacteristic(0x6d813cfd2937495dbc1be91aa6742eca);
BLECharacteristic RADIO_c = BLECharacteristic(0xeb00def4f7e94bb4a1d148dd87098f13);
BLECharacteristic RADIO_d = BLECharacteristic(0x143641017d9149edb28d676e39e04cc1);
BLECharacteristic RADIO_e = BLECharacteristic(0xcb27777ba33f42ae841b00fa979077f5);
BLECharacteristic RADIO_f = BLECharacteristic(0xf4b9032407324873a04ebc8b970b567b);
BLECharacteristic RADIO_onoff = BLECharacteristic(0xbe14c89cc6154fc18f892188db954709);
BLEDis bledis;   
BLEBas blebas;   

volatile float sensor[6] = {1,2,3,4,5,6};
byte onoff = 0;
uint8_t  bps = 0;

void setup(){
  pinMode(LED_RED, OUTPUT);

  Bluefruit.begin();                                             
  Bluefruit.setName("A peripheral");                             
  Bluefruit.Periph.setConnectCallback(connect_callback);           
  Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
  bledis.setManufacturer("DGD");                             
  bledis.setModel("Bluefruit Feather Express nRF52840");
  bledis.begin();
  blebas.begin();                                                 
  blebas.write(100);
 
  setupParameters();
  startAdvertising();
}

void loop(){
  if (Bluefruit.connected()){                                     
          onoff = RADIO_onoff.read8();                           
          if(onoff){
            if(!digitalRead(LED_RED))                               
              digitalWrite(LED_RED, HIGH);           
          }
          else               
            digitalWrite(LED_RED, LOW);                                       
          RADIO_a.write32((uint32_t)(1000 * sensor[0]));     
          RADIO_b.write32((uint32_t)(1000 * sensor[1]));                     
          RADIO_c.write32((uint32_t)(1000 * sensor[2]));                     
          RADIO_d.write32((uint32_t)(1000 * sensor[3]));                     
          RADIO_e.write32((uint32_t)(1000 * sensor[4]));                     
          RADIO_f.write32((uint32_t)(1000 * sensor[5]));
  }
}

void connect_callback(uint16_t conn_handle){ 
  BLEConnection* connection = Bluefruit.Connection(conn_handle);   
  char central_name[32] = { 0 };
  connection->getPeerName(central_name, sizeof(central_name));
}

void disconnect_callback(uint16_t conn_handle, uint8_t reason){
  (void) conn_handle;
  (void) reason;
}

void startAdvertising(void){ 
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);    // Advertising packet
  Bluefruit.Advertising.addTxPower(); 
  Bluefruit.Advertising.addService(UService);                   
  Bluefruit.Advertising.addName();                               
  Bluefruit.Advertising.restartOnDisconnect(true);               
  Bluefruit.Advertising.setInterval(32, 244);                     
  Bluefruit.Advertising.setFastTimeout(30);                       
  Bluefruit.Advertising.start(0);                                 
}

void setupParameters(void){
  UService.begin();

  RADIO_a.setProperties(CHR_PROPS_READ);
  RADIO_a.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  RADIO_a.setFixedLen(4);
  RADIO_a.begin();

  RADIO_b.setProperties(CHR_PROPS_READ);
  RADIO_b.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  RADIO_b.setFixedLen(4);
  RADIO_b.begin();

  RADIO_c.setProperties(CHR_PROPS_READ);
  RADIO_c.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  RADIO_c.setFixedLen(4);
  RADIO_c.begin();

  RADIO_d.setProperties(CHR_PROPS_READ);
  RADIO_d.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  RADIO_d.setFixedLen(4);
  RADIO_d.begin();

  RADIO_e.setProperties(CHR_PROPS_READ);
  RADIO_e.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  RADIO_e.setFixedLen(4);
  RADIO_e.begin();

  RADIO_f.setProperties(CHR_PROPS_READ);
  RADIO_f.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  RADIO_f.setFixedLen(4);
  RADIO_f.begin();

  RADIO_onoff.setProperties(CHR_PROPS_WRITE);
  RADIO_onoff.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  RADIO_onoff.setFixedLen(1);
  RADIO_onoff.begin();
  RADIO_onoff.write8(1);                                           
}




This takes six values in the array sensor[6] and sends them to the central, via BLE. I also attempts to read the value of "onoff" and control an LED with it.

The BLE connects and I get all the sensor data just fine. But I can't get the onoff data to send back the other way. I also have checked the value of onoff, which never becomes "1", so I know it doesn't have anything to do with the LED. I have a feeling it's the nomenclature I'm using, but I can't seem to find any information or examples to set me straight.

Does this help?

Don

Eromlignod
 
Posts: 11
Joined: Thu Jun 25, 2020 8:00 pm

Re: BLE data FROM central TO peripheral?

by jpconstantineau on Mon Aug 03, 2020 11:26 pm

For my split keyboard firmware, I have used BLECharacteristic and BLEClientCharacteristic depending if the code is on the central or peripheral. Depending on the direction of the communication (C to P or P to C), I use the write or notify methods. The receiving code is in callbacks.

Have a look though this code (https://github.com/jpconstantineau/Blue ... etooth.cpp) it will provide you with example for both sides. I don't have a simplified example but hopefully that will give you a path to look into.

jpconstantineau
 
Posts: 52
Joined: Tue Nov 13, 2018 12:30 pm

Re: BLE data FROM central TO peripheral?

by Eromlignod on Tue Aug 04, 2020 11:01 am

Actually, I finally figured out, with help from a poster in the Arduino forum, that I needed to change the onoff characteristic to both "read" and "write" and I needed to change the "SECMODE_NO_ACCESS" to "SECMODE_OPEN".

But thanks for your help anyway.

Don

Eromlignod
 
Posts: 11
Joined: Thu Jun 25, 2020 8:00 pm

Please be positive and constructive with your questions and comments.