Hi,
I have using nrf52832. I have done the device sleep by using RTC. But, it's not wake up from sleep. How Can I wake up the device from sleep?
I need help regarding this
Thank you,
Hi,
I have using nrf52832. I have done the device sleep by using RTC. But, it's not wake up from sleep. How Can I wake up the device from sleep?
I need help regarding this
Thank you,
HI,
I have to keep on trying to wake up the device. The device woke up also happen. But one time the device woke up from sleep second time that was not happen
please help me with this
Hi,
You should see the RTC example in the SDK, it implements IDLE ON Sleep and wakes up when a new RTC event is generated.
Mr.NCK said:I have to keep on trying to wake up the device. The device woke up also happen. But one time the device woke up from sleep second time that was not happen
I can take a look at your code if you share it.
regards
Jared
#include <stdint.h> #include <string.h> #include <math.h> #include "nordic_common.h" #include "nrf.h" #include "ble_hci.h" #include "ble_advdata.h" #include "ble_advertising.h" #include "ble_conn_params.h" #include "nrf_sdh.h" #include "nrf_sdh_soc.h" #include "nrf_sdh_ble.h" #include "nrf_ble_gatt.h" #include "nrf_ble_qwr.h" #include "app_timer.h" #include "ble_nus.h" #include "app_uart.h" #include "app_util_platform.h" #include "bsp_btn_ble.h" #include "nrf_pwr_mgmt.h" #include "nrf_calendar.h" #include "nrf_delay.h" #include "bsp.h" #include "app_error.h" #if defined(UART_PRESENT) #include "nrf_uart.h" #endif #if defined(UARTE_PRESENT) #include "nrf_uarte.h" #endif #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "nrf_drv_twi.h" #include "app_timer.h" #include "boards.h" #include "nrf_fstorage.h" // added #include "nrf_fstorage_sd.h" //added #include "mpu6050.h" #include "ble_dfu.h" #include "nrf_bootloader_info.h" #include "nrf_dfu_ble_svci_bond_sharing.h" #include "nrf_svci_async_function.h" #include "nrf_svci_async_handler.h" #include "nrf_drv_rtc.h" #include "nrf_drv_clock.h" #include "nrf_gpio.h" #ifdef BSP_LED_0 #define TICK_EVENT_OUTPUT BSP_LED_0 /**< Pin number for indicating tick event. */ #endif #ifndef TICK_EVENT_OUTPUT #error "Please indicate output pin" #endif #ifdef BSP_LED_1 #define COMPARE_EVENT_OUTPUT BSP_LED_1 /**< Pin number for indicating compare event. */ #endif #ifndef COMPARE_EVENT_OUTPUT #error "Please indicate output pin" #endif const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(0); #define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */ #define DEVICE_NAME "kdd_00" /**< Name of device. Will be included in the advertising data. */ #define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */ #define APP_BLE_OBSERVER_PRIO 3 /**< Application's BLE observer priority. You shouldn't need to modify this value. */ #define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */ #define APP_ADV_DURATION 0 /**< The advertising duration (180 seconds) in units of 10 milliseconds. */ #define MIN_CONN_INTERVAL MSEC_TO_UNITS(9, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */ #define MAX_CONN_INTERVAL MSEC_TO_UNITS(9, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */ #define SLAVE_LATENCY 0 /**< Slave latency. */ #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */ #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */ #define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */ #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ #define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */ #define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ #define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */ BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT); /**< BLE NUS service instance. */ NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */ NRF_BLE_QWR_DEF(m_qwr); /**< Context for the Queued Write module.*/ BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */ static bool run_time_updates = false; /* MPU-6050 I2C-ADDRESS */ #define MPU_6050_I2C_ADDR 0x68 /* MPU-6050 Register Map */ #define WHO_AM_I 0x75 #define ACCEL_XOUT_H 0x3B #define TEMP_OUT_H 0x41 #define GYRO_XOUT_H 0x43 #define PWR_MGMT_1 0x6B //#define MAX_LEN 510 /* TWI instance. */ static const nrf_drv_twi_t m_twi_mpu_6050 = NRF_DRV_TWI_INSTANCE(0); //added static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ static uint16_t m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3; /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */ { {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}}; static ble_advdata_manuf_data_t m_manuf_advdata; static float tm, start_time, current_time, milli2; static int millik; static uint32_t write_time_interval, write_sleep_time; static int configuration_set = 10; uint32_t length, length1,length2, mil_length; static int16_t AccValue[3]; float accel[3], accel2[3]; char accelerometer_data[30]; char str[40]; char buf[40]; char *array[15]; int read_data_counter1, read_data_counter2, read_data_counter3; uint32_t year, month, day, hour, minute, second, set; int time_counter; static bool motion_flag = 0; static uint8_t connected_flag = 0; static bool disconnected_flag = 0; char timestamp_data[25],timestamp1[25],timesync[25]; static uint8_t flag; // creating a structure char *get_mpu6050_data; // creating a structure struct sensor_data { char xyz_data[23]; //int sensor_value; }; struct sensor_data sensordata_array1[450]; struct sensor_data sensordata_array2[450]; struct sensor_data sensordata_array3[450]; static bool connected = 0; APP_TIMER_DEF(m_led_a_timer_id); //ADDED // Added for advertising (fake) temperature data regularly ----- #define COMPANY_IDENTIFIER 0x0059 // Nordic company ID. #define TEMP_UPDATE_INTERVAL APP_TIMER_TICKS(5000) // 5 seconds temperature update interval static ble_advdata_t m_advdata; static ble_advdata_t m_srdata; static void ble_dfu_buttonless_evt_handler(ble_dfu_buttonless_evt_type_t event) { switch (event) { case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE: NRF_LOG_INFO("Device is preparing to enter bootloader mode\r\n"); break; case BLE_DFU_EVT_BOOTLOADER_ENTER: NRF_LOG_INFO("Device will enter bootloader mode\r\n"); break; case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED: NRF_LOG_ERROR("Device failed to enter bootloader mode\r\n"); break; default: NRF_LOG_INFO("Unknown event from ble_dfu.\r\n"); break; } } static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event) { switch (event) { case NRF_PWR_MGMT_EVT_PREPARE_DFU: NRF_LOG_INFO("Power management wants to reset to DFU mode\r\n"); // Change this code to tailor to your reset strategy. // Returning false here means that the device is not ready // to jump to DFU mode yet. // // Here is an example using a variable to delay resetting the device: // /* if (!im_ready_for_reset) return false; } */ break; default: // Implement any of the other events available // from the power management module: // -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF // -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP // -NRF_PWR_MGMT_EVT_PREPARE_RESET return true; } NRF_LOG_INFO("Power management allowed to reset to DFU mode\r\n"); return true; } ///////////////fs strorage/// static void fstorage_evt_handler(nrf_fstorage_evt_t *p_evt); NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) = { /* Set a handler for fstorage events. */ .evt_handler = fstorage_evt_handler, /* These below are the boundaries of the flash space assigned to this instance of fstorage. * You must set these manually, even at runtime, before nrf_fstorage_init() is called. * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the * last page of flash available to write data. */ .start_addr = 0x3c000, .end_addr = 0x3ffff, }; // char m_depth[80]; char axis[40]; char ble_name[20], ble_time[20], ble_sleep[20]; char milli[30]; uint8_t x = 0; int i; /**@brief Function for assert macro callback. * * @details This function will be called in case of an assert in the SoftDevice. * * @warning This handler is an example only and does not fit a final product. You need to analyse * how your product is supposed to react in case of Assert. * @warning On assert from the SoftDevice, the system can only recover on reset. * * @param[in] line_num Line number of the failing ASSERT call. * @param[in] p_file_name File name of the failing ASSERT call. */ void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) { app_error_handler(DEAD_BEEF, line_num, p_file_name); } /**@brief Function for initializing the timer module. */ static void timers_init(void) { ret_code_t err_code = app_timer_init(); APP_ERROR_CHECK(err_code); } /**@brief Function for the GAP initialization. * * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of * the device. It also sets the permissions and appearance. */ static void gap_params_init(char device_name[10]) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; //static char DEVICE_NAME[10]="praveen"; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (uint8_t *)device_name, strlen(device_name)); NRF_LOG_INFO("device2 :%s\n", device_name); APP_ERROR_CHECK(err_code); //memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); } /**@brief Function for handling Queued Write Module errors. * * @details A pointer to this function will be passed to each service which may need to inform the * application about an error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void nrf_qwr_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); } /**@brief Function for handling advertising errors. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void ble_advertising_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); } /**@brief Function for handling the data from the Nordic UART Service. * * @details This function will process the data received from the Nordic UART BLE Service and send * it to the UART module. * * @param[in] p_evt Nordic UART Service event. */ /**@snippet [Handling the data received over BLE] */ static void nus_data_handler(ble_nus_evt_t *p_evt) { int stop_parse = 0; if (p_evt->type == BLE_NUS_EVT_RX_DATA) { uint32_t err_code; NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART."); NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length); for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++) { str[i] = p_evt->params.rx_data.p_data[i]; } NRF_LOG_INFO("%s\n", str); if (stop_parse == 0) { strcpy(buf, str); uint8_t j = 0; char *pch = strtok(buf, "$"); while (pch != NULL) { array[j] = pch; j = j + 1; pch = strtok(NULL, ","); } strcpy(axis, array[0]); NRF_LOG_INFO("parsed string is %s and copied string is %s\n", array[0], axis); stop_parse = 1; } do { err_code = app_uart_put(p_evt->params.rx_data.p_data[i]); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) { NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code); APP_ERROR_CHECK(err_code); } } while (err_code == NRF_ERROR_BUSY); if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r') { while (app_uart_put('\n') == NRF_ERROR_BUSY) ; } } } /**@snippet [Handling the data received over BLE] */ /**@brief Function for initializing services that will be used by the application. */ static void services_init(void) { uint32_t err_code; ble_nus_init_t nus_init; nrf_ble_qwr_init_t qwr_init = {0}; // Initialize Queued Write Module. qwr_init.error_handler = nrf_qwr_error_handler; err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init); APP_ERROR_CHECK(err_code); // Initialize NUS (Nordic UART Service) memset(&nus_init, 0, sizeof(nus_init)); nus_init.data_handler = nus_data_handler; err_code = ble_nus_init(&m_nus, &nus_init); APP_ERROR_CHECK(err_code); // BEGIN Block Added for DFU // ONLY ADD THIS BLOCK TO THE EXISTING FUNCTION // Initialize the DFU service ble_dfu_buttonless_init_t dfus_init = { .evt_handler = ble_dfu_buttonless_evt_handler }; err_code = ble_dfu_buttonless_init(&dfus_init); APP_ERROR_CHECK(err_code); // END Block Added for DFU } /**@brief Function for handling an event from the Connection Parameters Module. * * @details This function will be called for all events in the Connection Parameters Module * which are passed to the application. * * @note All this function does is to disconnect. This could have been done by simply setting * the disconnect_on_fail config parameter, but instead we use the event handler * mechanism to demonstrate its use. * * @param[in] p_evt Event received from the Connection Parameters Module. */ static void on_conn_params_evt(ble_conn_params_evt_t *p_evt) { uint32_t err_code; if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); APP_ERROR_CHECK(err_code); } } /**@brief Function for handling errors from the Connection Parameters module. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); } /**@brief Function for initializing the Connection Parameters module. */ static void conn_params_init(void) { uint32_t err_code; ble_conn_params_init_t cp_init; memset(&cp_init, 0, sizeof(cp_init)); cp_init.p_conn_params = NULL; cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; cp_init.disconnect_on_fail = false; cp_init.evt_handler = on_conn_params_evt; cp_init.error_handler = conn_params_error_handler; err_code = ble_conn_params_init(&cp_init); APP_ERROR_CHECK(err_code); } /**@brief Function for putting the chip into sleep mode. * * @note This function will not return. */ static void sleep_mode_enter(void) { uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // Prepare wakeup buttons. err_code = bsp_btn_ble_sleep_mode_prepare(); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } /**@brief Function for handling advertising events. * * @details This function will be called for advertising events which are passed to the application. * * @param[in] ble_adv_evt Advertising event. */ static void on_adv_evt(ble_adv_evt_t ble_adv_evt) { uint32_t err_code; switch (ble_adv_evt) { case BLE_ADV_EVT_FAST: err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); APP_ERROR_CHECK(err_code); break; case BLE_ADV_EVT_IDLE: sleep_mode_enter(); break; default: break; } } /**@brief Function for handling BLE events. * * @param[in] p_ble_evt Bluetooth stack event. * @param[in] p_context Unused. */ static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: NRF_LOG_INFO("Connected"); err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle); APP_ERROR_CHECK(err_code); connected = 1; connected_flag = 1; break; case BLE_GAP_EVT_DISCONNECTED: NRF_LOG_INFO("Disconnected"); // LED indication will be changed when advertising starts. m_conn_handle = BLE_CONN_HANDLE_INVALID; break; case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { NRF_LOG_DEBUG("PHY update request."); ble_gap_phys_t const phys = { .rx_phys = BLE_GAP_PHY_AUTO, .tx_phys = BLE_GAP_PHY_AUTO, }; err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: // Pairing not supported err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have been stored. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GATTC_EVT_TIMEOUT: // Disconnect on GATT Client timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; default: // No implementation needed. break; } } /**@brief Function for the SoftDevice initialization. * * @details This function initializes the SoftDevice and the BLE event interrupt. */ 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 using the default settings. // 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); // Register a handler for BLE events. NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL); } /**@brief Function for handling events from the GATT library. */ void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt) { if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) { m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH; NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len); } NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x", p_gatt->att_mtu_desired_central, p_gatt->att_mtu_desired_periph); } /**@brief Function for initializing the GATT library. */ void gatt_init(void) { ret_code_t err_code; err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler); APP_ERROR_CHECK(err_code); err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE); APP_ERROR_CHECK(err_code); } /**@brief Function for handling events from the BSP module. * * @param[in] event Event generated by button press. */ void bsp_event_handler(bsp_event_t event) { uint32_t err_code; switch (event) { case BSP_EVENT_SLEEP: sleep_mode_enter(); break; case BSP_EVENT_DISCONNECT: err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } break; case BSP_EVENT_WHITELIST_OFF: if (m_conn_handle == BLE_CONN_HANDLE_INVALID) { err_code = ble_advertising_restart_without_whitelist(&m_advertising); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } } break; default: break; } } /**@brief Function for handling app_uart events. * * @details This function will receive a single character from the app_uart module and append it to * a string. The string will be be sent over BLE when the last character received was a * 'new line' '\n' (hex 0x0A) or if the string has reached the maximum data length. */ /**@snippet [Handling the data received over UART] */ void uart_event_handle(app_uart_evt_t *p_event) { static uint8_t data_array[BLE_NUS_MAX_DATA_LEN]; static uint8_t index = 0; uint32_t err_code; switch (p_event->evt_type) { case APP_UART_DATA_READY: UNUSED_VARIABLE(app_uart_get(&data_array[index])); index++; if ((data_array[index - 1] == '\n') || (data_array[index - 1] == '\r') || (index >= m_ble_nus_max_data_len)) { if (index > 1) { NRF_LOG_DEBUG("Ready to send data over BLE NUS"); NRF_LOG_HEXDUMP_DEBUG(data_array, index); do { uint16_t length = (uint16_t)index; err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle); if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_RESOURCES) && (err_code != NRF_ERROR_NOT_FOUND)) { APP_ERROR_CHECK(err_code); } } while (err_code == NRF_ERROR_RESOURCES); } index = 0; } break; /* case APP_UART_COMMUNICATION_ERROR: APP_ERROR_HANDLER(p_event->data.error_communication); break;*/ case APP_UART_FIFO_ERROR: APP_ERROR_HANDLER(p_event->data.error_code); break; default: break; } } /**@snippet [Handling the data received over UART] */ /**@brief Function for initializing the UART module. */ /**@snippet [UART Initialization] */ static void uart_init(void) { uint32_t err_code; app_uart_comm_params_t const comm_params = { .rx_pin_no = RX_PIN_NUMBER, .tx_pin_no = TX_PIN_NUMBER, .rts_pin_no = RTS_PIN_NUMBER, .cts_pin_no = CTS_PIN_NUMBER, .flow_control = APP_UART_FLOW_CONTROL_DISABLED, .use_parity = false, #if defined(UART_PRESENT) .baud_rate = NRF_UART_BAUDRATE_115200 #else .baud_rate = NRF_UARTE_BAUDRATE_115200 #endif }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_event_handle, APP_IRQ_PRIORITY_LOWEST, err_code); APP_ERROR_CHECK(err_code); } static void advertising_init(void) { uint32_t err_code; uint8_t adv_flags; ble_advertising_init_t init; m_manuf_advdata.company_identifier = COMPANY_IDENTIFIER; m_manuf_advdata.data.p_data = &flag; m_manuf_advdata.data.size = 1; memset(&init, 0, sizeof(init)); // Advertising data adv_flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; init.advdata.name_type = BLE_ADVDATA_FULL_NAME; init.advdata.include_appearance = true; init.advdata.flags = adv_flags; init.advdata.p_manuf_specific_data = &m_manuf_advdata; // Scan response data init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); init.srdata.uuids_complete.p_uuids = m_adv_uuids; // Copy Adv data and SR data to static buffers to be used when data is to be updated memcpy(&m_advdata, &init.advdata, sizeof(m_advdata)); memcpy(&m_srdata, &init.srdata, sizeof(m_srdata)); // Configure advertising parameters and advertising module init.config.ble_adv_fast_enabled = true; init.config.ble_adv_directed_high_duty_enabled = false; init.config.ble_adv_directed_enabled = false; init.config.ble_adv_directed_interval = 0; init.config.ble_adv_directed_timeout = 0; init.config.ble_adv_fast_interval = APP_ADV_INTERVAL; init.config.ble_adv_fast_timeout = APP_ADV_DURATION; init.evt_handler = on_adv_evt; init.error_handler = ble_advertising_error_handler; err_code = ble_advertising_init(&m_advertising, &init); APP_ERROR_CHECK(err_code); ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG); } /**@brief Function for initializing buttons and leds. * * @param[out] p_erase_bonds Will be true if the clear bonding button was pressed to wake the application up. */ static void buttons_leds_init(bool *p_erase_bonds) { bsp_event_t startup_event; uint32_t err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler); APP_ERROR_CHECK(err_code); err_code = bsp_btn_ble_init(NULL, &startup_event); APP_ERROR_CHECK(err_code); *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA); } /** @brief: Function for handling the RTC0 interrupts. * Triggered on TICK and COMPARE0 match. */ static void rtc_handler(nrf_drv_rtc_int_type_t int_type) { if (int_type == NRF_DRV_RTC_INT_COMPARE0) { nrf_gpio_pin_toggle(COMPARE_EVENT_OUTPUT); } else if (int_type == NRF_DRV_RTC_INT_TICK) { nrf_gpio_pin_toggle(TICK_EVENT_OUTPUT); } } static void lfclk_config(void) { ret_code_t err_code = nrf_drv_clock_init(); APP_ERROR_CHECK(err_code); nrf_drv_clock_lfclk_request(NULL); } /** @brief Function initialization and configuration of RTC driver instance. */ static int rtc_config(uint32_t time) { uint32_t err_code; //Initialize RTC instance nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG; config.prescaler = 4095; err_code = nrf_drv_rtc_init(&rtc, &config, rtc_handler); APP_ERROR_CHECK(err_code); //Enable tick event & interrupt nrf_drv_rtc_tick_enable(&rtc,true); //Set compare channel to trigger interrupt after COMPARE_COUNTERTIME seconds err_code = nrf_drv_rtc_cc_set(&rtc,0,time* 8,true); APP_ERROR_CHECK(err_code); //Power on RTC instance nrf_drv_rtc_enable(&rtc); } /**@brief Function for initializing the nrf log module. */ static void log_init(void) { ret_code_t err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); } /**@brief Function for 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); } /**@brief Function for handling the idle state (main loop). * * @details If there is 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(); } } /**@brief Function for starting advertising. */ static void advertising_start(void) { uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); } //void mpu_6050_read_acc(int16_t *p_x_val, int16_t *p_y_val, int16_t *p_z_val) //char *mpu6050_data() void mpu6050_data() { if (MPU6050_ReadAcc(&AccValue[0], &AccValue[1], &AccValue[2]) == true) // Read acc value from mpu6050 internal registers and save them in the array { // printf("ACC Values: x = %d y = %d z = %d\n", AccValue[0], AccValue[1], AccValue[2]); // display the read values accel[0] = ((float)AccValue[0]) / 2048; accel[1] = ((float)AccValue[1]) / 2048; accel[2] = ((float)AccValue[2]) / 2048; // printf("ACCEl Values: x = %.2f y = %.2f z = %.2f\n", accel[0], accel[1], accel[2]); accel2[0] = accel[0] * 9.80665; accel2[1] = accel[1] * 9.80665; accel2[2] = accel[2] * 9.80665; // printf("ACCELERATION Values: x = %.2f y = %.2f z = %.2f\n", accel2[0], accel2[1], accel2[2]); } sprintf(accelerometer_data, "%.2f,%.2f,%.2f", accel2[0], accel2[1], accel2[2]); } //FStorage// static uint32_t nrf5_flash_end_addr_get() { uint32_t const bootloader_addr = BOOTLOADER_ADDRESS; uint32_t const page_sz = NRF_FICR->CODEPAGESIZE; uint32_t const code_sz = NRF_FICR->CODESIZE; return (bootloader_addr != 0xFFFFFFFF ? bootloader_addr : (code_sz * page_sz)); } static void fstorage_evt_handler(nrf_fstorage_evt_t *p_evt) { if (p_evt->result != NRF_SUCCESS) { NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation."); return; } switch (p_evt->id) { case NRF_FSTORAGE_EVT_WRITE_RESULT: { NRF_LOG_INFO("--> Event received: wrote %d bytes at address 0x%x.", p_evt->len, p_evt->addr); } break; case NRF_FSTORAGE_EVT_ERASE_RESULT: { NRF_LOG_INFO("--> Event received: erased %d page from address 0x%x.", p_evt->len, p_evt->addr); } break; default: break; } } static void print_flash_info(nrf_fstorage_t *p_fstorage) { NRF_LOG_INFO("========| flash info |========"); NRF_LOG_INFO("erase unit: \t%d bytes", p_fstorage->p_flash_info->erase_unit); NRF_LOG_INFO("program unit: \t%d bytes", p_fstorage->p_flash_info->program_unit); NRF_LOG_INFO("=============================="); } void wait_for_flash_ready(nrf_fstorage_t const *p_fstorage) { /* While fstorage is busy, sleep and wait for an event. */ while (nrf_fstorage_is_busy(p_fstorage)) { // power_manage(); } } /**@brief Application main function. */ int main(void) { bool erase_bonds; int MAX_LEN = 320; static uint32_t sleep_time; //=10000; static uint32_t time_interval; //=10; /////////////////////////////////////////////////////////////////////////////// NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); ret_code_t err_code; nrf_cal_init(); nrf_cal_set_callback(0, 1); int writen_flag = 0; int time_counter = 0; ret_code_t rc; static char m_depth[20], t_depth[10], s_depth[10],TS_depth[25]; nrf_fstorage_api_t *p_fs_api; p_fs_api = &nrf_fstorage_sd; rc = nrf_fstorage_init(&fstorage, p_fs_api, NULL); APP_ERROR_CHECK(rc); print_flash_info(&fstorage); (void)nrf5_flash_end_addr_get(); uart_init(); nrf_delay_ms(3000); rc = nrf_fstorage_read(&fstorage, 0x3d000, m_depth, sizeof(m_depth)); APP_ERROR_CHECK(rc); if (rc == NRF_SUCCESS) { NRF_LOG_INFO("read from flash:%s\n", m_depth); } if (m_depth[0] != 'k' && m_depth[1] != 'd' && m_depth[2] != 'd' && m_depth[3] != '_') { m_depth[0] = 'k'; m_depth[1] = 'd'; m_depth[2] = 'd'; m_depth[3] = '-'; m_depth[4] = '1'; m_depth[5] = '\0'; } log_init(); timers_init(); buttons_leds_init(&erase_bonds); power_management_init(); ble_stack_init(); gap_params_init(&m_depth); gatt_init(); services_init(); advertising_init(); conn_params_init(); twi_master_init(); mpu6050_init(); advertising_start(); uint8_t device_id; NRF_LOG_INFO("ble status : %d\n", connected_flag); // Read Device ID // mpu6050_verify_product_id(&device_id); while (connected_flag == 0) { time_counter++; NRF_LOG_INFO("ble not connected\n"); nrf_delay_ms(1000); if (time_counter == 25) { NRF_LOG_INFO("Timed Out\n"); break; } } NRF_LOG_INFO("ble status outside wait loop : %d\n", connected_flag); nrf_delay_ms(2000); // parse axis into 3 configurations while (connected_flag == 1 && writen_flag == 0) { NRF_LOG_INFO("ble status -- %d\n", connected_flag); nrf_delay_ms(2000); if (array[0] != '\0') { char *token = strtok(axis, ","); int token_counter = 1; // Keep printing tokens while one of the // delimiters present in axis. while (token != NULL) { array[token_counter] = token; NRF_LOG_INFO("token Number %d is %s\n", token_counter, token); token_counter++; token = strtok(NULL, ","); } strcpy(ble_name, array[1]); NRF_LOG_INFO("ble name is %s\n", ble_name); // write_time_interval = atoi(array[2]); strcpy(ble_time, array[2]); length1 = sprintf("%s", ble_time); NRF_LOG_INFO("write time interval is name is %s\n", ble_time); // write_sleep_time = atoi(array[3]); strcpy(ble_sleep, array[3]); NRF_LOG_INFO("sleep time interval is name is %s\n", ble_sleep); year = atoi(array[4]); month = atoi(array[5]); day = atoi(array[6]); hour = atoi(array[7]); minute = atoi(array[8]); second = atoi(array[9]); set = atoi(array[10]); nrf_cal_set_time(year, month, day, hour, minute, second); if (writen_flag == 0) { rc = nrf_fstorage_erase(&fstorage, 0x3d000, 1, NULL); rc = nrf_fstorage_erase(&fstorage, 0x3e000, 1, NULL); rc = nrf_fstorage_erase(&fstorage, 0x3f000, 1, NULL); APP_ERROR_CHECK(rc); if (rc == NRF_SUCCESS) { NRF_LOG_INFO("erased from flash\n"); } rc = nrf_fstorage_write(&fstorage, 0x3d000, &ble_name, sizeof(ble_name), NULL); nrf_delay_ms(1000); rc = nrf_fstorage_write(&fstorage, 0x3e000, &ble_time, sizeof(ble_time), NULL); nrf_delay_ms(1000); rc = nrf_fstorage_write(&fstorage, 0x3f000, &ble_sleep, sizeof(ble_sleep), NULL); nrf_delay_ms(1000); writen_flag = 1; memset(array, '\0', sizeof(array)); } APP_ERROR_CHECK(rc); if (rc == NRF_SUCCESS) { NRF_LOG_INFO("Device Name : write data to flash :%s\n", ble_name); NRF_LOG_INFO("Sensor Data Read Interval : write data to flash :%s\n", ble_time); NRF_LOG_INFO("Waiting Time Interval : write data to flash :%s\n", ble_sleep); } wait_for_flash_ready(&fstorage); NRF_LOG_INFO("Done."); nrf_delay_ms(2000); } } /////////////////////Read//////////////////////// nrf_delay_ms(1000); rc = nrf_fstorage_read(&fstorage, 0x3d000, m_depth, sizeof(m_depth)); APP_ERROR_CHECK(rc); if (rc == NRF_SUCCESS) { NRF_LOG_INFO("read from flash Device Name :%s\n", m_depth); } nrf_delay_ms(1000); rc = nrf_fstorage_read(&fstorage, 0x3e000, t_depth, sizeof(t_depth)); APP_ERROR_CHECK(rc); if (rc == NRF_SUCCESS) { NRF_LOG_INFO("read from flash Time Interval:%s\n", t_depth); } nrf_delay_ms(1000); rc = nrf_fstorage_read(&fstorage, 0x3f000, s_depth, sizeof(s_depth)); APP_ERROR_CHECK(rc); if (rc == NRF_SUCCESS) { NRF_LOG_INFO("read from flash Sleep Time :%s\n", s_depth); } time_interval = atoi(t_depth); NRF_LOG_INFO("write_time_interval:%d\n", time_interval); if (time_interval >= 10 && time_interval <= 1000) { MAX_LEN = 4500 / time_interval; // Ensure AAPP sends between 10 and 1000 ms, should divided by 10 NRF_LOG_INFO("MAX LENGTH :%d\n", MAX_LEN); } else { NRF_LOG_INFO("write_time_interval os out of boundar\n"); } sleep_time = atoi(s_depth); NRF_LOG_INFO("write_sleep_time:%d\n", sleep_time); //////////////Infinite Sensor Reading ///////////////// while (1) { int set2 = 1; ret_code_t err_code; mpu6050_data(); float g = sqrt(((accel2[0]) * (accel2[0])) + ((accel2[1]) * (accel2[1])) + ((accel2[2]) * (accel2[2]))) / 9.8; //float g = sqrt(4) ; NRF_LOG_INFO("G=%f\n", g); if (g >= 1.05) { time_counter++; NRF_LOG_INFO("flag"); nrf_delay_ms(10); } else { time_counter = 0; } if (time_counter == 5) { motion_flag = 1; NRF_LOG_INFO("flag raised"); } if (motion_flag == 1) { NRF_LOG_INFO("started storing"); nrf_gpio_pin_toggle(12); for (read_data_counter1 = 0; read_data_counter1 < MAX_LEN; read_data_counter1++) { int a = 0; sprintf(timestamp_data, "%s", nrf_cal_get_time_string(true)); sprintf(timestamp1, "%s", timestamp_data); NRF_LOG_INFO("timestamp :%s\n", timestamp_data); char *arr2[4]; char *p = strtok(timestamp_data, ":"); while (p != NULL) { arr2[a++] = p; p = strtok(NULL, ":"); } strcpy(milli, arr2[2]); NRF_LOG_INFO("\n Milli2 = %s", milli); tm = atof(milli); if (set2 == 1) { start_time = tm; set2 = 0; } current_time = tm; milli2 = current_time - start_time; millik = milli2 * 1000; NRF_LOG_INFO("\n Milli result = %d", millik); sprintf(milli, "%d", millik); NRF_LOG_INFO("\n Milli222 = %s", milli); char ch = ','; mil_length = strlen(milli); strncat(milli, &ch, 1); NRF_LOG_INFO("\n %s\n", milli); mpu6050_data(); // milli[mil_length+2]='\0'; strcat(milli, accelerometer_data); NRF_LOG_INFO("\n Milli = %s", milli); get_mpu6050_data = milli; NRF_LOG_INFO("\n Milli cat = %s", get_mpu6050_data); strcpy(sensordata_array1[read_data_counter1].xyz_data, get_mpu6050_data); nrf_delay_ms(time_interval); } for (read_data_counter2 = 0; read_data_counter2 < MAX_LEN; read_data_counter2++) { int a = 0; sprintf(timestamp_data, "%s", nrf_cal_get_time_string(true)); NRF_LOG_INFO("timestamp :%s\n", timestamp_data); char *arr2[4]; char *p = strtok(timestamp_data, ":"); while (p != NULL) { arr2[a++] = p; p = strtok(NULL, ":"); } strcpy(milli, arr2[2]); NRF_LOG_INFO("\n Milli2 = %s", milli); tm = atof(milli); current_time = tm; NRF_LOG_INFO("Start time : %f", start_time); milli2 = current_time - start_time; millik = milli2 * 1000; NRF_LOG_INFO("\n Milli result = %d", millik); sprintf(milli, "%d", millik); NRF_LOG_INFO("\n Milli222 = %s", milli); char ch = ','; mil_length = strlen(milli); strncat(milli, &ch, 1); NRF_LOG_INFO("\n %s\n", milli); mpu6050_data(); strcat(milli, accelerometer_data); get_mpu6050_data = milli; strcpy(sensordata_array2[read_data_counter2].xyz_data, get_mpu6050_data); nrf_delay_ms(time_interval); } for (read_data_counter3 = 0; read_data_counter3 < MAX_LEN; read_data_counter3++) { int a = 0; sprintf(timestamp_data, "%s", nrf_cal_get_time_string(true)); NRF_LOG_INFO("timestamp :%s\n", timestamp_data); char *arr2[4]; char *p = strtok(timestamp_data, ":"); while (p != NULL) { arr2[a++] = p; p = strtok(NULL, ":"); } strcpy(milli, arr2[2]); NRF_LOG_INFO("\n Milli2 = %s", milli); tm = atof(milli); current_time = tm; milli2 = current_time - start_time; millik = milli2 * 1000; NRF_LOG_INFO("\n Milli result = %d", millik); sprintf(milli, "%d", millik); NRF_LOG_INFO("\n Milli222 = %s", milli); char ch = ','; mil_length = strlen(milli); strncat(milli, &ch, 1); NRF_LOG_INFO("\n %s\n", milli); mpu6050_data(); strcat(milli, accelerometer_data); get_mpu6050_data = milli; strcpy(sensordata_array3[read_data_counter3].xyz_data, get_mpu6050_data); nrf_delay_ms(time_interval); } NRF_LOG_INFO("completed storing\n"); NRF_LOG_INFO("FLAG ON\n"); flag = 1; err_code = ble_advertising_advdata_update(&m_advertising, &m_advdata, &m_srdata); APP_ERROR_CHECK(err_code); nrf_delay_ms(2000); while (connected == 0) { nrf_delay_ms(2000); } if (connected == 1) { nrf_delay_ms(1000); NRF_LOG_INFO("%s", t_depth); length1 = sprintf("%s", t_depth); ble_nus_data_send(&m_nus, t_depth, &length1, m_conn_handle); nrf_delay_ms(1000); NRF_LOG_INFO("%s", timestamp1); length2 = sizeof(timestamp1); ble_nus_data_send(&m_nus, timestamp1, &length2, m_conn_handle); for (read_data_counter1 = 0; read_data_counter1 < MAX_LEN; read_data_counter1++) { nrf_delay_ms(20); //printf("xyz:%s\n", sensordata_array1[read_data_counter1].xyz_data); //printf("hello"); length = sizeof(sensordata_array1[read_data_counter1].xyz_data); ble_nus_data_send(&m_nus, sensordata_array1[read_data_counter1].xyz_data, &length, m_conn_handle); } for (read_data_counter2 = 0; read_data_counter2 < MAX_LEN; read_data_counter2++) { nrf_delay_ms(20); //printf("xyz:%s\n", sensordata_array2[read_data_counter2].xyz_data); //printf("hello"); length = sizeof(sensordata_array2[read_data_counter2].xyz_data); ble_nus_data_send(&m_nus, sensordata_array2[read_data_counter2].xyz_data, &length, m_conn_handle); } for (read_data_counter3 = 0; read_data_counter3 < MAX_LEN; read_data_counter3++) { nrf_delay_ms(20); //printf("xyz:%s\n",sensordata_array3[read_data_counter3].xyz_data); //printf("hello"); length = sizeof(sensordata_array3[read_data_counter3].xyz_data); ble_nus_data_send(&m_nus, sensordata_array3[read_data_counter3].xyz_data, &length, m_conn_handle); } ble_nus_data_send(&m_nus, "stop", 25, m_conn_handle); motion_flag = 0; time_counter = 0; flag = 0; err_code = ble_advertising_advdata_update(&m_advertising, &m_advdata, &m_srdata); APP_ERROR_CHECK(err_code); NRF_LOG_INFO("Flag off"); nrf_delay_ms(500); lfclk_config(); rtc_config(sleep_time); idle_state_handle(); } //connected flag closes memset(sensordata_array1, 0, sizeof(sensordata_array1)); memset(sensordata_array2, 0, sizeof(sensordata_array2)); memset(sensordata_array3, 0, sizeof(sensordata_array3)); memset(milli, 0, sizeof(milli)); set2 = 0; } //if nrf_gpio_pin_toggle(19); } } //main /** * @} */
Hi,
It's very difficult for an external to review your code as it's not organized. My guess is your application is asserting somewhere the second time it goes to sleep. Try to debug your application and see if it hits the error handler at some point.
regards
Jared
Hi Jarod
https://devzone.nordicsemi.com/f/nordic-q-a/44846/nrf52832-system-on-sleep-from-rtc
This is what I am trying to do. But, I need to do Sleep for a specific time. That time can be configured at any time
please help me with this
Thank you
Hi again,
Could you use the debugger and verify that the example enters sleep the second time? If not, then it's probably hitting an error handler.
regards
Jared
Yes, your points are correct because of my calendar module RTC. I can't able to initialize the Sleep time RTC instance. That's why it's creating the issues
Yes, your points are correct because of my calendar module RTC. I can't able to initialize the Sleep time RTC instance. That's why it's creating the issues
So before you go to sleep a second time you try to re-initialize the module?