ble beacon over energy harvesting

hi dev

I have a  question about energy harvest over BLE beacon.

As you can see from previous tickets, I'm working on making beacons using energy harvesting.

And now I made a voltage source using energy harvesting. This voltage supply is 3.0V and supplies voltage to the custom ble module for approximately 24ms.

And this voltage source consists of the structure of the tact switch. When I press the switch, 3.0v voltage is supplied to the ble module for about 24ms and ble module programed the beacon code(ble peripheral/ble_app_beacon)is powered on.

I think this 24ms time is enough for the ble beacon to send advertising data to the central device.

but sometimes it doesn't  work even though I press the button to supply the voltage .

When checked with the oscilloscope, it was confirmed that power was supplied every time the switch was pressed.

Unfortunately, I don't have a ppk2, so I can't check the exact current consumption, but when I checked through the multimeter, I was able to check that the current of 0.5mA goes in on average.(minimum 0.2mA, maximum 0.6mA)

I will attach the bl code here. But the code I attached will be almost the same as the example of beacon.

#include <stdbool.h>
#include <stdint.h>
#include "nordic_common.h"
#include "nrf_soc.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "ble_advdata.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "ble_nus.h"
#include "ble_gap.h"

#include "boards.h"

#define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */
#define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(160, UNIT_0_625_MS)  /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */
#define APP_BEACON_INFO_LENGTH          0x17                               /**< Total length of information advertised by the Beacon. */
#define APP_ADV_DATA_LENGTH             0x09                               /**< Length of manufacturer specific data in the advertisement. */
#define APP_DEVICE_TYPE                 0x02                               /**< 0x02 refers to Beacon. */
#define APP_MEASURED_RSSI               0xC3                               /**< The Beacon's measured RSSI at 1 meter distance in dBm. */
#define APP_COMPANY_IDENTIFIER          0x0059                             /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */
#define APP_MAJOR_VALUE                 0x01, 0x02                         /**< Major value used to identify Beacons. */
#define APP_MINOR_VALUE                 0x03, 0x04                         /**< Minor value used to identify Beacons. */
#define APP_BEACON_UUID                 0x01, 0x12, 0x23, 0x34 
                                                 /**< Proprietary UUID for Beacon. */






static ble_gap_adv_params_t m_adv_params;                                  /**< Parameters to be passed to the stack when starting advertising. */
static uint8_t              m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
static uint8_t              m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */

static ble_gap_adv_data_t m_adv_data =
{
    .adv_data =
    {
        .p_data = m_enc_advdata,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    },
    .scan_rsp_data =
    {
        .p_data = NULL,
        .len    = 0

    }
};


static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] =                    /**< Information advertised by the Beacon. */
{
    APP_DEVICE_TYPE,     // Manufacturer specific information. Specifies the device type in this
                         // implementation.
    APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
                         // manufacturer specific data in this implementation.
    APP_BEACON_UUID,     // 128 bit UUID value.
    APP_MAJOR_VALUE,     // Major arbitrary value that can be used to distinguish between Beacons.
    APP_MINOR_VALUE,     // Minor arbitrary value that can be used to distinguish between Beacons.
    APP_MEASURED_RSSI    // Manufacturer specific information. The Beacon's measured TX power in
                         // this implementation.
};


static void advertising_init(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;
    uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
    ble_advdata_manuf_data_t manuf_specific_data;

    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;

    manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
    manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type             = BLE_ADVDATA_NO_NAME;
    advdata.flags                 = flags;
    advdata.p_manuf_specific_data = &manuf_specific_data;

    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
    m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = 0;       // Never time out.

    ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);

   
}


static void advertising_start(void)
{
   sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
}

static void ble_stack_init(void)
{
   uint32_t ram_start = 0;
   nrf_sdh_enable_request();
   nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
   nrf_sdh_ble_enable(&ram_start);
}

static void log_init(void)
{
    NRF_LOG_INIT(NULL);
    NRF_LOG_DEFAULT_BACKENDS_INIT();



}

static void idle_state_handle(void)
{
    if (NRF_LOG_PROCESS() == false)
    {
        nrf_pwr_mgmt_run();
    }
}



int main(void)
{
    //nrf_gpio_cfg_input(6, NRF_GPIO_PIN_PULLDOWN);
    //nrf_gpio_cfg_input(14, NRF_GPIO_PIN_PULLDOWN);
    log_init();
    nrf_pwr_mgmt_init();
    ble_stack_init();
    advertising_init();
    

    advertising_start();
    
    
       
    
    
    while(1)
    {   
        
        idle_state_handle();
    }
}

and I use sdk v17.1 and segger embedded stdio.

I want you to look at my ticket and code and give me some advice.

thank you.

Parents
  • as the code shows /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */

    There is a minimum time for ble pairs to be connected. I believe 24ms is not enough time. Also you need to make sure maximum of at least 15mA is able to flow that's the peak current when adv event or conn event happens.

  • hi Senchoi

    thank you for reply my ticket.

    I'm sorry to say that There was something I forgot to write it down in this ticket.

    in my project, beacon and central device don't have to pair and bond each other.

    because my beacon only send "advertising data' to central device.

    and whenever central device receive "advertising data", central device do something (like turning on the led on central board)

    there is no pairing or bonding process. 


    as the code shows /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */

    There is a minimum time for ble pairs to be connected. I believe 24ms is not enough time.

    As far as I understand, "the advertising interval" refers to the period during which the peripheral device (in my case, beacon) sends the advertising data once and then the next advertising data.

    and whenever beacon turns on, it sends the advertising data right away. 

    so in my case, I only need the first advertising adta. I dont need the advertising data to be sent after "the advertising interval"

  • Then I’m guessing it’s the lack of supply for the peak current. When I measure BLE device ppk2, my case nRF52840 dongle, peak current fluctuates a little. In range 12 to 18mA. If you’re sure you’re supplying enough power, you should look deeper into softdevice whether the timer is getting cut off because the supply lasts only 24. Since the interval looks like 160ms. The timer value is trying to meet the compare value which results in not sending the data. Would you try disabling timing interval mechanism and sending the data once and finish the program on your device?

  • Would you try disabling timing interval mechanism and sending the data once and finish the program on your device?

    would you explain about that?

    I've been working on it since yesterday but... nothing changes.

    what I do is 

    1) change the value of NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(160, UNIT_0_625_MS)

    What I've checked here is that the smaller the value, the more sensitive the reaction is, and the bigger the value, the less effective it is.

    1)-1 and I remove that code

    : #define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(160, UNIT_0_625_MS)

    in this case, I can debug but nothing happens.

    Everything I've done doesn't work...

     

Reply
  • Would you try disabling timing interval mechanism and sending the data once and finish the program on your device?

    would you explain about that?

    I've been working on it since yesterday but... nothing changes.

    what I do is 

    1) change the value of NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(160, UNIT_0_625_MS)

    What I've checked here is that the smaller the value, the more sensitive the reaction is, and the bigger the value, the less effective it is.

    1)-1 and I remove that code

    : #define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(160, UNIT_0_625_MS)

    in this case, I can debug but nothing happens.

    Everything I've done doesn't work...

     

Children
  • It's natural to get very complicated as you try to modify the given code. Usually you should work on top of nordic's sdk layer. But there's a good chance you have to modify things that people normally shouldn't to implement what you want.

    removing such code is not going to help. if you're using Segger Embedded Studio you can right click each code and select Go To Definition to get deeper into the sdk.

    In my brief research, it seems you have to insert sd_ble_gap_adv_stop(uint8_t adv_handle) function somewhere in the code to stop advertising immediately after one adv event.

    Or there may be a single-shot mode for ble_advertising_init.

    Or try setting max_adv_evts to 1 for m_adv_params. This may be the single shot mode.

    Also since it says 100ms is the minimum value. You may be violating the standard. In that case things can get even more complicated to implement. It may not be even possible with Nordic's sdk.

    I wish you good luck. It always looks impossible before you actually make it happen.

Related