9 Replies Latest reply on Sep 14, 2017 9:24 AM by e.pratt_1639216

    CyBle_GetRssi() returned value doesn't make sense

    user_74346845

      Hi,

         

      I've got a PRoC 4 EZ-BLE working as a peripheral server in a custom profile mode. I have a function that reads the CyBle_GetRssi() value and stores it in a custom service in the GATT DB. The client (phone or CySmart) reads this value to see what the received RSSI was on the peripheral. I can't seem to make sense of the value that gets stored, it seems out of bounds for the API. The API says it gives a range from -85-5 dBm, but the value I am reading on CySmart is often times around 2C, which is equivalent to 44dBm. Also, the value will sometimes jump to some value not even close to what it was before, an erroneous reading. 

         

      Please help me to understand what the CyBle_GetRssi() function is actually returning, or possibly my code is not storing it correctly. 

         

      Also, I am running PSoC Creator 3.2.0.6175. I will be upgrading to 3.3 today.

         

      Here's my code:

         

      In my main function, every loop (after wakeup from sleep), I call this function

         

      void UpdateRSSIValue()

         

      {

         

        /* Read the last known RSSI Value */

         

        /* I dont understand the value completely. Also, it is an int, but the handle.value.val

         

         * below is a uint, how does that affect the value?

         

         */

         

        static int8 rssiValue = 0;

         

        rssiValue = CyBle_GetRssi();

         

       

         

        /* Save the RSSI Value to the GATT db */

         

        CYBLE_GATT_ERR_CODE_T gattResult;

         

        CYBLE_GATT_HANDLE_VALUE_PAIR_T rssiHandle;

         

       

         

        rssiHandle.attrHandle = RSSI_CHAR_HANDLE;

         

        rssiHandle.value.val = &rssiValue;

         

        rssiHandle.value.len = 1;

         

       

         

        gattResult = CyBle_GattsWriteAttributeValue(&rssiHandle, FALSE, &cyBle_connHandle, FALSE);

         

       

         

        /* Check if the db was successfully updated */

         

        if(gattResult != CYBLE_GATT_ERR_NONE)

         

        {

         

          Green_LED_SetDriveMode(Green_LED_DM_STRONG);    //Constant on LED indicates a failure

         

          CYASSERT(0);

         

        }

         

      }

         

      Here's my main loop for completeness:

         

      int main()
      {
          /*Initialize System */
          InitializeSystem();
          
          CYBLE_LP_MODE_T lpMode;
          CYBLE_BLESS_STATE_T blessState;
          
          uint8 connIntervalCount = 0;

         

          CyGlobalIntEnable;
          
          for(;;)
          {
              /* Set the lowest possible power mode. First check the state of the BLE. If it's not
               * initializing, try to set the lowest power mode based on what's allowable by the
               * current bless state. If the BLE is in deep sleep, the Bless is in deep sleep or
               * ECO_ON state, AND the timers are all off (Alert levels are off and LLS timer
               * is not running), then put the CPU into deep sleep. Otherwise go into sleep.
               */
              if(CyBle_GetState() != CYBLE_STATE_INITIALIZING)
              {
                  /* Enter DeepSleep mode between connection intervals */
                  lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP);
                  blessState = CyBle_GetBleSsState();

         

                  if(lpMode == CYBLE_BLESS_DEEPSLEEP) 
                  {   /* CPU system is capable of entering deep sleep */
                      if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP)
                      {
                          /* If the timers are not active, go into deep sleep */
                          if(CheckTimerStates() == TIMERS_OFF) 
                          {
                              CySysPmDeepSleep();
                          }
                          /* Otherwise go into sleep to keep timers active */
                          else 
                          {
                              CySysPmSleep();
                          }
                      }
                  }
                  else
                  {
                      if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE)
                      {
                          CySysPmSleep();
                      }
                  }
              }
              
              /* Try processing events here. The downside is everything will be 1 interval 
               * behind, but hopefully i can improve rssi data */
              CyBle_ProcessEvents();
              
              /* Once the system wakes up from the BLE timer,
               * process the routine functions as well as the BLE Events */
              if(CyBle_GetState() == CYBLE_STATE_CONNECTED)
              {
                  /* Update the last known RSSI Value in the GATT db */
                  UpdateRSSIValue();
                  
                  /* Check the status of the CapSense Pads ONLY if the user wants an alarm for them.
                   * Otherwise don't check so we can save time and power */
                  if(cssAlertLevel != 0)
                  {
                      UpdateCapSense(FALSE);
                  }
                  
                  /* For some reason I can't get the system to use the bas register callback
                   * Therefor, temporarily, I will just measure the battery level every 'X'
                   * number of connection intervals. This should be fixed at a later date!!
                   */
                  if(connIntervalCount++ == MEAS_BAT_INTERVAL)
                  {
                      connIntervalCount = 0;
                      (void) MeasureBattery();
                  }
              }
              /* If the device is not connected but the BLE is active, update
               * the advertisement data to broadcast the current alert level
               */
              else if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_ACTIVE)
              {
                  UpdateAdvertisementData();
              }
              /* Things worked when I had process events here, but lets try moving it up to get better rssi data */
              //CyBle_ProcessEvents();
          }   
      }