How to get the rssi from BLE scan

iamblwb
Posts: 13
Joined: Wed Dec 28, 2016 3:26 pm

How to get the rssi from BLE scan

Postby iamblwb » Thu Dec 29, 2016 5:25 am

I refer to the example 15_gatt_client and think the rssi should be gotten from scan result when I received the event ESP_GAP_BLE_SCAN_RESULT_EVT in callback function esp_gap_cb.
Is it correct?
If so, is this rssi reliable?
The value I got seems very very unstable even my ESP32 and target always kept in the same position without any move.
Should I or may I do the RF calibration to improve this?
Thanks

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: How to get the rssi from BLE scan

Postby kolban » Thu Dec 29, 2016 2:29 pm

What is the value your are seeing? How does it change (if at all) when your BLE peripheral is moved further from the ESP32 ... at what distance do you see the loss of the advertising packet?

The way I have seen the signal strength measured is exactly as your describe.

A call to esp_ble_gap_register() to register a callback handler.
A call to esp_ble_gap_set_scan_params() to set the scan parameters.
A call to esp_ble_gap_start_scanning() to initiate scanning.

Now the callback will be invoked when a BLE peripheral performs an advertisement. In the received data structure, one of the available fields is "rssi" which is the signal strength received.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

iamblwb
Posts: 13
Joined: Wed Dec 28, 2016 3:26 pm

Re: How to get the rssi from BLE scan

Postby iamblwb » Thu Dec 29, 2016 4:35 pm

Hi Neil,
Actually, I didn't do too many experiments.
It's because the result seems very poor (compare to the result measured by my android phone), so I stop the further experiment.
You can check the statistical data in the attachment.
Totally I do 3 experiments for one target, each experiment performed 157 times scanning, the distance is about 50 cm.
Besides, I try to put the target and my EPS32 together (0 distance), but looks like the RSSI didn't change significantly.
Thanks
ESP32 experiment.jpg
ESP32 experiment
ESP32 experiment.jpg (30.18 KiB) Viewed 8580 times

bombix
Posts: 12
Joined: Fri Jan 20, 2017 12:56 pm

Re: How to get the rssi from BLE scan

Postby bombix » Tue Jan 24, 2017 10:53 am

Hi,

Im started to play a little with the esp32 but its alot mode dificult than the esp8266 and arduino.
Im trying to scan beacons and i started from the example gatt_client.
It shows 0 results but im surrrounded by beacons acording to my phone.
Could you please help me, sharing your code?

Thanks in advance

neilyoung
Posts: 12
Joined: Fri Mar 03, 2017 8:12 pm

Re: How to get the rssi from BLE scan

Postby neilyoung » Mon Mar 13, 2017 1:03 pm

I can confirm this mess. I'm using a Sparkfun ESP32Thing. RSSI values are sometimes complete nonsense, some industry standard iBeacons (like RadBeacons) are not recognized at all (or just occasionally).

Here is my ESP32-IDF snippet and the results I'm receiving with it. Donald would finish with "Very disappointing" and so do I :)

Maybe code sharing helps to come behind:

Here is the code:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "bt.h"

#include "esp_blufi_api.h"
#include "esp_bt_defs.h"
#include "esp_gap_ble_api.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"

extern void bt_task(void *ignore);

static const char tag[] = "BLE";

static uint8_t ibeacon_prefix[] = {
	 0x02,0x01,0x00,0x1A,0xFF,0x4C,0x00,0x02,0x15
};


void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
	esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param;

	if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) {
		// Check for iBeacon adv prefix. Ignore 3rd byte, this varies from beacon type to beacon type
		p->scan_rst.ble_adv[2]  = 0x00;
		for (int i=0; i < sizeof(ibeacon_prefix); i++) {
			if (p->scan_rst.ble_adv[i] != ibeacon_prefix[i]) {
				return;
			}
		}
		ESP_LOGI(tag, "BDA: %02x:%02x:%02x:%02x:%02x:%02x, RSSI %d", 
			p->scan_rst.bda[0], 
			p->scan_rst.bda[1],
			p->scan_rst.bda[2], 
			p->scan_rst.bda[3], 
			p->scan_rst.bda[4],
			p->scan_rst.bda[5],  
			p->scan_rst.rssi);
	}
} 


void bt_task(void *ignore) {
	esp_err_t ret;

	esp_bt_controller_init();

	ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM);
	if (ret) {
		ESP_LOGE(tag, "%s enable bt controller failed\n", __func__);
		goto end;
	}

	ret = esp_bluedroid_init();
	if (ret != ESP_OK) {
		ESP_LOGE(tag, "%s init bluedroid failed\n", __func__);
		goto end;
	}

	ret = esp_bluedroid_enable();
	if (ret) {
		ESP_LOGE(tag, "%s enable bluedroid failed\n", __func__);
		goto end;
	}
	ret = esp_ble_gap_register_callback(gap_event_handler);
	if (ret != ESP_OK) {
		ESP_LOGE(tag, "esp_ble_gap_register_callback: rc=%d", ret);
		goto end;
	}
	static esp_ble_scan_params_t ble_scan_params = {
		.scan_type              = BLE_SCAN_TYPE_ACTIVE,
		.own_addr_type          = ESP_PUBLIC_ADDR,
		.scan_filter_policy     = BLE_SCAN_FILTER_ALLOW_ALL,
		.scan_interval          = 0x50,
		.scan_window            = 0x30
	};
	ret = esp_ble_gap_set_scan_params(&ble_scan_params);
	if (ret != ESP_OK) {
		ESP_LOGE(tag, "esp_ble_gap_set_scan_params: rc=%d", ret);
		goto end;
	}

	ret = esp_ble_gap_start_scanning(60);
	if (ret != ESP_OK) {
		ESP_LOGE(tag, "esp_ble_gap_start_scanning: rc=%d", ret);
		goto end;
	}
	ESP_LOGI(tag, "Wait for scans...");
end:
	vTaskDelete(NULL);	
} 


void app_main(void) {
	xTaskCreatePinnedToCore(&bt_task, "btTask", 2048, NULL, 5, NULL, 0);
}
Maybe I'm doing something fundamentally wrong, don't know.

The code is scanning for 60 seconds and it is examining incoming traces in order to accept just iBeacon advertisements. I have tried to vary esp_ble_scan_params_t to no avail.

Some info regarding the environment:

(29) boot: ESP-IDF v2.0-rc1-257-g4745895 2nd stage bootloader
I (29) boot: compile time 02:20:42
I (56) boot: Enabling RNG early entropy source...
I (56) boot: SPI Speed : 40MHz
I (56) boot: SPI Mode : DIO
I (59) boot: SPI Flash Size : 4MB
I (69) boot: Partition Table:
I (77) boot: ## Label Usage Type ST Offset Length
I (96) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (116) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (137) boot: 2 factory factory app 00 00 00010000 00100000
I (157) boot: End of partition table

This code running on a Sparkfun ESP32Thing does

Just displaying scattered scans from an Estimote Hardware beacon with weak battery like so:
I (325) BLE: Wait for scans...
I (2745) BLE: BDA: ea:19:6f:c1:48:39, RSSI -60
I (4585) BLE: BDA: ea:19:6f:c1:48:39, RSSI -58
I (5205) BLE: BDA: ea:19:6f:c1:48:39, RSSI -60
I (13205) BLE: BDA: ea:19:6f:c1:48:39, RSSI -61
I (15045) BLE: BDA: ea:19:6f:c1:48:39, RSSI -67
I (15655) BLE: BDA: ea:19:6f:c1:48:39, RSSI -67

Looks OK, but frequency of scans results is too low and RSSI is too high.

Does show this with an iPhone running an virtual beacon Estimote beacon:
I (6445) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (6515) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (6545) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -8
I (6605) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (6635) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (6695) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -8
I (6735) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (6795) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (6865) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -8
I (6895) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (6955) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (6985) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -8
I (7045) BLE: BDA: ea:19:6f:c1:48:39, RSSI -59
I (7045) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (7115) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (7145) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -8
I (7255) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9
I (7305) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -8
I (7335) BLE: BDA: 5a:4d:31:43:d2:21, RSSI -9

Frequency is OK, IMHO, but RSSI is nonsense... The Sparkfun lies on top of the iPhone.

Does literally show NOTHING at all (OK, maybe one or two in a minute, if in luck), if scanning a RadBeacon Dot.

bombix
Posts: 12
Joined: Fri Jan 20, 2017 12:56 pm

Re: How to get the rssi from BLE scan

Postby bombix » Thu Mar 23, 2017 5:42 pm

Hi,

This chip is starting to be really dificult.
I have a ESP-WROOM-32, and can only upload in platformIO, in the arduino ide i cant upload.
I runned your code and it gave an error after some googling i fixe that error but now i get another:

src\main.c:59:35: error: 'ESP_BT_MODE_BTDM' undeclared (first use in this function)

The code is the folowing:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "bt.h"

#include "esp_blufi_api.h"
#include "esp_bt_defs.h"
#include "esp_gap_ble_api.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"

extern void bt_task(void *ignore);

static const char tag[] = "BLE";

static uint8_t ibeacon_prefix[] = {
    0x02,0x01,0x00,0x1A,0xFF,0x4C,0x00,0x02,0x15
};


void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
   esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param;

   if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) {
      // Check for iBeacon adv prefix. Ignore 3rd byte, this varies from beacon type to beacon type
      p->scan_rst.ble_adv[2]  = 0x00;
      for (int i=0; i < sizeof(ibeacon_prefix); i++) {
         if (p->scan_rst.ble_adv[i] != ibeacon_prefix[i]) {
            return;
         }
      }
      ESP_LOGI(tag, "BDA: %02x:%02x:%02x:%02x:%02x:%02x, RSSI %d",
         p->scan_rst.bda[0],
         p->scan_rst.bda[1],
         p->scan_rst.bda[2],
         p->scan_rst.bda[3],
         p->scan_rst.bda[4],
         p->scan_rst.bda[5],
         p->scan_rst.rssi);
   }
}


void bt_task(void *ignore) {
   esp_err_t ret;

   esp_bt_controller_init();

   ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM);
   if (ret) {
      ESP_LOGE(tag, "%s enable bt controller failed\n", __func__);
      goto end;
   }

   ret = esp_bluedroid_init();
   if (ret != ESP_OK) {
      ESP_LOGE(tag, "%s init bluedroid failed\n", __func__);
      goto end;
   }

   ret = esp_bluedroid_enable();
   if (ret) {
      ESP_LOGE(tag, "%s enable bluedroid failed\n", __func__);
      goto end;
   }
   ret = esp_ble_gap_register_callback(gap_event_handler);
   if (ret != ESP_OK) {
      ESP_LOGE(tag, "esp_ble_gap_register_callback: rc=%d", ret);
      goto end;
   }
   static esp_ble_scan_params_t ble_scan_params = {
      .scan_type              = BLE_SCAN_TYPE_ACTIVE,
      .own_addr_type          = ESP_PUBLIC_ADDR,
      .scan_filter_policy     = BLE_SCAN_FILTER_ALLOW_ALL,
      .scan_interval          = 0x50,
      .scan_window            = 0x30
   };
   ret = esp_ble_gap_set_scan_params(&ble_scan_params);
   if (ret != ESP_OK) {
      ESP_LOGE(tag, "esp_ble_gap_set_scan_params: rc=%d", ret);
      goto end;
   }

   ret = esp_ble_gap_start_scanning(60);
   if (ret != ESP_OK) {
      ESP_LOGE(tag, "esp_ble_gap_start_scanning: rc=%d", ret);
      goto end;
   }
   ESP_LOGI(tag, "Wait for scans...");
end:
   vTaskDelete(NULL);
}


void app_main(void) {
   xTaskCreatePinnedToCore(&bt_task, "btTask", 2048, NULL, 5, NULL, 0);
}
Im using windows, maybe that is part of the problem...
I read in a forum that i have to turn BT on in the menuconfig... but i cant seem to find any configs.
Any ideas?
Thanks in advance

neilyoung
Posts: 12
Joined: Fri Mar 03, 2017 8:12 pm

Re: How to get the rssi from BLE scan

Postby neilyoung » Thu Mar 23, 2017 6:41 pm

You need to follow the installation rules provided here https://github.com/espressif/esp-idf
Then take the /examples/bluetooth/gatt_client/ and copy my main.c into the main sub dir. Remove gatt_demo.c
Run "make menuconfig" from the root of the project. After the proper configuration run "make flash" or "make flash monitor"

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: How to get the rssi from BLE scan

Postby kolban » Thu Mar 23, 2017 6:59 pm

I'd like to second what neilyoung said ... Ive started to study platformio and think I see that it currently has limited integration with the ESP-IDF technologies. It might work fine if you are staying exclusively in an "arduino" platform but if you are working in an ESP-IDF platform, it isn't there yet. Investment you make in studying the Espressif build system associated with ESP-IDF at this stage will do you no harm.

I do like the ideas behind platformio.org but it looks like it will need more attention to be "GREAT" for ESP-IDF solutions. I'm trying to contact the maintainers of platformio.org to see if they are open to working with the ESP32 community for enhancements and integration with ESP32 specifics. In the meantime, stick to ESP-IDF and the Espressif build system (opinion).
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

neilyoung
Posts: 12
Joined: Fri Mar 03, 2017 8:12 pm

Re: How to get the rssi from BLE scan

Postby neilyoung » Thu Mar 23, 2017 7:11 pm

Thanks @kolban. I'm also working with platform.io in an ESP8266 project, using Visual Studio Code as IDE. The same IDE is perfectly working (including symbol resolution, git support and kind of "intellisense") in the ESP-IDF world. Right now ESP-IDF is the bleeding edge in ESP32 development and the #1 choice. The Arduino port is currently not fully supporting things, already there in ESP-IDF.

bombix
Posts: 12
Joined: Fri Jan 20, 2017 12:56 pm

Re: How to get the rssi from BLE scan

Postby bombix » Fri Mar 24, 2017 12:28 pm

Hi,

I have followed your advice.
It worked. Could you please recoment any documentation adequate for beginners?

What serial monitor do you use?

Thanks in advance

Who is online

Users browsing this forum: Google [Bot] and 13 guests