#include #include #include #include #include "ledctl.h" #define SERVICE_INTERVAL_INTERVAL (60 * 60 * 1000) #define BATTERY_UPDATE_INTERVAL (60 * 60 * 1000) #define TEMPERATURE_TAG_PUB_NO_CHANGE_INTEVAL (15 * 60 * 1000) #define TEMPERATURE_TAG_PUB_VALUE_CHANGE 0.2f #define TEMPERATURE_UPDATE_SERVICE_INTERVAL (5 * 1000) #define TEMPERATURE_UPDATE_NORMAL_INTERVAL (10 * 1000) #define APPLICATION_TASK_ID 0 #define COLOR_BLACK true typedef struct { uint8_t number; float value; bc_tick_t next_pub; } event_param_t; bc_led_t led; bc_led_t led_lcd_red; bc_led_t led_lcd_blue; // Thermometer instance bc_tmp112_t tmp112; event_param_t temperature_event_param = { .next_pub = 0, .value = NAN }; float temperature_on_display = NAN; void tmp112_event_handler(bc_tmp112_t *self, bc_tmp112_event_t event, void *event_param) { float value; event_param_t *param = (event_param_t *)event_param; if (event != BC_TMP112_EVENT_UPDATE) return; if (bc_tmp112_get_temperature_celsius(self, &value)) { if ((fabsf(value - param->value) >= TEMPERATURE_TAG_PUB_VALUE_CHANGE) || (param->next_pub < bc_scheduler_get_spin_tick())) { bc_radio_pub_temperature(BC_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_ALTERNATE, &value); param->value = value; param->next_pub = bc_scheduler_get_spin_tick() + TEMPERATURE_TAG_PUB_NO_CHANGE_INTEVAL; } } else param->value = NAN; if ((fabsf(param->value - temperature_on_display) >= 0.1) || isnan(temperature_on_display)) bc_scheduler_plan_now(APPLICATION_TASK_ID); } void lcd_button_left_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param) { if (event == BC_BUTTON_EVENT_CLICK) { click_left(); bc_led_pulse(&led_lcd_blue, 30); } else if (event == BC_BUTTON_EVENT_HOLD) { hold_left(); bc_led_pulse(&led_lcd_blue, 500); } } void lcd_button_right_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param) { if (event == BC_BUTTON_EVENT_CLICK) { click_right(); bc_led_pulse(&led_lcd_red, 30); } else if (event == BC_BUTTON_EVENT_HOLD) { hold_right(); bc_led_pulse(&led_lcd_red, 500); } } void battery_event_handler(bc_module_battery_event_t event, void *event_param) { if (event != BC_MODULE_BATTERY_EVENT_UPDATE) return; float voltage; if (bc_module_battery_get_voltage(&voltage)) bc_radio_pub_battery(&voltage); } void switch_to_normal_mode_task(void *param) { bc_tmp112_set_update_interval(&tmp112, TEMPERATURE_UPDATE_NORMAL_INTERVAL); bc_scheduler_unregister(bc_scheduler_get_current_task_id()); } void application_init(void) { // Initialize LED on core module bc_led_init(&led, BC_GPIO_LED, false, false); bc_led_set_mode(&led, BC_LED_MODE_OFF); // Initialize Radio bc_radio_init(BC_RADIO_MODE_NODE_SLEEPING); // Initialize battery bc_module_battery_init(); bc_module_battery_set_event_handler(battery_event_handler, NULL); bc_module_battery_set_update_interval(BATTERY_UPDATE_INTERVAL); // Initialize thermometer sensor on core module bc_tmp112_init(&tmp112, BC_I2C_I2C0, 0x49); bc_tmp112_set_event_handler(&tmp112, tmp112_event_handler, &temperature_event_param); bc_tmp112_set_update_interval(&tmp112, TEMPERATURE_UPDATE_SERVICE_INTERVAL); // Initialize LCD bc_module_lcd_init(); // Initialize LCD button left static bc_button_t lcd_left; bc_button_init_virtual(&lcd_left, BC_MODULE_LCD_BUTTON_LEFT, bc_module_lcd_get_button_driver(), false); bc_button_set_event_handler(&lcd_left, lcd_button_left_event_handler, NULL); // Initialize LCD button right static bc_button_t lcd_right; bc_button_init_virtual(&lcd_right, BC_MODULE_LCD_BUTTON_RIGHT, bc_module_lcd_get_button_driver(), false); bc_button_set_event_handler(&lcd_right, lcd_button_right_event_handler, NULL); // Initialize red and blue LED on LCD module bc_led_init_virtual(&led_lcd_red, BC_MODULE_LCD_LED_RED, bc_module_lcd_get_led_driver(), true); bc_led_init_virtual(&led_lcd_blue, BC_MODULE_LCD_LED_BLUE, bc_module_lcd_get_led_driver(), true); bc_radio_pairing_request("lcd-thermostat", VERSION); bc_scheduler_register(switch_to_normal_mode_task, NULL, SERVICE_INTERVAL_INTERVAL); bc_led_pulse(&led, 2000); } void application_task(void) { static char str_temperature[10]; if (!bc_module_lcd_is_ready()) return; bc_system_pll_enable(); bc_module_lcd_clear(); bc_module_lcd_set_font(&bc_font_ubuntu_33); snprintf(str_temperature, sizeof(str_temperature), "%.1f ", temperature_event_param.value); int x = bc_module_lcd_draw_string(20, 20, str_temperature, COLOR_BLACK); temperature_on_display = temperature_event_param.value; bc_module_lcd_set_font(&bc_font_ubuntu_24); bc_module_lcd_draw_string(x - 20, 25, "\xb0" "C ", COLOR_BLACK); bc_module_lcd_update(); bc_system_pll_disable(); }