This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to extract BLE Central characteristic data sent from BLE peripheral

Other Parts Discussed in Thread: CC2540, CC2650STK

Have 2 SmartRF05EB with CC2540DK_EM
One is setup as peripheral and the other as central.
 
I have characteristic value of 16 bytes being sent from peripheral and I would like to get this
from the central setup.

I have setup the peripheral per example provided in the set of CC2540 APIs
I am using the central API code  provided in the set of CC2540 APIs


Below is the code for the Central.
On the Central LCD, it displays "Simple Svc Found" and so I think that it has found the Characteristic
SIMPLEPROFILE_CHAR6_UUID which is what is being sent by the peripheral.

But question is how do I extract the 16 bytes of data from the received Characteristic ?

Is there a Central BLE example code that shows how to extract the data?

I have looked at the example codes in processors.wiki.ti.com/.../CC254X_Embedded_Examples but I cannot
see how data is extracted. Please help.

Thank you,
Asha

===================================================================================================
At the central, in function simpleBLECentralStartDiscovery() -- no change
       (1)
            static void simpleBLECentralStartDiscovery( void )
            {
                  uint8 uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(SIMPLEPROFILE_SERV_UUID),
                                                   HI_UINT16(SIMPLEPROFILE_SERV_UUID) };
 
                  // Initialize cached handles
                  simpleBLESvcStartHdl = simpleBLESvcEndHdl = simpleBLECharHdl = 0;
                  simpleBLEDiscState = BLE_DISC_STATE_SVC;
 
                  // Discovery simple BLE service
                  GATT_DiscPrimaryServiceByUUID( simpleBLEConnHandle,
                                 uuid,
                                 ATT_BT_UUID_SIZE,
                                 simpleBLETaskId );
           }

  
      (2)
          static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )
          {
              attReadByTypeReq_t req;
              if ( simpleBLEDiscState == BLE_DISC_STATE_SVC )
              {
                 // Service found, store handles
                if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
                     pMsg->msg.findByTypeValueRsp.numInfo > 0 )
                {
                    simpleBLESvcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);
                    simpleBLESvcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);
                }
   
                // If procedure complete
                if ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP  &&
                       pMsg->hdr.status == bleProcedureComplete ) ||
                     ( pMsg->method == ATT_ERROR_RSP ) )
                {
                   if ( simpleBLESvcStartHdl != 0 )
                   {
                      // Discover characteristic
                      simpleBLEDiscState = BLE_DISC_STATE_CHAR;
       
                      req.startHandle = simpleBLESvcStartHdl;
                      req.endHandle = simpleBLESvcEndHdl;
                      req.type.len = ATT_BT_UUID_SIZE;
                      req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR6_UUID);
                      req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR6_UUID);

                      GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId );
                   }
                }
             }
             else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR )
             {
               // Characteristic found, store handle
               if ( pMsg->method == ATT_READ_BY_TYPE_RSP &&
               pMsg->msg.readByTypeRsp.numPairs > 0 )      
               {
                  simpleBLECharHdl = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[0],
                                      pMsg->msg.readByTypeRsp.pDataList[1]);
     
                 LCD_WRITE_STRING( "Simple Svc Found", HAL_LCD_LINE_1 );
                 simpleBLEProcedureInProgress = FALSE;
              }
            simpleBLEDiscState = BLE_DISC_STATE_IDLE;
  
  }   

  • Hello,

    Have you considered using HostTest with BTool? You could save the log from BTool.

    Best wishes
  • Hi,

    That's ok.

    I was able to  extract the 16 bytes of data from the received Characteristics after sometime.

    Thanks,

    Asha

  • Hey Asha,

    Were you able to send data from Peripheral to Central?
    if so can you guide me doing that please?
  • Hi Asha,
    i am trying to do the same with CC2650STK and #CC2650DK. and i am stuck at same point as you was couple of days before. could you guide me what is the next step? i actually reach at discState = BLE_DISC_STATE_SVC; instead of LCD_WRITE_STRING("Simple Svc Found", LCD_PAGE2); 
    Best Wishes
    Usman

  • Hi,

    i am working with CC2650STK and CC2650DK. i am using SensorTag on CC2650STK to send data. and SimpleBLECentral on CC2650DK to receive data. i am able to conect both devices. As both devices are communicating but i am unable to reach the discState == BLE_DISC_STATE_CHAR. i want to go at this state because i need the data in pDataList[0] and pDataList[1] in the function BLECommunication_processGATTDiscEvent, which according to me is the received data string of sensorTag. 1st am i right? 2nd i am unable to reach the discState = BLE_DISC_STATE_CHAR; because the

    if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
    pMsg->msg.findByTypeValueRsp.numInfo > 0)

    is not satisfied. because pMsg->method has value 1. and ATT_FIND_BY_TYPE_VALUE_RSP has value 7. so condition is not satisfied. i looked and findout pMsg->method=1 mean ATT_ERROR_RSP . and the value of pMsg->msg.findByTypeValueRsp.numInfo = 2822. so it satisfied the &&.

    i don't know why is it so as i am ammature in this field. please help. i shall be very thankful to you. i want to display the sensors value of hum, temp etc. on lcd.

    Best Regards

    Usman
  • Hi Pradeep,

    Yes I was able to send data from Peripheral to Central

    If you advertise with say 16 bytes in one of the characteristics you create, like SIMPLEPROFILE_CHAR9_UUID  in Peripheral then in the Central function,

    static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg ) you can see the data like in

    Char_data[] -- you can put a break point right after you populate it:

    Please note that simpleBLECharHdl is in the first 2 bytes in Char_data[] and that is why the size of it is 18.

    =====================================================================================

    static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )
    {
      attReadByTypeReq_t req;
     
     // uint8 status;
      uint8 i, Char_data[18];
     
      if ( simpleBLEDiscState == BLE_DISC_STATE_SVC )
      {
        // Service found, store handles
        if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
             pMsg->msg.findByTypeValueRsp.numInfo > 0 )
        {
          simpleBLESvcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);
          simpleBLESvcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);
        }
       
        // If procedure complete
        if ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP  &&
               pMsg->hdr.status == bleProcedureComplete ) ||
             ( pMsg->method == ATT_ERROR_RSP ) )
        {
          if ( simpleBLESvcStartHdl != 0 )
          {
            // Discover characteristic
            simpleBLEDiscState = BLE_DISC_STATE_CHAR;
           
            req.startHandle = simpleBLESvcStartHdl;
            req.endHandle = simpleBLESvcEndHdl;
            req.type.len = ATT_BT_UUID_SIZE;
            req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR9_UUID);
            req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR9_UUID);
            GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId );
          }
        }
      }
      else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR )
      {
        // Characteristic found, store handle
        if ( pMsg->method == ATT_READ_BY_TYPE_RSP &&
             pMsg->msg.readByTypeRsp.numPairs > 0 )
        {
          simpleBLECharHdl = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[0],
                                          pMsg->msg.readByTypeRsp.pDataList[1]);
         
          for(i=0; i<18; i++)
          {
              Char_data[i] = pMsg->msg.readByTypeRsp.pDataList[i];
          }
          LCD_WRITE_STRING( "Simple Svc Found", HAL_LCD_LINE_1 );
          simpleBLEProcedureInProgress = FALSE;
        }
        simpleBLEDiscState = BLE_DISC_STATE_IDLE;   
      }   
    }

    Thanks,

    Asha

  • Hi Usman,

    You need to advertise the characteristic after advertising the Service -- then only the Central will see this.
    Look at the Simple simpleBLEPeripheral.c, function SimpleBLEPeripheral_Init(), file where it does
    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR1, sizeof ( uint8 ), &charValue1 );

    So this will be advertised using SIMPLEPROFILE_CHAR1_UUID. Look simpleGATTprofile.c and peripheral.c
    This will give you more insight how both sides are setup.

    Thanks,
    Asha
  • Hey asha i tried using this method and when i tried to print the value on the lcd by using this code:
    "LCD_WRITE_STRING_VALUE("Char 1:", pMsg->msg.readByTypeRsp.pDataList[0], 10, LCD_PAGE4);"
    its showing
    Char1: 30
    i had not defind it anywhere like this.
    Can u guide where m going wrong.