443 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <rtthread.h>
#include <finsh.h>
#include "common.h"
#include "param_config.h"
#include "ble_pub.h"
#include "drv_oled.h"
#include <rtthread.h>
#include <rtdevice.h>
#include "app_temperature.h"
#ifdef PKG_USING_EASYFLASH
#include "easyflash.h"
#endif
static app_temperature_info_t temperature_info;
static app_dev_info_t dev_info;
static app_temperature_mode_t app_mode = APP_MODE_NORMAL;
static beken_timer_t timer_detect;
static beken_timer_t timer_hall_detect;
static beken_timer_t timer_poweroff;
static beken_timer_t timer_bind;
static beken_timer_t timer_idle;
//extern uint8_t ble_active;
//static uint8_t actv_idx;
int Temp,Temp2,lastTemp;
int temp0,temp1,temp2;
uint8_t tempstr[5];
uint8_t tempstr1[5];
uint8_t tempstr11[5];
uint8_t tempstr2[5];
uint8_t batstr1[5];
uint8_t batstr2[5]="%";
uint8_t batstr3[5]=" ";
char *endPtr;
int start_bind_detect = 0;
int hall_key_down_count = 0;
int hall_io_state = 0;
uint8_t ble_device_mac[6] = {0xe5, 0xe6, 0xb6, 0x09, 0x28, 0x37};
int ble_device_rssi = -100;
int ble_found_bind_dev = 0;
/**
* 在BLE 广播里边查找设备名称
*/
int temperature_adv_get_name(recv_adv_t *r_ind,char *name){
int name_len = 0;
const uint8_t *p = r_ind->data;
const uint8_t *end = r_ind->data + r_ind->data_len;
while (p < end)
{
uint8_t current_length = *p++;
// current_length是类型+数据的总字节数。当前指针已经移动到类型字段。
if (current_length == 0)
{
break;
}
if (p + current_length > end)
{ // 类型1字节 + 数据长度current_length -1字节
// 数据不够,退出
break;
}
uint8_t type = *p++;
uint8_t data_len = current_length - 1; // 扣除类型字节后的数据长度
const uint8_t *data_ptr = p;
switch (type)
{
case 0x09: // Complete Local Name
if(data_len){
name_len = data_len;
rt_strncpy(name,(char*)data_ptr,data_len);
//rt_snprintf(name,data_len,"%s",data_ptr);
}
break;
default:
break;
}
p += data_len; // p之前已经移动到数据部分开始处此时加上数据长度让指针移动到下一个AD结构
}
return name_len;
}
void temperature_adv_callback(recv_adv_t *r_ind)
{
char str_name[12] ={0};
int ret = temperature_adv_get_name(r_ind,str_name);
signed char rssi = (signed char)r_ind->rssi;
if(ret){
#if 0
bk_printf("ble dev (%s): %02x:%02x:%02x:%02x:%02x:%02x,rssi:%d\r\n",str_name,r_ind->adv_addr[0], r_ind->adv_addr[1], r_ind->adv_addr[2],
r_ind->adv_addr[3], r_ind->adv_addr[4], r_ind->adv_addr[5],rssi);
#endif
}else{
//没有名称的 跳过!
return;
}
if(strstr(str_name,BLE_TEMPERATURE_DEVICE_IT12) == NULL){
//不等于 IT12的 跳过!
return;
}
#if 1
bk_printf("\r\n");
bk_printf("ble dev (%s): %02x:%02x:%02x:%02x:%02x:%02x,rssi:%d\r\n",str_name,r_ind->adv_addr[0], r_ind->adv_addr[1], r_ind->adv_addr[2],
r_ind->adv_addr[3], r_ind->adv_addr[4], r_ind->adv_addr[5],rssi);
#endif
//如果当前是绑定模式 则收集BLE 测温设备 判断信号值,然后绑定
if(app_mode == APP_MODE_BIND){
//简单匹配 选择信号值最大的
if(rssi > ble_device_rssi){
ble_found_bind_dev = 1;
ble_device_rssi = rssi;
rt_memcpy(ble_device_mac,r_ind->adv_addr,6);
bk_printf("found better !bind - > ble_device : %s \r\n",str_name);
}
return;
}
// 绑定的设备
if (r_ind->adv_addr[0] != dev_info.bind_mac[0]
&&r_ind->adv_addr[1] != dev_info.bind_mac[1]
&&r_ind->adv_addr[2] != dev_info.bind_mac[2]
&&r_ind->adv_addr[3] != dev_info.bind_mac[3]
&&r_ind->adv_addr[4] != dev_info.bind_mac[4]
&&r_ind->adv_addr[5] != dev_info.bind_mac[5])
{
return;
}
rtos_reload_timer(&timer_idle);
//int i;
//for (i = 0; i < r_ind->data_len; i++)
//{
// bk_printf("0x%02x,", r_ind->data[i]);
//}
//bk_printf("\r\n");
const uint8_t *p = r_ind->data;
const uint8_t *end = r_ind->data + r_ind->data_len;
int j = 0;
while (p < end)
{
uint8_t current_length = *p++;
// current_length是类型+数据的总字节数。当前指针已经移动到类型字段。
if (current_length == 0)
{
break;
}
if (p + current_length > end)
{ // 类型1字节 + 数据长度current_length -1字节
// 数据不够,退出
break;
}
uint8_t type = *p++;
uint8_t data_len = current_length - 1; // 扣除类型字节后的数据长度
const uint8_t *data_ptr = p;
switch (type)
{
case 0x01: // Flags
break;
case 0xFF: // Manufacturer Specific Data
bk_printf("FF: ");
for (j = 0; j < data_len; j++)
{
bk_printf("0x%02x ", data_ptr[j]);
}
bk_printf("\r\n");
uint16_t body = (data_ptr[1] & 0xff) | (((data_ptr[0] & 0xff) << 8));
uint16_t obj = (data_ptr[3] & 0xff) | (((data_ptr[2] & 0xff) << 8));
uint16_t env = (data_ptr[5] & 0xff) | (((data_ptr[4] & 0xff) << 8));
uint16_t batt = data_ptr[6] & 0xff;
temperature_info.temperature_body = body;
temperature_info.temperature_obj = obj;
temperature_info.temperature_env = env;
temperature_info.batt_val = batt;
bk_printf("temp-> body : %d obj : %d env : %d batt : %d\r\n", body, obj, env, batt);
break;
// 其他需要的类型可以继续添加
default:
break;
}
p += data_len; // p之前已经移动到数据部分开始处此时加上数据长度让指针移动到下一个AD结构
}
}
uint16_t last_body_temp = 0;
void timer_temp_run_callback(void *arg){
//如果当前进入了绑定模式 则不刷新温度
if(app_mode == APP_MODE_BIND){
return;
}
//如果当前温度和之前相同 不刷新温度
uint16_t temp_body = temperature_info.temperature_body;
if(last_body_temp == temp_body){
return;
}
last_body_temp = temp_body;
char str_temp[8]={0};
rt_sprintf(str_temp,"%d.%d \n",temp_body/100,temp_body/10%10);
rt_kprintf("%s\r\n",str_temp);
//rt_kprintf("Temp:%d,Temp2:%d\r\n",Temp,Temp2);
//rt_kprintf("Temp:%d,Temp2:%d\r\n",Temp,Temp2);
if(temp_body > BLE_TEMPERATURE_LIMIT_MIN && temp_body < BLE_TEMPERATURE_LIMIT_MAX){
OLED_Clear();
rt_memset(str_temp,0,sizeof(str_temp));
rt_sprintf(str_temp,"%d",temp_body/100);//整数
OLED_ShowString(0,0+10,(u8*)str_temp,32,1);
OLED_ShowChar(32,0+10,'.',32,1);//小数点
rt_memset(str_temp,0,sizeof(str_temp));
rt_sprintf(str_temp,"%d",temp_body/10%10);//小数点后一位
OLED_ShowString(40,0+10,(u8*)str_temp,32,1);
OLED_DrawCircle(58,5+6,4);
OLED_ShowChar(56,8+10,'C',24,1);
}
if(temp_body < BLE_TEMPERATURE_LIMIT_MIN){
OLED_Clear();
OLED_ShowString(0+10,0+5,(u8 *)"LOW",32,1);
}
if(temp_body > BLE_TEMPERATURE_LIMIT_MAX){
OLED_Clear();
OLED_ShowString(0+5,0+5,(u8 *)"HIGH",32,1);
}
lastTemp=Temp;
OLED_Refresh();
}
void app_enter_bind_mode(bool enter){
if(enter){
app_mode = APP_MODE_BIND;
rt_memset(ble_device_mac,0,sizeof(ble_device_mac));
//收到的信号值 区域0 为越好
ble_device_rssi = -100;
//清除找到绑定设备标志
ble_found_bind_dev = 0;
OLED_Clear();
OLED_ShowString(0+5,0+5,(u8 *)"BIND",32,1);
}else{
app_mode = APP_MODE_NORMAL;
OLED_Clear();
OLED_ShowString(0+20,0,(u8 *)"...",32,1);
}
OLED_Refresh();
}
void box_poweroff_timeout_callback(void *arg){
rtos_stop_timer(&timer_poweroff);
bk_gpio_config_output(BLE_TEMPERATURE_BOX_POWER_CTR);
bk_gpio_output(BLE_TEMPERATURE_BOX_POWER_CTR,0);
rt_kprintf("box poweroff !!!\r\n");
}
/**
* 绑定扫描设备时间到 判断有无找到设备 有则写入FLASH
*/
void box_bind_timeout_callback(void *arg){
rtos_stop_timer(&timer_bind);
if(ble_found_bind_dev){
bk_printf("BIND: %02x:%02x:%02x:%02x:%02x:%02x \r\n",ble_device_mac[0],ble_device_mac[1], ble_device_mac[2],
ble_device_mac[3], ble_device_mac[4],ble_device_mac[5]);
rt_memcpy(dev_info.bind_mac,ble_device_mac,sizeof(ble_device_mac));
EfErrCode result = EF_NO_ERR;
//将要写入的数据存放到 easy flash 环境变量
result = ef_set_env(BLE_TEMPERATURE_FLASH_CONFIG_KEY, (char*)&dev_info);
//保存数据
result = ef_save_env();
if(result == EF_NO_ERR)
{
OLED_Clear();
OLED_ShowString(0+15,0+5,(u8 *)"OK",32,1);
OLED_Refresh();
rt_thread_mdelay(1000);
}
}
app_enter_bind_mode(false);
rt_kprintf("exit bind mode !!!\r\n");
}
/*
长时间没有接收到温度广播 则回到等待页面
*/
void timer_app_idle_callback(void *arg){
if(app_mode == APP_MODE_BIND){
return;
}
app_enter_bind_mode(false);
rt_kprintf("back idle mode !!!\r\n");
}
/**
* 检测hall开关状态 判断是否进入绑定模式
* 进入绑定模式后检测接收到的最强一个测温信号设备绑定
*/
void timer_hall_detect_callback(void *arg){
int hall = bk_gpio_input(38);
//rt_kprintf("hall -> %d\r\n",hall);
if(hall_io_state == hall){
return;
}
hall_io_state = hall;
if(hall == 0){
if(!start_bind_detect){
start_bind_detect = 1;
}
hall_key_down_count ++;
rt_kprintf("detect hall down ,count :%d\r\n",hall_key_down_count);
//延迟关机
//启动定时8秒关机
rtos_start_timer(&timer_poweroff);
}else{
//如果启动定时开机后 检测到开盖,则取消开机
if(rtos_is_timer_running(&timer_poweroff)){
//rt_kprintf("stop poweroff timeout !!!\r\n");
rtos_stop_timer(&timer_poweroff);
}
if(start_bind_detect && hall_key_down_count == 5){
rt_kprintf("enter bind !!!\r\n");
start_bind_detect = 0;
hall_key_down_count = 0;
app_enter_bind_mode(true);
//进入绑定模式 并启动超时退出
rtos_start_timer(&timer_bind);
}
}
}
// 中断触发的回调函数
void box_switch_irq_callback(unsigned char ucChannel)
{
rt_kprintf("Interrupt triggered!\n");
// 这里可以添加更多的处理逻辑
int hall = bk_gpio_input(38);
rt_kprintf("hall -> %d\r\n",hall);
}
int box_switch_init(void)
{
//关闭box 保持电源不关机
bk_gpio_config_output(39);
bk_gpio_output(39,1);
bk_gpio_config_input(38);
//启动中断失败
//gpio_int_enable(38,GMODE_INPUT_PULLDOWN,box_switch_irq_callback);
/* 按键引脚为输入模式*/
//rt_pin_mode(GPIO38 , PIN_MODE_INPUT);
/* 绑定中断, 下降沿模式, 回调函数名为box_switch_irq_callback */
//rt_pin_attach_irq(GPIO38 , PIN_IRQ_MODE_FALLING , box_switch_irq_callback, RT_NULL);
/* 使能中断*/
//rt_pin_irq_enable(GPIO38 , PIN_IRQ_ENABLE);
return 0;
}
void temperature_dev_config_init(){
easyflash_init();
rt_memset(&dev_info,0,sizeof(app_dev_info_t));
/*获取easy flash存入的数据*/
char *t = ef_get_env(BLE_TEMPERATURE_FLASH_CONFIG_KEY);
if(t != NULL){
rt_memcpy(&dev_info,t,sizeof(app_dev_info_t));
rt_kprintf("\r\n");
rt_kprintf("BIND TDEVICE:%02X %02X %02X %02X %02X %02X\r\n",dev_info.bind_mac[0],dev_info.bind_mac[1],dev_info.bind_mac[2],dev_info.bind_mac[3],dev_info.bind_mac[4],dev_info.bind_mac[5]);
//rt_kprintf("DETECT %d\r\n",dev_info.detect_interval);
rt_kprintf("\r\n");
}else{
rt_kprintf("easy_flash read error\r\n");
}
}
void temperature_init(void){
// 查询绑定设备
uint8_t test_device_mac[6] = {0xe5, 0xe6, 0xb6, 0x09, 0x28, 0x37};
rt_memcmp(dev_info.bind_mac, test_device_mac, sizeof(test_device_mac));
//初始化GPIO
gpio_init();
//初始化OLED显示屏
OLED_Init();
//OLED_Clear();
// OLED_ShowChar(32,0+10,'.',32,1);
// OLED_Refresh();
// rt_thread_mdelay(100);
// OLED_Clear();
// OLED_ShowChar(56,8+10,'C',24,1);
// OLED_Refresh();
// bk_gpio_output(20,0);
// bk_gpio_output(21,0);
// oled_show_temp(370,4);
// user_app_start();
temperature_dev_config_init();
app_enter_bind_mode(false);
box_switch_init();
//初始化BLE
belon_ble_active();
//启动BLE MASTER 扫描BLE测温设备
belon_ble_init_scan();
rt_thread_mdelay(100);
//启动BLE SLAVE 发广播提供APP 连接进行设置
belon_ble_init_adv();
//启动定时器 定时更新温度显示
rtos_init_timer(&timer_detect, 1000, timer_temp_run_callback, NULL);
rtos_start_timer(&timer_detect);
//霍尔检测 100ms一次 中断不好使 先这样处理
rtos_init_timer(&timer_hall_detect, 100, timer_hall_detect_callback, NULL);
rtos_start_timer(&timer_hall_detect);
rtos_init_timer(&timer_poweroff, BLE_TEMPERATURE_POWEROFF_TIMEOUT, box_poweroff_timeout_callback, NULL);
rtos_init_timer(&timer_bind, BLE_TEMPERATURE_BIND_MODE_TIMEOUT, box_bind_timeout_callback, NULL);
rtos_init_timer(&timer_idle, BLE_TEMPERATURE_IDLE_MODE_TIMEOUT, timer_app_idle_callback, NULL);
}