10 Replies Latest reply on Jul 24, 2018 9:54 AM by jesc_1313431

    BLE Central Role Example

      Is there an example that shows a BLE Central role.

        • 1. Re: BLE Central Role Example

          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.

          • 2. Re: BLE Central Role Example

            Works great. 


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

            • 3. Re: BLE Central Role Example

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

              • 4. Re: BLE Central Role Example

                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?

                • 5. Re: BLE Central Role Example

                  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 */



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




                           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 */




                  /* Handle BLE Status LED */





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



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



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

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

                  peripheralFound = FALSE;





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




                  #ifdef ENABLE_LOW_POWER_MODE

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



                  /* Put the system in Low power mode */




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



                  /* 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()*/





                  • 6. Re: BLE Central Role Example

                    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.

                    • 7. Re: BLE Central Role Example

                      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. */



                      /* Put the system in Low power mode */

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

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



                      • 8. Re: BLE Central Role Example

                        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.

                        • 9. Re: BLE Central Role Example



                          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[i].data[list_of_devices[i].dataLen-4];

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

                          BeaconRSSI = list_of_devices[i].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?

                          • 10. Re: BLE Central Role Example

                            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[i].peerBdAddr = &address_store[i][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[i].peerBdAddr, scanReport->peerBdAddr, ADV_ADDR_LEN))


                            newDevice = FALSE;





                              //      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