Beacon only advertising once when interval is set to ~5s

I'm trying to create a demo beacon with an advertising interval of 5s and I only ever see a single advertisement from the device, following boot up. I've encountered this both on a custom app and when modifying the zephyr BLE beacon sample. I've encountered this on both NCS 2.6.1 & 2.7.0. AFAIK a 5s advertising interval is valid per the BLE spec.

My app:

main.c

#include <zephyr/bluetooth/bluetooth.h>

// Advertising interval = 0x1F38 * 0.625 ms = 4995 ms
// Intervals also have an added 0 to 10 ms random delay.
#define ADV_INTVL (0x1F38)

#define SERIAL_NUMBER "ACEA11ED240286"

static const struct bt_data ad[] = {
	BT_DATA(BT_DATA_NAME_COMPLETE, SERIAL_NUMBER,
		sizeof(SERIAL_NUMBER) - 1),
};

static bool call_enable = true;

static void bt_ready(int err)
{
	if (err) return;

	struct bt_le_adv_param adv_param = BT_LE_ADV_PARAM_INIT(
		BT_LE_ADV_OPT_USE_NRPA, ADV_INTVL, ADV_INTVL, NULL);

	err = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), NULL, 0);
	if (err) {
		bt_disable();
	} else {
		call_enable = false;
	}
}

int main(void)
{
	int err;

	while (call_enable) {
		err = bt_enable(bt_ready);
		if (err) {
			call_enable = true;
		}
	}

	return 0;
}

prj.conf:

CONFIG_BT=y
CONFIG_BT_BROADCASTER=y

CONFIG_DEBUG=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_THREAD_INFO=y

CONFIG_ASSERT=y

Modified zephyr BLE sample main.c:

/* main.c - Application main entry point */

/*
 * Copyright (c) 2015-2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/types.h>
#include <stddef.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>

#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

/*
 * Set Advertisement data. Based on the Eddystone specification:
 * https://github.com/google/eddystone/blob/master/protocol-specification.md
 * https://github.com/google/eddystone/tree/master/eddystone-url
 */
static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
	BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0xaa, 0xfe),
	BT_DATA_BYTES(BT_DATA_SVC_DATA16,
		      0xaa, 0xfe, /* Eddystone UUID */
		      0x10, /* Eddystone-URL frame type */
		      0x00, /* Calibrated Tx power at 0m */
		      0x00, /* URL Scheme Prefix http://www. */
		      'z', 'e', 'p', 'h', 'y', 'r',
		      'p', 'r', 'o', 'j', 'e', 'c', 't',
		      0x08) /* .org */
};

/* Set Scan Response data */
static const struct bt_data sd[] = {
	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};

static void bt_ready(int err)
{
	char addr_s[BT_ADDR_LE_STR_LEN];
	bt_addr_le_t addr = {0};
	size_t count = 1;

	if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
		return;
	}

	printk("Bluetooth initialized\n");

	struct bt_le_adv_param params = BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_USE_IDENTITY,
		0x1f38, 0x1f39, NULL);

	/* Start advertising */
	err = bt_le_adv_start(&params, ad, ARRAY_SIZE(ad),
			      sd, ARRAY_SIZE(sd));
	if (err) {
		printk("Advertising failed to start (err %d)\n", err);
		return;
	}


	/* For connectable advertising you would use
	 * bt_le_oob_get_local().  For non-connectable non-identity
	 * advertising an non-resolvable private address is used;
	 * there is no API to retrieve that.
	 */

	bt_id_get(&addr, &count);
	bt_addr_le_to_str(&addr, addr_s, sizeof(addr_s));

	printk("Beacon started, advertising as %s\n", addr_s);
}

int main(void)
{
	int err;

	printk("Starting Beacon Demo\n");

	/* Initialize the Bluetooth Subsystem */
	err = bt_enable(bt_ready);
	if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
	}
	return 0;
}

Parents
  • Hello Benjamin,

    How did you determine it wasn't advertising? I just added the following to the beacon sample:

    struct bt_le_adv_param params = BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_USE_IDENTITY, 0x1f38, 0x1f39, NULL);

    Right before starting the adverts, which I changed to use &params, and I am verifying adverts that are >=5s apart. I did notice though that if I try to monitor the adverts using the nRF Connect Mobile app (iOS) the main scan results screen does show the 'Test beacon' device as N/A<->N/A. However, if you select that device and look on the following screen you will see that new packets are coming in as expected, just not showing on the main screen probably due to the large interval. 

    Let me know if you are not able to confirm this. 

    Thank you,

    Jennifer Gibbs

  • I'm running this on a brand new 52833dk (powered by the coin cell) and scanning from the iOS app running on a Mac. For other detected devices, I can see the advertising packets, but for my tests I only ever see a single dot until I power cycle.

Reply Children
Related