#include <Wire.h>
#include <nrf.h>
#include <nrf_soc.h>
#include <nrf_delay.h>
#include <nrf_drv_gpiote.h>
#include <nrf_sdh.h>
#include <nrf_sdh_ble.h>
#include <nrf_ble_gatt.h>
#include <nrf_ble_qwr.h>
#include <nrf_ble_scan.h>
#include <nrf_ble_gatt.h>
#include <nrf_ble_scan.h>
#include <nrf_ble_gatt.h>
#include <nrf_ble_qwr.h>
#include <nrf_ble_scan.h>
#include <nrf_log.h>
#include <nrf_log_ctrl.h>
#include <nrf_log_default_backends.h>
#include <nrf_log.h>
// Define your UUIDs for services and characteristics
#define SMART_BATHTUB_SERVICE_UUID 0x1234
#define FALL_DETECTION_CHAR_UUID 0x5678
// Define pin for fall detection sensor
#define FALL_SENSOR_PIN 7
// Function declarations
static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action);
static void services_init(void);
static void characteristic_init(void);
static void advertising_init(void);
static void on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
// Global variables
static ble_gap_adv_params_t m_adv_params;
static ble_gatts_char_handles_t m_fall_char_handles;
static ble_gatts_value_t m_fall_char_value = BLE_GATTS_VALUE_INIT;
static ble_qwr_t m_qwr;
int main(void)
{
ret_code_t err_code;
// Initialize Bluetooth stack
err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK(err_code);
// Initialize Bluetooth SoftDevice
err_code = nrf_sdh_ble_default_cfg_set(1, 1);
APP_ERROR_CHECK(err_code);
err_code = nrf_sdh_ble_enable(&nrf_ble_enable_params);
APP_ERROR_CHECK(err_code);
// Initialize services and characteristics
services_init();
characteristic_init();
// Initialize GPIO for fall detection sensor
nrf_drv_gpiote_init();
nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
in_config.pull = NRF_GPIO_PIN_PULLUP;
err_code = nrf_drv_gpiote_in_init(FALL_SENSOR_PIN, &in_config, gpiote_event_handler);
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_in_event_enable(FALL_SENSOR_PIN, true);
// Initialize advertising
advertising_init();
// Start execution
NRF_LOG_INFO("Smart Bathtub with Fall Detection example started.");
advertising_start();
// Enter main loop
for (;;)
{
// Enter low-power mode
// ...
}
}
static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{ }
static void services_init(void)
{
ret_code_t err_code;
nrf_ble_qwr_init_t qwr_init = {0};
// Initialize Queued Write Module
qwr_init.error_handler = nrf_ble_gatt_error_handler;
err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
APP_ERROR_CHECK(err_code);
}
static void characteristic_init(void)
{
ret_code_t err_code;
ble_uuid_t uuid = {.uuid = SMART_BATHTUB_SERVICE_UUID, .type = BLE_UUID_TYPE_VENDOR_BEGIN};
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, NULL);
APP_ERROR_CHECK(err_code);
memset(&m_fall_char_handles, 0, sizeof(m_fall_char_handles));
memset(&m_fall_char_value, 0, sizeof(m_fall_char_value));
ble_gatts_char_md_t char_md = {0};
char_md.char_props.notify = 1;
char_md.char_props.read = 1;
ble_gatts_attr_md_t cccd_md = {0};
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
ble_gatts_attr_t attr_char_value = {0};
attr_char_value.p_uuid = &uuid;
attr_char_value.p_attr_md = &char_md;
attr_char_value.init_len = sizeof(uint8_t);
attr_char_value.init_offs = 0;
attr_char_value.max_len = sizeof(uint8_t);
attr_char_value.p_value = &m_fall_char_value;
err_code = sd_ble_gatts_characteristic_add(BLE_UUID_FALL_DETECTION_CHAR, &char_md,
&attr_char_value, &m_fall_char_handles);
APP_ERROR_CHECK(err_code);
}
static void advertising_init(void)
{
ret_code_t err_code;
ble_advdata_t advdata;
ble_adv_modes_config_t options = BLE_ADV_OPTIONS_DEFAULT;
// Set advertising data
memset(&advdata, 0, sizeof(advdata));
advdata.name_type = BLE_ADVDATA_FULL_NAME;
advdata.include_appearance = true;
advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
err_code = ble_advertising_init(&advdata, NULL, &options, NULL, NULL);
APP_ERROR_CHECK(err_code);
}
static void on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
// Handle BLE events
// ...
}
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
// Handle errors
// ...
}
Comments