Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
William Lu
Created September 12, 2023

Smart Temperature Monitoring System

Monitor your room temperature from your mobile devices.

23
Smart Temperature Monitoring System

Things used in this project

Hardware components

CY8CPROTO-062-4343W
Infineon CY8CPROTO-062-4343W
×1
USB Cable Assembly, USB Type A Plug to Micro USB Type B Plug
USB Cable Assembly, USB Type A Plug to Micro USB Type B Plug
×1

Software apps and online services

ModusToolbox™ Software
Infineon ModusToolbox™ Software
EFR Connect BLE Mobile App

Story

Read more

Schematics

BOARD LAYOUT

Board Components

Code

Bluetooth_LE_Environmental_Sensing_Service

C/C++
Environmental Sensing Service (Thermistor)
#include "cybsp.h"
#include "cy_retarget_io.h"
#include "cybt_platform_trace.h"
#include "cyhal.h"
#include "cyhal_gpio.h"
#include "stdio.h"
#include "cyabs_rtos.h"
#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>
#include <string.h>
#include <timers.h>
#include "GeneratedSource/cycfg_gatt_db.h"
#include "app_bt_gatt_handler.h"
#include "app_bt_utils.h"
#include "wiced_bt_ble.h"
#include "wiced_bt_uuid.h"
#include "wiced_memory.h"
#include "wiced_bt_stack.h"
#include "cycfg_bt_settings.h"
#include "cycfg_gap.h"
#include "cybsp_bt_config.h"

#define POLL_TIMER_IN_MSEC              (49999u)
#define POLL_TIMER_FREQ                 (10000)
/* Temperature Simulation Constants */
#define DEFAULT_TEMPERATURE             (2500u)
#define MAX_TEMPERATURE_LIMIT           (3000u)
#define MIN_TEMPERATURE_LIMIT           (2000u)
#define DELTA_TEMPERATURE               (100u)

/* Number of advertisment packet */
#define NUM_ADV_PACKETS                 (3u)

/* Absolute value of an integer. The absolute value is always positive. */
#ifndef ABS
#define ABS(N) ((N<0) ? (-N) : (N))
#endif

/* Check if notification is enabled for a valid connection ID */
#define IS_NOTIFIABLE(conn_id, cccd) (((conn_id)!= 0)? (cccd) & GATT_CLIENT_CONFIG_NOTIFICATION: 0)

/* Configuring Higher priority for the application */
volatile int uxTopUsedPriority;

/* Manages runtime configuration of Bluetooth stack */
extern const wiced_bt_cfg_settings_t wiced_bt_cfg_settings;

/* FreeRTOS variable to store handle of task created to update and send dummy
   values of temperature */
TaskHandle_t ess_task_handle;

/* Status variable for connection ID */
uint16_t app_bt_conn_id;

/* Dummy Room Temperature */
int16_t temperature = DEFAULT_TEMPERATURE;
uint8_t alternating_flag = 0;

/* Variable for 5 sec timer object */
static cyhal_timer_t ess_timer_obj;
/* Configure timer for 5 sec */
const cyhal_timer_cfg_t ess_timer_cfg =
    {
        .compare_value = 0,                    /* Timer compare value, not used */
        .period = POLL_TIMER_IN_MSEC, /* Defines the timer period */
        .direction = CYHAL_TIMER_DIR_UP,       /* Timer counts up */
        .is_compare = false,                   /* Don't use compare mode */
        .is_continuous = true,                 /* Run timer indefinitely */
        .value = 0                             /* Initial value of counter */
};

/* Callback function for Bluetooth stack management type events */
static wiced_bt_dev_status_t
app_bt_management_callback(wiced_bt_management_evt_t event,
                           wiced_bt_management_evt_data_t *p_event_data);

/* This function sets the advertisement data */
static wiced_result_t app_bt_set_advertisement_data(void);

/* This function initializes the required BLE ESS & thermistor */
static void bt_app_init(void);

/* Task to send notifications with dummy temperature values */
void ess_task(void *pvParam);
/* HAL timer callback registered when timer reaches terminal count */
void ess_timer_callb(void *callback_arg, cyhal_timer_event_t event);

/* This function starts the advertisements */
static void app_start_advertisement(void);

int main(void)
{
    uxTopUsedPriority = configMAX_PRIORITIES - 1;
    wiced_result_t wiced_result;
    BaseType_t rtos_result;

    /* Initialize and Verify the BSP initialization */
    CY_ASSERT(CY_RSLT_SUCCESS == cybsp_init());

    /* Enable global interrupts */
    __enable_irq();

    /* Initialize retarget-io to use the debug UART port */
    cy_retarget_io_init(CYBSP_DEBUG_UART_TX,
                        CYBSP_DEBUG_UART_RX,
                        CY_RETARGET_IO_BAUDRATE);

    /* Initialising the HCI UART for Host contol */
    cybt_platform_config_init(&cybsp_bt_platform_cfg);

    /* Debug logs on UART port */

    printf("****** Environmental Sensing Service ******\n");

    /* Register call back and configuration with stack */
    wiced_result = wiced_bt_stack_init(app_bt_management_callback,
                                 &wiced_bt_cfg_settings);

    /* Check if stack initialization was successful */
    if (WICED_BT_SUCCESS == wiced_result) {
        printf("Bluetooth Stack Initialization Successful \n");
    } else {
        printf("Bluetooth Stack Initialization failed!!\n");
    }

    rtos_result = xTaskCreate(ess_task, "ESS Task", (configMINIMAL_STACK_SIZE * 4),
                                        NULL, (configMAX_PRIORITIES - 3), &ess_task_handle);
    if(pdPASS == rtos_result)
    {
        printf("ESS task created successfully\n");
    }
    else
    {
        printf("ESS task creation failed\n");
    }

    /* Start the FreeRTOS scheduler */
    vTaskStartScheduler();

    /* Should never get here */
    CY_ASSERT(0);
}

static wiced_result_t
app_bt_management_callback(wiced_bt_management_evt_t event,
                           wiced_bt_management_evt_data_t *p_event_data)
{
    wiced_bt_dev_status_t status = WICED_ERROR;


    switch (event) {

    case BTM_ENABLED_EVT:
    {
        printf("\nThis application implements Bluetooth LE Environmental Sensing\n"
                "Service and sends dummy temperature values in Celsius\n"
                "every %d milliseconds over Bluetooth\n", (POLL_TIMER_IN_MSEC));

        printf("Discover this device with the name:%s\n", app_gap_device_name);

        print_local_bd_address();

        printf("\n");
        printf("Bluetooth Management Event: \t");
        printf("%s", get_btm_event_name(event));
        printf("\n");

        /* Perform application-specific initialization */
        bt_app_init();
    }break;

    case BTM_DISABLED_EVT:
        /* Bluetooth Controller and Host Stack Disabled */
        printf("\n");
        printf("Bluetooth Management Event: \t");
        printf("%s", get_btm_event_name(event));
        printf("\n");
        printf("Bluetooth Disabled\n");
        break;

    case BTM_BLE_ADVERT_STATE_CHANGED_EVT:
    {
        wiced_bt_ble_advert_mode_t *p_adv_mode = &p_event_data->ble_advert_state_changed;
        /* Advertisement State Changed */
        printf("\n");
        printf("Bluetooth Management Event: \t");
        printf("%s", get_btm_event_name(event));
        printf("\n");
        printf("\n");
        printf("Advertisement state changed to ");
        printf("%s", get_btm_advert_mode_name(*p_adv_mode));
        printf("\n");
    }break;

    default:
        printf("\nUnhandled Bluetooth Management Event: %d %s\n",
                event,
                get_btm_event_name(event));
        break;
    }

    return (status);
}

static void bt_app_init(void)
{
    wiced_bt_gatt_status_t gatt_status = WICED_BT_GATT_ERROR;
    cy_rslt_t rslt;

    /* Register with stack to receive GATT callback */
    gatt_status = wiced_bt_gatt_register(app_bt_gatt_event_callback);
    printf("\n gatt_register status:\t%s\n",get_gatt_status_name(gatt_status));

    /* Initialize the User LED */
    cyhal_gpio_init(CONNECTION_LED,
                    CYHAL_GPIO_DIR_OUTPUT,
                    CYHAL_GPIO_DRIVE_STRONG,
                    CYBSP_LED_STATE_OFF);

    /* Initialize the HAL timer used to count 5 seconds */
    rslt = cyhal_timer_init(&ess_timer_obj, NC, NULL);
    if (CY_RSLT_SUCCESS != rslt)
    {
        printf("ESS timer init failed !\n");
    }
    /* Configure the timer for 5 seconds */
    cyhal_timer_configure(&ess_timer_obj, &ess_timer_cfg);
    rslt = cyhal_timer_set_frequency(&ess_timer_obj, POLL_TIMER_FREQ);
    if (CY_RSLT_SUCCESS != rslt)
    {
        printf("ESS timer set freq failed !\n");
    }
    /* Register for a callback whenever timer reaches terminal count */
    cyhal_timer_register_callback(&ess_timer_obj, ess_timer_callb, NULL);
    cyhal_timer_enable_event(&ess_timer_obj, CYHAL_TIMER_IRQ_TERMINAL_COUNT, 3, true);

    /* Start the timer */
    if (CY_RSLT_SUCCESS != cyhal_timer_start(&ess_timer_obj))
    {
        printf("ESS timer start failed !");
    }

    /* Initialize GATT Database */
    gatt_status = wiced_bt_gatt_db_init(gatt_database, gatt_database_len, NULL);
    if (WICED_BT_GATT_SUCCESS != gatt_status) {
        printf("\n GATT DB Initialization not successful err 0x%x\n", gatt_status);
    }

    /* Start Bluetooth LE advertisements */
    app_start_advertisement();

}

static void app_start_advertisement(void)
{
    wiced_result_t wiced_status;

    /* Set Advertisement Data */
    wiced_status = app_bt_set_advertisement_data();
    if (WICED_SUCCESS != wiced_status) {
        printf("Raw advertisement failed err 0x%x\n", wiced_status);
    }

    /* Do not allow peer to pair */
    wiced_bt_set_pairable_mode(WICED_FALSE, FALSE);

    /* Start Undirected LE Advertisements on device startup. */
    wiced_status = wiced_bt_start_advertisements(BTM_BLE_ADVERT_UNDIRECTED_HIGH,
                                                 BLE_ADDR_PUBLIC,
                                                 NULL);

    if (WICED_SUCCESS != wiced_status) {
        printf( "Starting undirected Bluetooth LE advertisements"
                "Failed err 0x%x\n", wiced_status);
    }
}


static wiced_result_t app_bt_set_advertisement_data(void)
{

    wiced_result_t wiced_result = WICED_SUCCESS;
    wiced_result = wiced_bt_ble_set_raw_advertisement_data( NUM_ADV_PACKETS,
                                                            cy_bt_adv_packet_data);

    return (wiced_result);
}


void ess_timer_callb(void *callback_arg, cyhal_timer_event_t event)
{
    BaseType_t xHigherPriorityTaskWoken;
    xHigherPriorityTaskWoken = pdFALSE;
    vTaskNotifyGiveFromISR(ess_task_handle, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

void ess_task(void *pvParam)
{
    while(true)
    {
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        /* Varying temperature by 1 degree on every timeout for simulation */
        if (0 == alternating_flag)
        {
            temperature += DELTA_TEMPERATURE;
            if (MAX_TEMPERATURE_LIMIT <= temperature)
            {
                alternating_flag = 1;
            }
        }
        else if ((1 == alternating_flag))
        {
            temperature -= DELTA_TEMPERATURE;
            if (MIN_TEMPERATURE_LIMIT >= temperature)
            {
                alternating_flag = 0;
            }
        }

        printf("\nTemperature (in degree Celsius) \t\t%d.%02d C\n",
                (temperature / 100), ABS(temperature % 100));

        app_ess_temperature[0] = (uint8_t)(temperature & 0xff);
        app_ess_temperature[1] = (uint8_t)((temperature >> 8) & 0xff);

        if (IS_NOTIFIABLE (app_bt_conn_id, app_ess_temperature_client_char_config[0]) == 0)
        {
            if(!app_bt_conn_id)
            {
                printf("This device is not connected to a central device\n");
            }else{
                printf("This device is connected to a central device but\n"
                        "GATT client notifications are not enabled\n");
            }
        }
        else
        {
            wiced_bt_gatt_status_t gatt_status;

            gatt_status = wiced_bt_gatt_server_send_notification(app_bt_conn_id,
                                                                    HDLC_ESS_TEMPERATURE_VALUE,
                                                                    app_ess_temperature_len,
                                                                    app_ess_temperature,
                                                                    NULL);

            printf("Sent notification status 0x%x\n", gatt_status);

        }
    }
}

Credits

William Lu

William Lu

4 projects • 1 follower
A motivated biomedical engineer with experience in 3D CAD modeling, assembling, FEA, computer vision, and machine learning object detection.

Comments