iot4c
Published © GPL3+

Bluetooth LE water leak detector

If not any room where water cranes are placed in a home, has signal wires for water leak detectors

IntermediateShowcase (no instructions)2 hours275
Bluetooth LE water leak detector

Things used in this project

Story

Read more

Schematics

04_V1Ofio1VO9.png

05_zfiCkWzTgw.png

Code

main.c

C/C++
For use with pca10056 NRF52840 SDK
/***************************************************************************************/
/*
 * The beacons detector,
 * based on Manuel Montenegro's 2018 beacon_scanner.
 * Is for switch on a payload (a relay) once if some BT device being detected.
*/
/***************************************************************************************/
/*
 * beacon_scanner
 * Created by Manuel Montenegro, Sep 7, 2018.
 *
 *  This is a Bluetooth 5 scanner. This code reads every advertisement from beacons
 *  and sends its data through serial port.
 *
 *  This code has been developed for Nordic Semiconductor nRF52840 PDK.
*/
/***************************************************************************************/

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "nrf_sdm.h"
#include "ble.h"
#include "ble_hci.h"
#include "ble_db_discovery.h"
#include "ble_srv_common.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "nrf_sdh_soc.h"
#include "nrf_pwr_mgmt.h"
#include "app_util.h"
#include "app_error.h"
#include "ble_dis_c.h"
#include "ble_rscs_c.h"
#include "app_util.h"
#include "app_timer.h"
#include "bsp_btn_ble.h"
#include "peer_manager.h"
#include "peer_manager_handler.h"
#include "fds.h"
#include "nrf_fstorage.h"
#include "ble_conn_state.h"
#include "nrf_ble_gatt.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_ble_scan.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

// UUIDs of BT devices for detect -----------------------------------------------------------------------------------
uint8_t g_UUID1[] = {0x88, 0x3E, 0x92, 0xF5, 0xC8, 0x5A, 0x45, 0x54, 0x85, 0x67, 0x55, 0xF3, 0x0B, 0x0F, 0xB1, 0xC7};
uint8_t g_UUID2[] = {0x74, 0x27, 0x8b, 0xda, 0xb6, 0x44, 0x45, 0x20, 0x8f, 0x0c, 0x72, 0x0e, 0xaf, 0x05, 0x99, 0x35};
// ------------------------------------------------------------------------------------------------------------------

uint32_t g_counter;

#define APP_BLE_CONN_CFG_TAG        1						/**< Tag that identifies the BLE configuration of the SoftDevice. */
#define APP_BLE_OBSERVER_PRIO       3						/**< BLE observer priority of the application. There is no need to modify this value. */
#define APP_SOC_OBSERVER_PRIO       1						/**< SoC observer priority of the application. There is no need to modify this value. */

#define SCAN_INTERVAL               0x0320					/**< Determines scan interval in units of 0.625 millisecond. */
#define SCAN_WINDOW                 0x0320					/**< Determines scan window in units of 0.625 millisecond. */
#define SCAN_DURATION           	0x0000					/**< Duration of the scanning in units of 10 milliseconds. If set to 0x0000, scanning continues until it is explicitly disabled. */

NRF_BLE_SCAN_DEF(m_scan);									/**< Scanning Module instance. */

static bool m_memory_access_in_progress;					/**< Flag to keep track of ongoing operations on persistent memory. */

static ble_gap_scan_params_t m_scan_param =					/**< Scan parameters requested for scanning and connection. */
{
    .active        = 0x00,
    .interval      = SCAN_INTERVAL,
    .window        = SCAN_WINDOW,
    .filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
    .timeout       = SCAN_DURATION,
//    .scan_phys     = BLE_GAP_PHY_CODED,					// Choose only one of the following scan_phys
    .scan_phys     = BLE_GAP_PHY_1MBPS,
//    .scan_phys     = BLE_GAP_PHY_2MBPS,
    .extended      = 1,
};

static void scan_start(void);


/**@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)
{
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_ADV_REPORT:
        {
			if (m_scan.scan_buffer.len >= (uint8_t)32) {
				if (memcmp(g_UUID1, m_scan.scan_buffer.p_data+9, (uint8_t)16) == 0) {
					NRF_LOG_RAW_HEXDUMP_INFO (m_scan.scan_buffer.p_data, m_scan.scan_buffer.len);
					NRF_LOG_RAW_INFO ("----------------------------------\r\n");
					if (g_counter == (uint8_t)0) g_counter = 1;	// Start of the relay clatching for one time
					NRF_LOG_RAW_INFO ("Hold the relay\r\n");
				}
				if (memcmp(g_UUID2, m_scan.scan_buffer.p_data+9, (uint8_t)16) == 0) {
					NRF_LOG_RAW_HEXDUMP_INFO (m_scan.scan_buffer.p_data, m_scan.scan_buffer.len);
					NRF_LOG_RAW_INFO ("----------------------------------\r\n");
					if (g_counter == (uint8_t)0) g_counter = 1;	// Start of the relay clatching for one time
					NRF_LOG_RAW_INFO ("Hold the relay\r\n");
				}
			}
        }

        default:
            break;
    }
}


/**
 * @brief SoftDevice SoC event handler.
 *
 * @param[in] evt_id    SoC event.
 * @param[in] p_context Context.
 */
static void soc_evt_handler(uint32_t evt_id, void * p_context)
{
    switch (evt_id)
    {
        case NRF_EVT_FLASH_OPERATION_SUCCESS:
        /* fall through */
        case NRF_EVT_FLASH_OPERATION_ERROR:

            if (m_memory_access_in_progress)
            {
                m_memory_access_in_progress = false;
                scan_start();
            }
            break;

        default:
            // No implementation needed.
            break;
    }
}


/**@brief Function for initializing the BLE stack.
 *
 * @details 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 handlers for BLE and SoC events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    NRF_SDH_SOC_OBSERVER(m_soc_observer, APP_SOC_OBSERVER_PRIO, soc_evt_handler, NULL);
}


/**@brief Function for handling Scanning Module events.
 */
static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{
    switch(p_scan_evt->scan_evt_id)
    {
        case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
        {
            NRF_LOG_INFO("Scan timed out.");
            scan_start();
        } break;

        default:
          break;
    }
}


/**@brief Function for initializing the scanning and setting the filters.
 */
static void scan_init(void)
{
    ret_code_t          err_code;
    nrf_ble_scan_init_t init_scan;

    memset(&init_scan, 0, sizeof(init_scan));

    init_scan.connect_if_match = false;
    init_scan.conn_cfg_tag     = APP_BLE_CONN_CFG_TAG;
    init_scan.p_scan_param     = &m_scan_param;

    err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for starting scanning.
 */
static void scan_start(void)
{
    ret_code_t err_code;

    // If there is any pending write to flash, defer scanning until it completes.
    if (nrf_fstorage_is_busy(NULL))
    {
        m_memory_access_in_progress = true;
        return;
    }

    err_code = nrf_ble_scan_start(&m_scan);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for 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();
}


/**@brief Function for initializing the timer. */
static void timer_init(void)
{
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
}


/**@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 Handles any pending log operations, then sleeps until the next event occurs.
 */
static void idle_state_handle(void)
{
    if (NRF_LOG_PROCESS() == false)
    {
        nrf_pwr_mgmt_run();
    }
}



int main(void)
{
    // Initialize.
    log_init();
	// The UART TX pin NRF_LOG_BACKEND_UART_TX_PIN had defined in sdk_config.h (P0.6)
	// NRF_LOG_BACKEND_UART_BAUDRATE had defined in sdk_config.h (30801920 i.e. 115200 baud)
    timer_init();
    power_management_init();
    ble_stack_init();
    scan_init();
    
	nrf_gpio_cfg_output(21);		// Set 21 pin as output for the relay
	nrf_gpio_pin_clear(21);			// Set the pin 21 to low

    // Start execution.
    NRF_LOG_RAW_INFO(    " ----------------\r\n");
    NRF_LOG_RAW_INFO(	 "|   BT scanner   |");
    NRF_LOG_RAW_INFO("\r\n ----------------\r\n");
    
    g_counter = 0;
    scan_start();

    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
        if ((g_counter > (uint8_t)0) && (g_counter != (uint32_t)70000)) {
			g_counter++;			// Hold the relay
			nrf_gpio_pin_set(21);	// Set the pin 21 to High
		}
		if ((g_counter > (uint32_t)720) && (g_counter != (uint32_t)70000)) {
			g_counter = 70000;		// Release the relay
			NRF_LOG_RAW_INFO ("Release the relay\r\n");
			nrf_gpio_pin_clear(21);	// Set the pin 21 to low
		}
    }
}

Credits

iot4c
10 projects • 2 followers
Contact

Comments

Please log in or sign up to comment.