Hi everyone,
I am currently working on a BLE scanner application that will scan for surrounding tag beacons for 5 seconds every time (the beacons interval is 1 second)
I am using nRF Connect SDK v2.3.0
Below are my thread file and config file (all the Zephyr BT libraries were included in the ble header file:
#ifndef _BLE_SCANNER_H_ #define _BLE_SCANNER_H_ #include <stdio.h> #include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/hci.h> #include <zephyr/bluetooth/uuid.h> #include <zephyr/bluetooth/controller.h> #include <zephyr/logging/log.h> #include <zephyr/sys/util.h> #include <zephyr/types.h> // Max legnth of advertising payload as defined by the BLE advertising standard #define MAX_MANUF_DATA_PAYLOAD_LENGTH 26 /** @brief Function that enable the ble API. */ void ble_enable(void); /** @brief Function that disable the ble API. */ void ble_disable(void); /** @brief Function that starts the ble scanner module. * @param[in] scan_duration_s The duration of scanning in seconds. If set to 0, the device will scan indefinitely. */ void ble_scan_start(struct bt_le_scan_param scan_param, uint32_t scan_duration_s, bt_le_scan_cb_t cb); #endif // _BLE_SCANNER_H_
#ifndef _BEACONS_HANDLE_H_
#define _BEACONS_HANDLE_H_
#include "../BLE/ble_scanner.h"
#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>
#include <zephyr/types.h>
#include <sdc.h>
#include <stdio.h>
#define DEFAULT_BEACON_DATA_LENGTH 40
#define BEACON_STACKSIZE 1024
#define BEACON_THREAD_PRIORITY 3
/** @brief BLE Door sensor struct
*/
typedef struct bt_le_beacon_ {
bt_addr_le_t beacon_addr; // Door sensor address in bt_le_addr format
uint8_t beacon_data_buf[DEFAULT_BEACON_DATA_LENGTH]; // Pointer to the buffer of the door sensor data
int8_t beacon_rssi; // Pointer to door_sensor RSSI
uint8_t beacon_adv_type; // pointer to door adv_type
} ble_beacon;
/** @brief Function that configure the ble beacon in the BLE Stack
* @param[in] beacon_uuid Tag beacon UUID [2 bytes]
* @return 0 on success or negative value otherwise
*/
static int16_t config_ble_beacons(uint16_t beacon_uuid);
/** @brief Function that handle the ble door sensor data after done call back
* @return none
*/
void ble_beacons_handle_thread(void);
#endif // _DOOR_SENSOR_HANDLE_H_
#include "beacons_handle.h"
#include <stdio.h>
#include <string.h>
int beacon_err; // Tag beacon error code
uint16_t beacon_callback_counter; // Counter for every success beacon callback
uint8_t total_callback_counter; // Counter for every scanned devices
uint8_t beacon_callback_flag = 0; // 1 when done callback
static bt_addr_le_t prev_addr; // Manually keep track on the addr has been found
ble_beacon tag_beacon;
LOG_MODULE_REGISTER(tag_beacon, LOG_LEVEL_DBG);
static struct bt_uuid_16 uuid_whitelist = BT_UUID_INIT_16(0xABFE); // beacon UUID
struct bt_le_scan_param tag_beacon_scan_param = {
.type = BT_HCI_LE_SCAN_PASSIVE, .options = BT_LE_SCAN_OPT_FILTER_DUPLICATE, .interval = 0x0010, .window = 0x0010, .timeout = 0
};
/** @brief Callback invoked when there is a new BLE scan result available. */
void scan_beacon_cb(const bt_addr_le_t* addr, int8_t rssi, uint8_t adv_type, struct net_buf_simple* buf)
{
// LOG_INF("\033[96mScanned %d devices!\033[1m\n", ++beacon_callback_counter);
total_callback_counter++;
char addr_str[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
uint16_t uuid_received = (buf->data[8] << 8 | buf->data[9]);
if (uuid_received != uuid_whitelist.val) {
// LOG_WRN("Invalid UUID: 0x%04x\n", uuid_received);
return;
}
beacon_callback_counter++;
LOG_INF("Device found: \033[92m%s\033[0m\tUUID: 0x%04x\tRSSI: %d\n", addr_str, uuid_received, rssi);
// ble_disable();
}
void ble_beacon_handle_thread(void)
{
ble_enable();
ble_scan_start(tag_beacon_scan_param, 4, scan_beacon_cb);
LOG_INF("Total %d MOKO beacons scanned", beacon_callback_counter);
LOG_INF("Total %d devices scanned\n", total_callback_counter);
while (1) {
k_msleep(10 * 1000);
}
}
K_THREAD_DEFINE(ble_beacon_ID, BEACON_STACKSIZE, ble_beacon_handle_thread, NULL, NULL, NULL, BEACON_THREAD_PRIORITY, 0, 0);
Config file:
# BLUETOOTH CONFIG_BT=y CONFIG_BT_OBSERVER=y CONFIG_BT_DEBUG_LOG=y CONFIG_BT_FILTER_ACCEPT_LIST=y CONFIG_BT_LL_SOFTDEVICE=y CONFIG_BT_SCAN_FILTER_ENABLE=y CONFIG_BT_SCAN_UUID_CNT=1 CONFIG_BT_SCAN=y CONFIG_BT_LL_SW_SPLIT=y # SERIAL CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_BOOT_BANNER=y CONFIG_NEWLIB_LIBC_NANO=n CONFIG_MINIMAL_LIBC=n # LOG CONFIG_LOG=y CONFIG_LOG_MODE_MINIMAL=n CONFIG_LOG_MODE_DEFERRED=y CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=1 CONFIG_LOG_PROCESS_THREAD=y CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=2048 # NEW LIB CONFIG_NEWLIB_LIBC=y # Stacks and heaps CONFIG_MAIN_STACK_SIZE=4096 CONFIG_HEAP_MEM_POOL_SIZE=2048 # PM MANAGER CONFIG_PM_DEVICE=y
I assume this code will filter out the duplicated addresses. When it callbacks, I also filter out the UUDI another time to make sure I have the exact beacon value. However, as can be seen from the terminal, there are 3 beacons that were called back 3 times in 5 seconds, which means the duplicated filter did not work as I expected.
Please let me know if anything was wrong with my code or my setup or maybe another way to filter out duplicated addresses. Thank you.
