CyBle_GetRssi() returned value doesn't make sense

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

cross mob
CoNe_349661
Level 1
Level 1
First like received

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();
    }   
}

1 Solution
Anonymous
Not applicable

The GetRssi() should work correctly on the BLE 4.2, 256k parts.

View solution in original post

0 Likes
15 Replies
Anonymous
Not applicable

Hello Cody: We discovered that problem too and reported it to Cypress. Their responses follow:

   

10/29/2015 10:32:28 AM - Vadlamudi
Hi Tim,
Thanks for contacting Cypress Technical support.Cyble_getRRSI() API will get the RSSi value of the previously received packet.
When using Advertisement, Link layer itself will append the RSSI  before passing to the host and we can get accurate RSSI values.
Currently the values returned by Cyble_GetRSSI() may give wrong values when device is connected.
We are working on it and this will be fixed in next silicon version(date is not yet fixed).
Regards,Vikas.

   


11/02/2015 12:06:17 PM - Vadlamudi
Hi Tim,
Currently we are testing the RSSI functionality(in connection) for our new chip BLE v.4.2 256K.
I will keep you updating on this. It may take 2-3 weeks to get our new silicon and complete the tests.
Regards,Vikas.

0 Likes

Thanks TDB! I've got a tech support ticket in now with the hopes that they will update me with any news of a fix. If you remember, can you post any info here for me/everyone else whenever you hear from them? Thanks again!

0 Likes
Anonymous
Not applicable

Hello Cody:

   

Yes, I will post an update as soon as I get a response.

   

It has been four (4) weeks already and I have not heard anything yet specifically about that update.

0 Likes
CoNe_349661
Level 1
Level 1
First like received

FYI, here's a response I got from Cypress about the RSSI bug in the 128K chips. 

   

"When you send an empty packet the internal register which holds the RSSI values is not updating properly. So it may result in some invalid RSSI value. We are trying to fix this in 256K chip

For now, the best way to read RSSI value is as follows. The server should send a notification with data packet(non empty). On receiving this notification by client, the event CYBLE_EVT_GATTC_HANDLE_VALUE_NTF will be generated. So once the event got triggered (in the event handler) you can read the RSSI value using the API. This will provide a valid RSSI value."

   

I was able to implement a workaround that seems to be working well, although it has not been tested extensively. My application is for a peripheral server connecting to an iPhone/Android device. I created a dummy characteristic value that the client (phone) writes to. Once the write occurs, the RSSI value is immediately updated and a notification is sent back to client. The RSSI value appears to be accurate and does not have random dropouts.

   

Hope this helps someone!

0 Likes
Anonymous
Not applicable

Hi CodyNeslen,

   

I'm having similar problems as reported in this thread. Could you explain me how to implement the workaround you designed? (I'm kinda' new in this)

   

Thanks!

   

Diego

0 Likes
Anonymous
Not applicable

Is there any update regarding the values returned by Cyble_GetRSSI() ?

   

I'm using CY8C4247LQI-BL483.

   

Thanks!

0 Likes
Anonymous
Not applicable

Hello,
can someone confirm if this issue is still present in the 256K chip (CYBL10XX7X family) used in the CYBLE-212019-00 module?

   

Thank you in advance!
BR
Stefano Voulaz

0 Likes
Anonymous
Not applicable

The GetRssi() should work correctly on the BLE 4.2, 256k parts.

0 Likes
Anonymous
Not applicable

Should probably mark the thread as answered for future reference.

0 Likes
Anonymous
Not applicable

@yssu, could you please precise which 256k parts do not have the CyBle_GetRSSI() problem?

I'm getting out of scale values with 214009, which is a 256k part, although BLE 4.1 only.

Strangely, GetRSSI values are fine when using the CyBLE 214009 Eval on the Pioneer Kit, but not when using the CyBLE 214009 on a custom board.

0 Likes
Anonymous
Not applicable

I have to correct what I posted earlier. The fix has been implemented only in 4.2 256K parts.

Anonymous
Not applicable

Could you please confirm it's fixed on the 214015?

0 Likes
Anonymous
Not applicable

Hi @yssu,

I am using the CYBLE-222005-00 PROC Module which houses the CYBL1XX7X chip.

This chip is BLE 4.2 and has 256 kB of Flash.

I am calling the CyBle_GetRssi() function on the peripheral device when a central is connected to it and it is returning invalid data (fluctuates and out of range of API Spec).

Is it possible this chip is affected by the bug as well? Is there an established workaround?

Thanks and best regards,

Michael S

0 Likes

Hello Michael,

   Where are you calling the API CyBle_GetRssi() in your peripheral project?

Since , the API CyBle_GetRssi()  will returns the most accurate value if you read it after just receiving a valid BLE packet ( Not empty packet). For example , in your peripheral project , you can call this API and read the RSSI value just after writing a characteristics attribute from the client/central device. More specifically in the event CYBLE_EVT_GATTS_WRITE_REQ.

-Gyan

Anonymous
Not applicable

Hi @Gyan,

I was calling the CyBle_GetRssi() from the main() section of my project.

As per your suggestion, I am now calling the CyBle_GetRssi() on the CYBLE_EVT_GATTS_WRITE_REQ event callback and the results seem better. I am still sometimes getting values outside the range of the API spec (i get +100) but I guess I can simply ignore those values?

If you can shed some light into the underlying mechanism maybe I can improve this? I am only sending 1 byte of data from central, should I try writing larger chunks of data or will this have no effect?

Thanks & best regards,

Michael

0 Likes