BLE Central Role Example

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Is there an example that shows a BLE Central role.

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
rola_264706
Level 8
Level 8
50 likes received 25 likes received 10 likes received

I am sending you 100 projects in 100 days ble example #06. I am also sending you a pdf file that explains how it works  Please enjoy this example.

View solution in original post

0 Likes
10 Replies
lock attach
Attachments are accessible only for community members.
rola_264706
Level 8
Level 8
50 likes received 25 likes received 10 likes received

I am sending you 100 projects in 100 days ble example #06. I am also sending you a pdf file that explains how it works  Please enjoy this example.

0 Likes
Anonymous
Not applicable

Works great. 

   

The documentation states that a fixed BD address is used. Where does this get set? 

0 Likes
Anonymous
Not applicable

Never mind. I found it in the BLEclient.c file.

0 Likes
Anonymous
Not applicable

I need to synchronize multiple peripheral devices to within 100 msec of  an Immediate Alert Service transaction from a central device. It would appear that I can do this with a broadcast message. Do you have any broadcast examples?

0 Likes
Anonymous
Not applicable

I am using the same example and trying to modify slightly.  I added a UART and get no output at all.  I have tried moving the printf command around to different points in the code in case Interrupts were interfering but nothing comes out. Is there a compatability issue?  I tried SCB and older version UART code.  Do I need to start the UART after every deep sleep cycle?  I tried putting Uart_start() inside the main "for" loop just in case. Will that cause other issues. 

int main()

{

    /* Initialize the system */

     UART_1_Start();

InitializeSystem();

printf("initializing \n\r");  <------- a simple test here... no output from this

    for(;;)

    {

       

         UART_1_Start();  <------ Tried restarting every loop

        /*Process Event callback to handle BLE events. The events generated and

* used for this application are inside the 'ApplicationEventHandler' routine */

    

CyBle_ProcessEvents();

/* Handle BLE Status LED */

HandleLEDs(ble_state);

if(peripheralFound)

{

/* If the desired peripheral is found, then connect to that peripheral */

CyBle_GapcConnectDevice(&connectPeriphDevice);

/* Call CyBle_ProcessEvents() once to process the Connect request sent above. */

CyBle_ProcessEvents();

/* Reset flag to prevent resending the Connect command */

            printf("found peripheral \n\r");   <----- no output from this either

peripheralFound = FALSE;

}

if(deviceConnected)

{

/* Check if the button was pressed and update the Alert Level Accordingly.*/

CheckButtonStatus();

}

#ifdef ENABLE_LOW_POWER_MODE

/* Call CyBle_ProcessEvents to process all events before going to sleep. */

CyBle_ProcessEvents();

/* Put the system in Low power mode */

HandleLowPowerMode();

#endif

/* If rescanning flag is TRUE, the restart the scan */

if(restartScanning)

{

/* Reset flag to prevent calling multiple Start Scan commands */

restartScanning = FALSE;

/* Start Fast BLE Scanning. This API will only take effect after calling

* CyBle_ProcessEvents()*/

CyBle_GapcStartScan(CYBLE_SCANNING_FAST);

}

}

}

0 Likes
Anonymous
Not applicable

I believe there are two functions for the UART:

SCB_Sleep() to put the unit into a deep-sleep mode for entering low power, and SCB_Wakeup() to wake up the unit from deep sleep mode.

If you forget to call one or the other, then you would get incorrect behavior and have trouble like you are seeing.

You only need to call the wakeup after calling the sleep, and you only need to call the wakeup if you are going to interact/use the UART while the CPU is active again.

0 Likes
Anonymous
Not applicable

Guys,  Thanks for all of the help so far.  This was supposed to be a simple demo of a product prototype, but due to my lack of programming prowess I am running more than a month late, but now almost done.  I am currently measuring current draw... and still using a lightly modified PSoC_4_BLE_Central_IAS example program... I found that the device is not going into deep sleep mode, and maybe not even sleep mode for that matter with the original example program . The current draw goes down to 4mA unless I add a CySysPmDeepSleep(); command.  Then the system goes down to 0.17mA which looks like deep sleep with something else also(haven't disabled debug port yet).  But, my question is this... Why dosen't the HandleLowPowerMode(); function do this? Is it not working in this example code? Has someone made a fix for it and can share that fix? 

#ifdef ENABLE_LOW_POWER_MODE

/* Call CyBle_ProcessEvents to process all events before going to sleep. */

CyBle_ProcessEvents();

/* Put the system in Low power mode */

            SPIM_1_Sleep();   /* jeffs added does not go into sleep unless this added??*/

          Added by me ----> CySysPmDeepSleep();

            HandleLowPowerMode();

#endif

0 Likes
Anonymous
Not applicable

It looks like the HandleLowPowerMode() is doing what it should after all.  Using debugger I found that I am landing in the CySysPmDeepSleep(void) routine as it should(without my added line of code).  Its just that the current is way too high.  I know there are lots of answers on what and how to reduce the consumption, so I will look into those.  Sorry for the false alarm.

0 Likes
Anonymous
Not applicable

PSoC_4_BLE_Central_IAS

Hello again.  I am using the BLE central to scan for devices and report the one with strongest RSSI.  So first I scan for all devices and then sort by highest RSSI.  I have three beacons. When I let the code do the scan, I only see two of the three captured no matter what. It looks like to me that third major/minor value always get over written by one of the other devices.  RSSI looks reasonable for the third device but always has the Major/Minor value for one of the other two.  So the end result is that I get three different RSSI values but only two different Major/Minor combinations.  I have been through my code for a few days and I am at a loss to figure out how this can happen. The scan results are stored by the example code and I am having trouble to find that part of the code

  I am simply pulling the data  from storage after the example code does it's thing, like this.  The number of devices detected is used as the counter i. 

Major = list_of_devices.data[list_of_devices.dataLen-4];

  Minor = list_of_devices.data[list_of_devices.dataLen-2];

BeaconRSSI = list_of_devices.rssi;

It never fails, I only get two different Major and Minor combinations in the three responses.

So, to make the question simple... Does anyone know if this example has a bug that might cause this?

0 Likes
Anonymous
Not applicable

Never mind... I was able to work around this issue.  To wrap this up I guess I should explain what I found. In this example the RSSI value seems to be updated at a later point than the other data.  So RSSI gets associated with one of the other devices if you read RSSI and look at the current data to find Major and Minor values.  I don't know if this is bug but something to be aware of. So if you want correct  RSSI value you must pull it from .RSSI pointer at the point after returning from the "HandleScanDevices"  function.  The other data can be pulled within that function (or later) and looks correct. Not sure if I somehow I affected this result by adding a redundant line of code:

list_of_devices[addedDevices].data = scanReport->data; (which was already in there)  into the "HandleScanDevices" function in error.  For the other problem of not seeing one of the three beacons every time(and was not always the same one), I had added the requirement of the report type being "0".  After removing that then all three beacons show up ot each scan.  I don't yet understand why that requirement caused the "newDevice" test to fail on different beacons at different times, but it now works.  Good enough for a POC

/*******************************************************************************

* Function Name: HandleScanDevices

********************************************************************************

* Summary:

*        This function checks for new devices that have been scanned and ads them

* to its internal list. Also, if one of the scanned peripherals is of CySmart

* USB Dongle, then it sets flag to allow connection with it.

*

* Parameters:

*  scanReport: parameter of type CYBLE_GAPC_ADV_REPORT_T* returned by BLE

* event CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT.

*

* Return:

*  void

*

*******************************************************************************/

void HandleScanDevices(CYBLE_GAPC_ADV_REPORT_T* scanReport) /* jeffs moved to main.h */

{

uint16 i;

uint8 newDevice = TRUE;

if((addedDevices < CYBLE_MAX_ADV_DEVICES))

{

for(i = 0; i < addedDevices; i++)

{

/* Initialize the peerBdAddr element of our list.*/

list_of_devices.peerBdAddr = &address_store[0];

/* In this for loop, compare the new device address with the existing addresses in the list to

determine if the address is new or not. If the address exists in the list, then the device

is not new.*/

if(FALSE == memcmp(list_of_devices.peerBdAddr, scanReport->peerBdAddr, ADV_ADDR_LEN))

{

newDevice = FALSE;

break;

}

}

  //      if(newDevice)

if(newDevice && !scanReport->eventType)    /* jeff added scan report event type must be 0 */    <--------------------------this addition seemed to cause random screening of one of the three beacons.

{

           

/* If the device address is new, then add the device to our existing list and compare the address

with our expected address to see if the desired peripheral is advertising or not.*/

list_of_devices[addedDevices].peerBdAddr = &address_store[addedDevices][0];

           

SW_Tx_UART_PutString("new device found\n\r");  /* jeffs added  */

           

/* Store the data*/

list_of_devices[addedDevices].dataLen = scanReport->dataLen;

list_of_devices[addedDevices].data = scanReport->data;

           

            Found_Beacons[addedDevices][0] = list_of_devices[addedDevices].data[list_of_devices[addedDevices].dataLen-4];  /*jeffs added for test */

            Found_Beacons[addedDevices][1] = list_of_devices[addedDevices].data[list_of_devices[addedDevices].dataLen-2]; /*jeffs added for test */

            Found_Beacons[addedDevices][2] = list_of_devices[addedDevices].data[list_of_devices[addedDevices].dataLen-0];   /*jeffs added for test */    <------------------I tried re-writing this in several ways and did not work to get correct RSSI. The above lines work fine for Major and Minor values

           

           

           

list_of_devices[addedDevices].eventType = scanReport->eventType;

/* Record the address type, Public or Random, of the advertising peripheral.*/

list_of_devices[addedDevices].peerAddrType = scanReport->peerAddrType;

/* Save the BD addresses */

list_of_devices[addedDevices].peerBdAddr[0] = scanReport->peerBdAddr[0];

list_of_devices[addedDevices].peerBdAddr[1] = scanReport->peerBdAddr[1];

list_of_devices[addedDevices].peerBdAddr[2] = scanReport->peerBdAddr[2];

list_of_devices[addedDevices].peerBdAddr[3] = scanReport->peerBdAddr[3];

list_of_devices[addedDevices].peerBdAddr[4] = scanReport->peerBdAddr[4];

list_of_devices[addedDevices].peerBdAddr[5] = scanReport->peerBdAddr[5];

            /* jeffs added storing data

            */

           

            list_of_devices[addedDevices].data = scanReport->data;        <----------------------------New, Redundant

             

           

      list_of_devices[addedDevices].rssi = scanReport->rssi;               <----------------------------New

0 Likes