Hi,
i m using my custom nrf52832 beacon.For Battery power, i used accelerometer.i trying to change advertising interval for non connectable BLE device while accelerometer enable.In IDLE mode i set advertising interval is 5000ms.when accelerometer is enabled, i changed advertising interval to 500ms for next 5 seconds then back to IDLE mode.My question is while in interrupt mode 350 uA current is taking (advertising interval 500ms).
Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "app_timer.h"
#include "nrf_drv_clock.h"
#include "ble_advdata.h"
#include "bsp.h"
#include "nordic_common.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_drv_gpiote.h"
#include "boards.h"
#include "nrf_drv_twi.h"
#include "LIS3DH.h"
//#include "nrf_drv_saadc.h"
//#include "nrf_drv_ppi.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <string.h> #include "app_timer.h" #include "nrf_drv_clock.h" #include "ble_advdata.h" #include "bsp.h" #include "nordic_common.h" #include "nrf_pwr_mgmt.h" #include "nrf_drv_gpiote.h" #include "boards.h" #include "nrf_drv_twi.h" #include "LIS3DH.h" //#include "nrf_drv_saadc.h" //#include "nrf_drv_ppi.h" #include "nrf_delay.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #define APP_BLE_CONN_CFG_TAG 1 // Tag identifying the BLE configuration. #define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(5000, UNIT_0_625_MS) // iBeacon specifies an advertising interval of 100ms #define NON_CONNECTABLE_ADV_INTERVAL_FAST MSEC_TO_UNITS(1000, UNIT_0_625_MS) #define APP_BEACON_INFO_LENGTH 0x17 // Total length of information advertised by the Beacon. */ #define APP_ADV_DATA_LENGTH 0x15 // Length of manufacturer specific data in the advertisement. */ #define APP_DEVICE_TYPE 0x02 // 0x02 refers to Beacon. #define APP_COMPANY_IDENTIFIER 0x004C #define DEAD_BEEF 0xDEADBEEF // Value used as error code on stack dump /*Pin Congiguration*/ #define NURSE_CALL 13 #define ACCEL_CALL 7 /* Number of possible TWI addresses. */ #define TWI_ADDRESSES 127 APP_TIMER_DEF(my_timer); APP_TIMER_DEF(fast_my_timer); uint32_t mac_addr[]; uint8_t service_uid[17]; uint8_t *service_uid_pointer; uint8_t m_beacon_info1[APP_BEACON_INFO_LENGTH]={0}; uint8_t serial_number[4]; uint32_t test_sno; bool aid_flag=false; bool accel_flag=false; 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. bool is_advertising = false; /* Indicates if operation on TWI has ended. */ /* TWI instance. */ static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(0); /*Encoded advertising data. */ 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 } }; void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) { app_error_handler(DEAD_BEEF, line_num, p_file_name); } /** Initializing the Advertising.**/ static void advertising_init(uint16_t interval) { uint32_t err_code; ble_advdata_t advdata; uint32_t pin_value; uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; /* Beacon Configuration*/ ble_advdata_manuf_data_t manuf_specific_data; manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER; m_beacon_info1[0]=APP_DEVICE_TYPE; m_beacon_info1[1]=APP_ADV_DATA_LENGTH; /* service id*/ for(int i=5;i>1;i--) { m_beacon_info1[i]=*service_uid_pointer++; } //m_beacon_info1[6]=0x00; // Aided m_beacon_info1[7]=0xff; //Reserved id m_beacon_info1[8]=0xff; // reserved id m_beacon_info1[18]=0x54; //Major 1st byte m_beacon_info1[19]=0x57; //Major 2nd byte m_beacon_info1[20]=0x4F; //Minor 1st byte m_beacon_info1[21]=0x54; //Minor 2nd byte m_beacon_info1[22]=0xC3; //Rssi @1m manuf_specific_data.data.p_data = (uint8_t *)m_beacon_info1; 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. 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; //Filter policy m_adv_params.interval = interval; m_adv_params.duration = 0; // Never time out. err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params); APP_ERROR_CHECK(err_code); } static void advertising_init_fast(void) { uint32_t err_code; ble_advdata_t advdata; uint32_t pin_value; uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; /* Beacon Configuration*/ ble_advdata_manuf_data_t manuf_specific_data; manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER; m_beacon_info1[0]=APP_DEVICE_TYPE; m_beacon_info1[1]=APP_ADV_DATA_LENGTH; /* service id*/ for(int i=5;i>1;i--) { m_beacon_info1[i]=*service_uid_pointer++; } //m_beacon_info1[6]=0x00; // Aided m_beacon_info1[7]=0xff; //Reserved id m_beacon_info1[8]=0xff; // reserved id m_beacon_info1[18]=0x54; //Major 1st byte m_beacon_info1[19]=0x57; //Major 2nd byte m_beacon_info1[20]=0x4F; //Minor 1st byte m_beacon_info1[21]=0x54; //Minor 2nd byte m_beacon_info1[22]=0xC3; //Rssi @1m manuf_specific_data.data.p_data = (uint8_t *)m_beacon_info1; 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. 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; //Filter policy m_adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL_FAST; m_adv_params.duration = 0; // Never time out. err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params); APP_ERROR_CHECK(err_code); } /**Starting advertising.*/ static void advertising_start(void) { ret_code_t err_code; err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG); APP_ERROR_CHECK(err_code); err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); APP_ERROR_CHECK(err_code); } void device_name_get(void) { memcpy(serial_number,(uint32_t*)0x10001084,4); mac_addr[0]=NRF_FICR->DEVICEADDR0; test_sno = test_sno | (serial_number[0] <<24)|(serial_number[1] <<16)|(serial_number[2] <<8)|(serial_number[3]); if (test_sno != 0xFFFF7FFFF) { for(int i=0;i<4;i++) { service_uid[i]=serial_number[i]; // NRF_LOG_INFO("S.NO:%2X",service_uid[i]); } } else { for(int i=0;i<4;i++){ service_uid[i]=(uint8_t)((mac_addr[0])>>(8*i)); // NRF_LOG_INFO("MAC:%2X",service_uid[i]); } } service_uid_pointer=&service_uid; } /*Initializing the BLE stack.*/ static void ble_stack_init(void) { ret_code_t err_code; err_code = nrf_sdh_enable_request(); APP_ERROR_CHECK(err_code); // Configure the BLE stack. // Fetch the start address of the application RAM. uint32_t ram_start = 0; err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start); APP_ERROR_CHECK(err_code); // Enable BLE stack. err_code = nrf_sdh_ble_enable(&ram_start); APP_ERROR_CHECK(err_code); } /** Initializing logging. */ static void log_init(void) { ret_code_t err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); } /**Initializing LEDs. */ static void leds_init(void) { ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL); APP_ERROR_CHECK(err_code); } /** Initializing power management.*/ static void power_management_init(void) { ret_code_t err_code; err_code = nrf_pwr_mgmt_init(); APP_ERROR_CHECK(err_code); } static void aid_call_timeout_handler(void * p_context) { //nrf_gpio_pin_clear(17); ret_code_t err_code; err_code = sd_ble_gap_adv_stop(m_adv_handle); accel_flag=false; device_name_get(); m_beacon_info1[6]=0x00; // m_adv_params.interval=NON_CONNECTABLE_ADV_INTERVAL_FAST; advertising_init(5000); advertising_start(); } static void accel_timeout_handler(void * p_context) { // nrf_gpio_pin_clear(17); accel_flag=false; ret_code_t err_code; err_code = sd_ble_gap_adv_stop(m_adv_handle); device_name_get(); //m_adv_params.interval=NON_CONNECTABLE_ADV_INTERVAL; advertising_init(5000); advertising_start(); } /**@brief Function for initializing timers. */ static void timers_init(void) { ret_code_t err_code = app_timer_init(); APP_ERROR_CHECK(err_code); err_code=app_timer_create(&my_timer, APP_TIMER_MODE_SINGLE_SHOT, aid_call_timeout_handler); //advertise normally after 5 seconds APP_ERROR_CHECK(err_code); err_code=app_timer_create(&fast_my_timer, APP_TIMER_MODE_SINGLE_SHOT, accel_timeout_handler); //advertise normally after 5 seconds APP_ERROR_CHECK(err_code); } /*Function for handling the idle state (main loop). *No pending log operation, then sleep until next the next event occurs. */ static void idle_state_handle(void) { if (NRF_LOG_PROCESS() == false) { nrf_pwr_mgmt_run(); } } /*Button Handler for aided call*/ void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { // printf("accel"); if(aid_flag==false) { aid_flag=true; } } /* Accelerometer handler*/ void fast_advertise(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { //nrf_gpio_pin_set(17); if(accel_flag==false) { accel_flag=true; } } /*@brief Function starting the internal LFCLK oscillator.*/ static void lfclk_request(void) { ret_code_t err_code = nrf_drv_clock_init(); APP_ERROR_CHECK(err_code); nrf_drv_clock_lfclk_request(NULL); } /* Gpio Initialisation*/ static void gpio_init(void) { ret_code_t err_code; err_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(err_code); nrf_drv_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); in_config.pull = NRF_GPIO_PIN_PULLUP; err_code = nrf_drv_gpiote_in_init(NURSE_CALL, &in_config, in_pin_handler); APP_ERROR_CHECK(err_code); err_code = nrf_drv_gpiote_in_init(ACCEL_CALL, &in_config, fast_advertise); APP_ERROR_CHECK(err_code); nrf_drv_gpiote_in_event_enable(NURSE_CALL, true); nrf_drv_gpiote_in_event_enable(ACCEL_CALL, true); } /*I2C initialise*/ void twi_init(void) { ret_code_t err_code; const nrf_drv_twi_config_t twi_lis3dh_config = { .scl = ARDUINO_SCL_PIN, .sda = ARDUINO_SDA_PIN, .frequency = NRF_DRV_TWI_FREQ_100K, .interrupt_priority = APP_IRQ_PRIORITY_HIGH, .clear_bus_init = false }; err_code = nrf_drv_twi_init(&m_twi, &twi_lis3dh_config, NULL, NULL); APP_ERROR_CHECK(err_code); nrf_drv_twi_enable(&m_twi); } void LIS3DH_write(uint8_t addr, uint8_t wdata) { ret_code_t ret; uint8_t tx_data[2] = {addr, wdata}; ret=nrf_drv_twi_tx(&m_twi, LIS3DH_SLAVE_ADDRESS, tx_data, sizeof(tx_data), false); // return ret; } uint8_t LIS3DH_read(uint8_t addr) { ret_code_t ret; static uint8_t receive_data; do { ret = nrf_drv_twi_tx(&m_twi, LIS3DH_SLAVE_ADDRESS, &addr, 1, true); if(NRF_SUCCESS == ret) { // printf("twi\n"); //break; } ret = nrf_drv_twi_rx(&m_twi, LIS3DH_SLAVE_ADDRESS, &receive_data, 1); }while(0); //printf("device:%02X",receive_data); return receive_data; } /*LIS3DH INTIALISE*/ void init_LIS3DH(void) { // configurations for control registers // printf("accel_init\n"); LIS3DH_write(REG_CTRL_REG1, 0x57); // Turn on the sensor with ODR = 10Hz normal mode. // LIS3DH_write(REG_CTRL_REG1, 0x08); LIS3DH_write(REG_CTRL_REG2, 0x01); // High-pass filter (HPF) enabled with 0.2Hz cut-off frequency for INT1 (AOI1) interrupt generation only. LIS3DH_write(REG_CTRL_REG3, 0x40); // ACC AOI1 interrupt signal is routed to INT1 pin. LIS3DH_write(REG_CTRL_REG4, 0x88); // Full Scale = +/-2 g with BDU and HR bits enabled. LIS3DH_write(REG_CTRL_REG5, 0x00); // Default value. Interrupt signals on INT1 pin is not latched. Users don’t need to read the INT1_SRC register to clear the interrupt signal. // configurations for wakeup and motionless detection LIS3DH_write(REG_INT1_THS, 0x08); // Threshold (THS) = 8LSBs * 15.625mg/LSB = 125mg. LIS3DH_write(REG_INT1_DURATION, 0x32); // Duration = 50LSBs * (1/10Hz) = 5s. LIS3DH_write(REG_INT1_CFG, 0x95); // Enable XLIE, YLIE and ZLIE interrupt generation, AND logic. It means that the interrupt will be generated when X and Y and Z axis acceleration is within the ±THS threshold simultaneously. } /*Main Loop */ int main(void) { // Initialize. uint16_t i; // nrf_gpio_cfg_output(17); lfclk_request(); //log_init(); nrf_drv_clock_init(); NRF_POWER->DCDCEN = 1; device_name_get(); timers_init(); power_management_init(); ble_stack_init(); twi_init(); init_LIS3DH(); advertising_init(5000); device_name_get(); gpio_init(); sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, BLE_GAP_TX_POWER_ROLE_ADV, 0); //Set transmission Power // Start execution. advertising_start(); // Enter main loop. for (;;) { idle_state_handle(); LIS3DH_read(0x2E); if(aid_flag==true) // Nurse aided { ret_code_t err_code; err_code = sd_ble_gap_adv_stop(m_adv_handle); device_name_get(); m_beacon_info1[6]=0x03; advertising_init(500); advertising_start(); aid_flag=false; app_timer_start(my_timer, APP_TIMER_TICKS(5000), NULL); } if(accel_flag==true) { ret_code_t err_code; err_code = sd_ble_gap_adv_stop(m_adv_handle); device_name_get(); advertising_init(100); nrf_delay_ms(10); advertising_start(); app_timer_start(fast_my_timer, APP_TIMER_TICKS(5000), NULL); } } } /** * @} */