#include #include #include "common.h" #include "param_config.h" #include "ble_pub.h" #include "drv_oled.h" #include #include #include "wlan_ui_pub.h" #include "sys_ctrl_pub.h" #include "sys_ctrl.h" #include "target_util_pub.h" #include "drv_model_pub.h" #include "md5.h" #include "app_temperature.h" #include "app_voice_player.h" #include "BkDriverFlash.h" #include "manual_ps_pub.h" #ifdef PKG_USING_EASYFLASH #include "easyflash.h" #endif #include "saradc_intf.h" #include "saradc_pub.h" #include "ring_queue.h" #include "charge.h" #include "mqtt_client.h" #include "app_wifi.h" static app_temperature_info_t temperature_info; //static app_dev_info_t dev_info; static app_box_info_t box_info; 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; static beken_timer_t timer_battery_refresh; static beken_timer_t timer_ble_scan; //static beken_timer_t timer_charge_hell ; int start_bind_detect = 0; int hall_key_down_count = 0; uint32_t hall_first_down_tick = 0; // 记录第一次合盖的tick #define HALL_BIND_WINDOW_MS 5000 int hall_io_state = 0; static ADC_OBJ box_batt_adc; static int box_battery_percent = -1; static int oled_is_on = 1; // 屏幕状态 uint16_t last_body_temp = 0; rt_thread_t tid_show_wait_temp; static app_ui_mode app_mode = UI_IDLE; rt_thread_t tid_show_detect_temp; static RingQueue ring_queue; extern mqtt_client client; static int e = 0; static int mean_value = 0; //WIFI信息 extern char last_ssid[33] ; extern char last_password[65]; extern char g_sta_mac[6]; /** * 当前绑定的设备 */ uint8_t box_bind_mac[32]; /** * 待绑定的设备 */ uint8_t ble_device_mac[6] = {0xe5, 0xe6, 0xb6, 0x09, 0x28, 0x37}; //uint8_t ble_device_name[12] = {0}; 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 timer_ble_scan_callback(void *arg); /** * 搜索广播回调 */ void temperature_adv_callback(recv_adv_t *r_ind) { //获取BLE 设备名称 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; } //不等于 IT12 或 IT22 跳过! if(strstr(str_name,BLE_TEMPERATURE_DEVICE_IT12) == NULL && strstr(str_name,BLE_TEMPERATURE_DEVICE_IT22) == NULL){ //bk_printf("%s\r\n",str_name); return; } // if(str_name[0] != '\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); // } #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 == UI_BOX_BIND){ //简单匹配 选择信号值最大的 bk_printf("app_mode == UI_BOX_BIND\r\n"); 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; } bk_printf("bind dev : %s \r\n", box_bind_mac); // 判断是否是绑定的设备 如果不是则跳出 //bind: box_bind_mac //current: char str_current [32]; rt_memset(str_current,0,sizeof(str_current)); rt_sprintf(str_current,"%02x:%02x:%02x:%02x:%02x:%02x",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]); if(rt_strcmp((char*)str_current, (char*)box_bind_mac) != 0){ return; }else{ bk_printf("same : %s \r\n",str_current); if(0){//box_info.charge_state == 0){ belon_ble_scan_stop(); rtos_init_timer(&timer_ble_scan, BLE_SCAN_INTERVAL, timer_ble_scan_callback, NULL); rtos_start_timer(&timer_ble_scan); } } //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; uint16_t batt_val = (data_ptr[8] & 0xff) | (((data_ptr[7] & 0xff) << 8)); if(body <= 20 && obj ==0 && env ==0 && batt == 0){ bk_printf("error data ...\r\n"); return ; } temperature_info.temperature_body = body; temperature_info.temperature_obj = obj; temperature_info.temperature_env = env; temperature_info.batt_percent = batt; temperature_info.batt_val = batt_val; bk_printf("temp-> body : %d obj : %d env : %d batt : %d batt_val : %d\r\n", body, obj, env, batt, batt_val); break; // 其他需要的类型可以继续添加 default: break; } p += data_len; // p之前已经移动到数据部分开始处,此时加上数据长度让指针移动到下一个AD结构 } //复制设备名称 rt_memset(temperature_info.device_name,0,sizeof(temperature_info.device_name)); rt_memcpy(temperature_info.device_name,str_name,sizeof(str_name)); //rt_strcmp((char*)str_name,(char*)temperature_info.device_name); bk_printf("!!!ble_device : %s %s \r\n",str_name,temperature_info.device_name); rtos_reload_timer(&timer_idle); //在超时或者等待温度页面 第一次接受到温度 显示设备信息 if(app_mode == UI_IDLE || app_mode == UI_WAIT_TEMPERATURE || app_mode == UI_SHOW_MEMORY_INFO || app_mode == UI_SHOW_DEVICE_INFO|| app_mode == UI_BOX_BATTERY){ bk_printf("!app_mode : %d \r\n",app_mode); app_enter_ui(UI_SHOW_DEVICE_INFO); voice_player_play_tts(VOICE_CN_DETECT_START); } //如果当前温度和之前相同 不刷新温度 uint16_t temp_body = temperature_info.temperature_body; //判断温度是否在规定范围 if(temp_body < BLE_TEMPERATURE_MIN || temp_body > BLE_TEMPERATURE_MAX){ return; } // if(last_body_temp == temp_body){ // bk_printf("last_body_temp == temp_body \r\n"); // return; // } last_body_temp = temp_body; app_enter_ui(UI_SHOW_TEMPERATURE); //添加数据到队列,数量足够后取出所有温度数据 计算方差 如果小于 N N可以趋近于0 暂定小于100 则表示温度稳定 RingQueue_enqueue(&ring_queue,(int)last_body_temp); int size = RingQueue_size(&ring_queue); bk_printf("RingQueue_size -> %d \r\n", size); if (RingQueue_isFull(&ring_queue)) { //int i = 0; //int t_datas[MAX_SIZE]; //for(i = 0;i < MAX_SIZE; i++){ int value = 0; RingQueue_dequeue(&ring_queue,&value); //t_datas[i] = value; bk_printf("%d ", value); //} bk_printf("size: %d\r\n", size); //计算平均值 int sum = 0; //for(i = 0;i < MAX_SIZE; i++){ // sum += t_datas[i]; //} //int mean_value = ring_queue.sum / MAX_SIZE; //bk_printf("mean_value:%d \r\n", mean_value); for (int j=0;j=MAX_SIZE){ e=0; if(client.isconnected){ if(mean_value!=0) mqtt_upload_temperature(mean_value); //mqtt_upload_boxbat(box_battery_percent); mqtt_upload_bat(temperature_info.batt_percent); } } } UINT32 usb_power_is_pluged(void) { UINT32 reg; reg = sctrl_analog_get((SCTRL_BASE + 0x21*4)); return (reg & (1 << 21)); } void box_poweroff_timeout_callback(void *arg); void timer_battery_refresh_callback(void *arg); int first_poweron = 0; static int s=0; void timer_check_device_run_callback(void *arg){ uint16_t reg_charge = CHARGE_REG0X2_CHARGE_X_STA_GET(0); int hall = bk_gpio_input(BLE_TEMPERATURE_HALL_DETECT_PIN); //未接入充电 5376 接入充电 38144 if(reg_charge == 5376){ box_info.charge_state = 0; }else{ box_info.charge_state = 1; } // box_info.charge_state = 0; rt_kprintf("usb_power_is_pluged reg:%d state:%d hall:%d\r\n", reg_charge, box_info.charge_state, box_info.hall_state); s++; if(s>=10){ timer_battery_refresh_callback(NULL); s=0; } for(int i = 0; i < 5; i++){ //1秒内处于合盖状态就关机 if(hall || !first_poweron){ first_poweron = 1; return; } rt_thread_mdelay(600); } //rtos_start_timer(&timer_poweroff); box_poweroff_timeout_callback(NULL); //合盖状态接入充电 ---> 关机 // if (box_info.hall_state == 0) // { // if (box_info.charge_state){ // // 接入充电 并且合盖 执行关机 // rtos_stop_timer(&timer_poweroff); // //延迟关机 // //启动定时3秒关机 // rtos_start_timer(&timer_poweroff); // } // } } void timer_ble_scan_callback(void *arg){ //belon_ble_scan_start(); //rtos_deinit_timer(&timer_ble_scan); } /** * 显示 ... 表示等待 */ static void app_temperature_ui_wait_entry(void *parameter) { int i = 0; int ui_wait_step = 0; while (1) { if(i >2000){ i = 0; } i++; if(app_mode == UI_WAIT_TEMPERATURE || app_mode == UI_IDLE ||UI_SHOW_MEMORY_INFO){ if(i%50==0){ //500ms OLED_Clear(); switch (ui_wait_step) { case 0: OLED_ShowString(0+20,0,(u8 *)"",32,1); ui_wait_step =1; break; case 1: OLED_ShowString(16,0,(u8 *)".",32,1); ui_wait_step =2; break; case 2: OLED_ShowString(16,0,(u8 *)"..",32,1); ui_wait_step =3; break; case 3: OLED_ShowString(16,0,(u8 *)"...",32,1); ui_wait_step =0; break; break; default: break; } OLED_Refresh(); } rt_thread_mdelay(10); } } rt_kprintf("ui_wait finish !!!\r\n"); } void app_show_box_battery(){ rt_kprintf("UI->app_show_box_battery\r\n"); OLED_Clear(); char str_batt[12] = {0}; rt_sprintf(str_batt,"%d%",box_battery_percent); extern unsigned char f35x40_box_ico[]; //满电显示屏显示不全 缩小字体显示 if(box_battery_percent >= 100){ OLED_ShowPicture(3,5,35,40,(u8 *)&f35x40_box_ico,1); OLED_ShowString(38,15,(u8 *)str_batt,16,1); }else{ OLED_ShowPicture(1,3,35,40,(u8 *)&f35x40_box_ico,1); //OLED_DrawCircle(15, 20, 10); //OLED_DrawCircle(15, 20, 7); OLED_ShowString(36,8,(u8 *)str_batt,24,1); } rt_kprintf("%s\r\n",str_batt); OLED_Refresh(); } /****channel 1 - 7***/ static void box_adc_detect_callback(int new_mv, void *user_data) { static int cnt = 0; box_batt_adc.user_data = (void*)new_mv; //u32 kmah=0; if(cnt++ >= 20){ cnt = 0; rt_kprintf("adc channel%d voltage:%d,%x\r\n",box_batt_adc.channel,new_mv,box_batt_adc.user_data); int bat_volt = new_mv*2; //int batt_min = 3300; //3300 //int batt_max = 4151; if(box_info.charge_state){ bat_volt -= 48 ; } rt_kprintf("battery_calc --> bat_volt:%d\n",bat_volt); if (bat_volt >= voltage_table[0].voltage) { printf("0000000000000000000000000000\r\n"); printf("voltage:%d\r\n",voltage_table[0].voltage); box_battery_percent = 100; } // 电压低于最低阈值,返回0% else if (bat_volt <= voltage_table[BATTERY_TABLE_SIZE-1].voltage) { printf("11111111111111111111111111111\r\n"); printf("voltage:%d\r\n",voltage_table[BATTERY_TABLE_SIZE-1].voltage); box_battery_percent = 0; } // 查表法查找对应的电量百分比 else{ for (int i = 1; i < BATTERY_TABLE_SIZE; i++){ if (bat_volt >= voltage_table[i].voltage){ // 线性插值计算百分比 //u16 voltage_range = voltage_table[i].voltage - voltage_table[i-1].voltage; //u16 voltage_offset = bat_val - voltage_table[i-1].voltage; box_battery_percent=(443570-voltage_table[i].mah)*100/443570; printf("i:%d \r\n", i); printf("voltage_table[i].mah:%d \r\n", voltage_table[i].voltage); printf("tmp_bat_val:%d \r\n", box_battery_percent); break; //return box_battery_percent; } } } /*if(bat_volt >= batt_max) box_battery_percent = 100; else if(bat_volt <= batt_max && bat_volt >= 4000){ kmah = (-28880*bat_volt+120895600)/151; box_battery_percent = (443570-kmah)*100/443570; // 4000~4150 } else if(bat_volt <= 4000 && bat_volt >= 3800){ kmah = (-78560*bat_volt+321360000)/200; box_battery_percent = (443570-kmah)*100/443570; // 3800~4000 } else if(bat_volt <= 3800 && bat_volt >= 3600){ kmah = (-134960*bat_volt+535680000)/200; box_battery_percent = (443570-kmah)*100/443570; // 3600~3800 } else if(bat_volt <= 3600 && bat_volt >= 3400){ kmah = (-163110*bat_volt+637020000)/200; box_battery_percent = (443570-kmah)*100/443570; // 3400~3600 } else if(bat_volt <= 3600 && bat_volt >= 3400){ kmah = (-31340*bat_volt+271448000)/400; box_battery_percent = (443570-kmah)*100/443570; // 3000~3400 } else box_battery_percent = 1;*/ // if (bat_volt < batt_min) { // box_battery_percent=0; // } else if (bat_volt > batt_max) { // box_battery_percent= 100; // } else { // box_battery_percent= ((float)(bat_volt - batt_min) / (batt_max - batt_min)) * 100; // printf("battery_calc @@@ --> percent:%d\n",box_battery_percent); // } // if(box_battery_percent < 0){ // box_battery_percent = 0; // } rt_kprintf("battery_calc --> percent:%d\n",box_battery_percent); adc_obj_stop(&box_batt_adc); } } void box_init_power(){ int channel; int retry = 0; channel = 7; saradc_work_create(); adc_obj_init(&box_batt_adc, box_adc_detect_callback, channel, &box_batt_adc); adc_obj_start(&box_batt_adc); rt_thread_mdelay(500); while(1){ if(box_battery_percent > 0){ break; } rt_thread_mdelay(20); if(++retry > 20) break; } } // 定时检测电量并刷新显示 void timer_battery_refresh_callback(void *arg) { rt_kprintf("Update power...\r\n"); // 重新采样电池电压 adc_obj_start(&box_batt_adc); // 重新显示电量 if(client.isconnected) mqtt_upload_boxbat(box_battery_percent); if(app_mode == UI_BOX_BATTERY || app_mode == UI_SHOW_MEMORY_INFO) { app_show_box_battery(); } } /** * 显示最近一次检测的温度 */ void app_show_memory_detect_info(){ rt_kprintf("UI->app_show_last_detect_info\r\n"); app_detect_record_t record; rt_memset(&record,0,sizeof(app_detect_record_t)); temperature_read_record(&record); if(record.temperature_value == 0){ rt_kprintf("no record\r\n"); return; } rtos_stop_timer(&timer_battery_refresh); OLED_Clear(); OLED_ShowString(21,5,(u8 *)"M1",32,1); OLED_Refresh(); rt_thread_mdelay(1000); OLED_Clear(); char str_temp[12]={0}; //rt_sprintf(str_temp,"%d.%d\n",record.temperature_value/100,record.temperature_value/10%10); rt_memset(str_temp,0,sizeof(str_temp)); rt_sprintf(str_temp,"%d",record.temperature_value/100/10);//整数 OLED_ShowString(0,0,(u8*)str_temp,48,1); rt_sprintf(str_temp,"%d",record.temperature_value/100%10);//整数 OLED_ShowString(19,0,(u8*)str_temp,48,1); OLED_ShowChar(35,0+18,'.',24,1);//小数点 rt_memset(str_temp,0,sizeof(str_temp)); rt_sprintf(str_temp,"%d",record.temperature_value/10%10);//小数点后一位 OLED_ShowString(41,0,(u8*)str_temp,48,1); OLED_ShowChar(61,18,'C',24,1); OLED_DrawCircle(63,10,4); //rt_sprintf(str_temp,"") //OLED_ShowString(0,18,(u8 *)"36.5 C",24,1); //OLED_ShowString(0,0,(u8 *)str_temp,48,1); //OLED_DrawCircle(55,15,4); OLED_Refresh(); rt_thread_mdelay(1000); } /** * 体温计电量过低时显示低电提示 */ void app_show_low_box_batt(){ rt_kprintf("UI->app_show_low_box_batt\r\n"); OLED_Clear(); OLED_ShowChinese(3,5,0,32,1); //低 OLED_ShowChinese(35,5,10,32,1);//电 OLED_Refresh(); rt_thread_mdelay(2000); } /** * 开机第一次检测到测温设备时 显示设备的名称和电量 然后持续监测温度 */ void app_show_temperature_device_info(){ rt_kprintf("UI->app_show_temperature_device_info\r\n"); OLED_Clear(); //char str_device[16]={0}; //rt_sprintf(str_device,"%s",temperature_info.device_name); OLED_ShowString(0,5,(u8 *)temperature_info.device_name,16,1); extern unsigned char f40x20_box_batt[]; OLED_ShowPicture(0,23,40,20,(u8 *)&f40x20_box_batt,1); char str_batt[16]={0}; rt_sprintf(str_batt,":%d%",temperature_info.batt_percent); OLED_ShowString(35,25,(u8 *)str_batt,16,1); OLED_Refresh(); rt_thread_mdelay(2000); if(temperature_info.batt_val < 330){ //电压值小于365显示“低电” app_enter_ui(UI_SHOW_LOW_BAT_INFO); } } /** * 显示正在等待测温 */ void app_show_wait_temperature(){ rt_kprintf("UI->app_show_wait_temperature\r\n"); if(tid_show_wait_temp){ rt_thread_delete(tid_show_wait_temp); tid_show_wait_temp = NULL; } tid_show_wait_temp = rt_thread_create("wait_temp",app_temperature_ui_wait_entry,RT_NULL,1024 * 8,21,10); if (tid_show_wait_temp) rt_thread_startup(tid_show_wait_temp); } static void app_temperature_ui_detect_entry(void *parameter) { int i = 0; int ui_show_point = 0; while (1) { if(i >2000){ i = 0; } i++; //1s刷新一次 用于 屏幕上的点 闪烁 if(i%100==0){ //1000ms OLED_Clear(); //rt_kprintf("UI->app_ui_show_temperautre \r\n"); uint16_t temp_body = last_body_temp; 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); //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/10);//整数 OLED_ShowString(0,0,(u8*)str_temp,48,1); rt_sprintf(str_temp,"%d",temp_body/100%10);//整数 OLED_ShowString(19,0,(u8*)str_temp,48,1); OLED_ShowChar(35,0+18,'.',24,1);//小数点 rt_memset(str_temp,0,sizeof(str_temp)); rt_sprintf(str_temp,"%d",temp_body/10%10);//小数点后一位 OLED_ShowString(41,0,(u8*)str_temp,48,1); OLED_ShowChar(61,18,'C',24,1); //屏幕上的点(度) 闪烁 if(ui_show_point){ OLED_DrawCircle(63,10,4); //未测量完成才允许闪烁 if(temperature_info.device_state == STATE_DETECT_ING){ ui_show_point = 0; } }else{ ui_show_point = 1; } //} /*if(temp_body < BLE_TEMPERATURE_LIMIT_MIN){ OLED_Clear(); //OLED_ShowString(0+10,0+5,(u8 *)"LOW",32,1); OLED_ShowChinese(3,5,0,32,1); //低 OLED_ShowChinese(35,5,2,32,1);//温 } if(temp_body > BLE_TEMPERATURE_LIMIT_MAX){ OLED_Clear(); //OLED_ShowString(0+5,0+5,(u8 *)"HIGH",32,1); OLED_ShowChinese(3,5,9,32,1); //超 OLED_ShowChinese(35,5,2,32,1);//温 }*/ OLED_Refresh(); } rt_thread_mdelay(10); //} } rt_kprintf("ui_detect finish !!!\r\n"); } /** * 显示正在测温 */ void app_show_detect_temperature(){ rt_kprintf("UI->app_show_detect_temperature\r\n"); OLED_Clear(); //退出正在进行的动画线程 if(tid_show_wait_temp){ rt_thread_delete(tid_show_wait_temp); tid_show_wait_temp = NULL; } //退出正在进行测温的动画线程 if(tid_show_detect_temp){ rt_thread_delete(tid_show_detect_temp); tid_show_detect_temp = NULL; } tid_show_detect_temp = rt_thread_create("do_detect",app_temperature_ui_detect_entry,RT_NULL,1024 * 8,21,10); if (tid_show_detect_temp) rt_thread_startup(tid_show_detect_temp); rt_kprintf("startup success\r\n"); } void app_ui_show_bind(){ rt_kprintf("UI->app_ui_show_bind \r\n"); OLED_Clear(); //OLED_ShowString(0+5,0+5,(u8 *)"BIND",32,1); OLED_ShowChinese(3,3,3,32,1); //绑 OLED_ShowChinese(35,3,4,32,1);//定 OLED_Refresh(); } /** * 显示接收到的温度 */ void app_ui_show_temperautre(){ rt_kprintf("UI->app_ui_show_temperautre \r\n"); uint16_t temp_body = last_body_temp; 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); 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(60,10,4); OLED_ShowChar(58,16,'C',24,1); } if(temp_body < BLE_TEMPERATURE_LIMIT_MIN){ OLED_Clear(); //OLED_ShowString(0+10,0+5,(u8 *)"LOW",32,1); OLED_ShowChinese(3,5,0,32,1); //低 OLED_ShowChinese(35,5,2,32,1);//温 } if(temp_body > BLE_TEMPERATURE_LIMIT_MAX){ OLED_Clear(); //OLED_ShowString(0+5,0+5,(u8 *)"HIGH",32,1); OLED_ShowChinese(3,5,9,32,1); //超 OLED_ShowChinese(35,5,2,32,1);//温 } OLED_Refresh(); } rt_mutex_t app_mode_mutex; void app_enter_ui(app_ui_mode mode){ rt_kprintf("app_mode:%d\r\n",mode); rt_mutex_take(app_mode_mutex, RT_WAITING_FOREVER); if(app_mode == mode){ rt_mutex_release(app_mode_mutex); return; } if(mode != UI_BOX_BATTERY && mode != UI_SHOW_MEMORY_INFO) { rt_kprintf("stop_timer\r\n"); rtos_stop_timer(&timer_battery_refresh); } app_mode = mode; rt_mutex_release(app_mode_mutex); //等待其它页面线程退出 rt_thread_mdelay(50); if(tid_show_wait_temp){ rt_thread_delete(tid_show_wait_temp); tid_show_wait_temp = NULL; } //退出正在进行测温的动画线程 if(tid_show_detect_temp){ rt_thread_delete(tid_show_detect_temp); tid_show_detect_temp = NULL; } switch (mode) { case UI_BOX_BATTERY: app_show_box_battery(); //static int battery_timer_inited = 0; // battery_timer_inited = 1; break; case UI_SHOW_DEVICE_INFO: app_show_temperature_device_info(); break; case UI_SHOW_LOW_BAT_INFO: app_show_low_box_batt(); break; case UI_IDLE: case UI_WAIT_TEMPERATURE: app_show_wait_temperature(); break; case UI_BOX_BIND: app_ui_show_bind(); break; case UI_SHOW_TEMPERATURE: //app_ui_show_temperautre(); app_show_detect_temperature(); break; case UI_SHOW_MEMORY_INFO: app_show_memory_detect_info(); break; default: break; } } void volume_save_record(app_detect_record_t *record){ EfErrCode result = EF_NO_ERR; //char t[sizeof(app_detect_record_t)] = {0x88,0x86,0x89}; //app_detect_record_t record; //record.temperature_value = t_value; char data[32]; rt_memset(data,0,sizeof(data)); rt_sprintf(data,"%d",record->volume); result = ef_set_env(BLE_TEMPERATURE_FLASH_RECORD_KEY_VOLUME, data); result = ef_save_env(); if (result == EF_NO_ERR) { rt_kprintf("volume_save_record success !!!\r\n"); }else{ rt_kprintf("volume_save_record failed !!!\r\n"); } } void volume_read_record(app_detect_record_t *record){ rt_memset(record,0,sizeof(app_detect_record_t)); /*获取easy flash存入的数据*/ char *t = ef_get_env(BLE_TEMPERATURE_FLASH_RECORD_KEY_VOLUME); if(t != NULL){ //rt_kprintf("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9]); //rt_memcpy(record,t,sizeof(app_detect_record_t)); uint8 Volume = atoi(t); record->volume = Volume; }else{ rt_kprintf("volume_read_record error\r\n"); } } /** * 保存最新的一次记录 */ void temperature_save_record(app_detect_record_t *record){ EfErrCode result = EF_NO_ERR; //char t[sizeof(app_detect_record_t)] = {0x88,0x86,0x89}; //app_detect_record_t record; //record.temperature_value = t_value; char data[32]; rt_memset(data,0,sizeof(data)); rt_sprintf(data,"%d",record->temperature_value); result = ef_set_env(BLE_TEMPERATURE_FLASH_RECORD_KEY_TEMPERATURE, data); result = ef_save_env(); if (result == EF_NO_ERR) { rt_kprintf("temperature_save_record success !!!\r\n"); }else{ rt_kprintf("temperature_save_record failed !!!\r\n"); } } /** * 读取最新的一次记录 */ void temperature_read_record(app_detect_record_t *record){ rt_memset(record,0,sizeof(app_detect_record_t)); /*获取easy flash存入的数据*/ char *t = ef_get_env(BLE_TEMPERATURE_FLASH_RECORD_KEY_TEMPERATURE); if(t != NULL){ //rt_kprintf("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9]); //rt_memcpy(record,t,sizeof(app_detect_record_t)); uint16 temp = atoi(t); record->temperature_value = temp; }else{ rt_kprintf("temperature_read_record error\r\n"); } } void wifi_init(); void box_show_ble_device_info(app_temperature_info_t *temperature_info){ OLED_Clear(); //OLED_ShowString(0+5,0+5,(u8 *)"BIND",32,1); OLED_DrawCircle(10,20,10); OLED_ShowString(22,0+5,(u8 *)"30%",24,1); rt_thread_mdelay(1500); } //充电合盖关闭外设(拉跨) void charge_sleep_on(int on) { rt_kprintf("oled_is_on:%d\r\n", oled_is_on); if (oled_is_on != on) { oled_is_on = on; if (on){ //bk_reboot(); OLED_DisPlay_On();//屏幕 voice_player_mute(1); //声音 // OLED_DisPlay_On();//屏幕 // voice_player_mute(1); //声音 // rtos_start_timer(&timer_detect); // bk_wlan_start_sta(BK_STATION); //WIFI //belon_ble_scan_start(); //蓝牙扫描 //belon_ble_start_adv(); //蓝牙广播 }else{ OLED_DisPlay_Off();//屏幕 voice_player_mute(0); //声音 // rtos_stop_timer(&timer_detect); // //bk_wlan_stop(BK_STATION); //WIFI //belon_ble_scan_stop(); //蓝牙扫描 //belon_ble_deinit_adv(); //蓝牙广播 } } } //深度睡眠,没啥卵用 void deep_sleep(){ rt_kprintf("box enter deep sleep!!!\r\n"); voice_player_mute(0); PS_DEEP_CTRL_PARAM deep_sleep_param; rt_memset(&deep_sleep_param, 0, sizeof(deep_sleep_param)); deep_sleep_param.wake_up_way = 1; deep_sleep_param.gpio_index_map = 0; deep_sleep_param.gpio_edge_map = 0; deep_sleep_param.gpio_last_index_map = (1 << (BLE_TEMPERATURE_HALL_DETECT_PIN - 32)); // 38号GPIO deep_sleep_param.gpio_last_edge_map = 0; deep_sleep_param.gpio_stay_lo_map = 0; deep_sleep_param.gpio_stay_hi_map = 0; deep_sleep_param.sleep_time = 0; deep_sleep_param.lpo_32k_src = 0; deep_sleep_param.sleep_mode = 0; // 0=深度睡眠 1=低压睡眠 deep_sleep_param.gpio_last_edge_sel_map = 0; bk_enter_deep_sleep_mode(&deep_sleep_param); //深度睡眠 //bk_wlan_instant_lowvol_sleep(&deep_sleep_param); //低压睡眠--会死机 } void box_poweroff_timeout_callback(void *arg){ rtos_stop_timer(&timer_poweroff); //paho_mqtt_stop(&client); if (box_info.charge_state) { oled_is_on = 1; charge_sleep_on(0); return; } 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 xx:xx:xx:xx:xx:xx */ void box_bind_timeout_callback(void *arg){ rtos_stop_timer(&timer_bind); rt_kprintf("box_bind callback\r\n"); if(ble_found_bind_dev){ char str_bind_mac[32]; rt_memset(str_bind_mac,0,sizeof(str_bind_mac)); rt_sprintf(str_bind_mac,"%02x:%02x:%02x:%02x:%02x:%02x",ble_device_mac[0], ble_device_mac[1], ble_device_mac[2], ble_device_mac[3], ble_device_mac[4], ble_device_mac[5]); bk_printf("BIND: %s\r\n",str_bind_mac); EfErrCode result = EF_NO_ERR; // 将要写入的数据存放到 easy flash 环境变量 result = ef_set_env(BLE_TEMPERATURE_FLASH_CONFIG_KEY_BIND_MAC, str_bind_mac); // 保存数据 result = ef_save_env(); if (result == EF_NO_ERR) { rt_strncpy((char*)box_bind_mac,(char*)str_bind_mac,rt_strlen(str_bind_mac)); voice_player_play_tts(VOICE_CN_BIND_SUCC); OLED_Clear(); // OLED_ShowString(0+15,0+5,(u8 *)"OK",32,1); OLED_ShowChinese(3, 3, 5, 32, 1); // 成 OLED_ShowChinese(35, 3, 6, 32, 1); // 功 OLED_Refresh(); rt_thread_mdelay(1000); } } //app_enter_bind_mode(false); app_enter_ui(UI_IDLE); rt_kprintf("exit bind mode !!!\r\n"); } /* 长时间没有接收到温度广播 则回到等待页面 */ void timer_app_idle_callback(void *arg){ if(app_mode == UI_BOX_BIND){ return; } //app_enter_bind_mode(false); temperature_info.device_state = STATE_DETECT_ING; app_enter_ui(UI_IDLE); rt_kprintf("back idle mode !!!\r\n"); } /** * 检测hall开关状态 判断是否进入绑定模式 * 进入绑定模式后检测接收到的最强一个测温信号设备绑定 */ void timer_hall_detect_callback(void *arg){ int hall = bk_gpio_input(BLE_TEMPERATURE_HALL_DETECT_PIN); //rt_kprintf("hall -> %d\r\n",hall); if(hall_io_state == hall){ return; } hall_io_state = hall; box_info.hall_state = hall; uint32_t now_tick = rt_tick_get() * 1000 / RT_TICK_PER_SECOND; //当前开关盖的tick //rt_kprintf("now_tick :%d\r\n",now_tick); if(hall == 0){ if(!start_bind_detect){ start_bind_detect = 1; } if(hall_key_down_count == 0){//记录第一次开盖的时间 hall_first_down_tick = now_tick; rt_kprintf("hall_first_down_tick :%d\r\n",hall_first_down_tick); }else{ // 判断是否超出5秒 if(now_tick - hall_first_down_tick > HALL_BIND_WINDOW_MS){ hall_key_down_count = 0; hall_first_down_tick = now_tick; } } hall_key_down_count ++; rt_kprintf("detect hall down ,count :%d\r\n",hall_key_down_count); //延迟关机 //启动定时3秒关机 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(!oled_is_on){ //充电时开盖复位设备 charge_sleep_on(1); rt_kprintf("charge_sleep_on(1) !!!\r\n"); } // 只有在5秒内且开关盖次数达到5才进入绑定 if(start_bind_detect && hall_key_down_count == 5 && (now_tick - hall_first_down_tick <= HALL_BIND_WINDOW_MS)){ rt_kprintf("enter bind !!!\r\n"); start_bind_detect = 0; hall_key_down_count = 0; hall_first_down_tick = 0; rt_memset(ble_device_mac,0,sizeof(ble_device_mac)); //收到的信号值 区域0 为越好 ble_device_rssi = -100; //清除找到绑定设备标志 ble_found_bind_dev = 0; //app_enter_bind_mode(true); //进入绑定模式 并启动超时退出 app_enter_ui(UI_BOX_BIND); voice_player_play_tts(VOICE_CN_SEARCH_DEVICE); rtos_start_timer(&timer_bind); } // 如果超时未达到5次,重置开关盖计数器 if(now_tick - hall_first_down_tick > HALL_BIND_WINDOW_MS){ hall_key_down_count = 0; hall_first_down_tick = 0; } } } // 中断触发的回调函数 void box_switch_irq_callback(unsigned char ucChannel) { rt_kprintf("Interrupt triggered!\n"); // 这里可以添加更多的处理逻辑 int hall = bk_gpio_input(BLE_TEMPERATURE_HALL_DETECT_PIN); 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(BLE_TEMPERATURE_HALL_DETECT_PIN); //启动中断失败 //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(){ rt_memset(&box_bind_mac,0,sizeof(box_bind_mac)); /*获取easy flash存入的数据*/ char *t = ef_get_env(BLE_TEMPERATURE_FLASH_CONFIG_KEY_BIND_MAC); if(t != NULL){ rt_memcpy(&box_bind_mac,t,strlen(t)); rt_kprintf("\r\n"); rt_kprintf("BIND TDEVICE:%s\r\n",box_bind_mac); rt_kprintf("\r\n"); }else{ rt_kprintf("easy_flash read error\r\n"); } } static void charger_module_enable(UINT32 enable) { sctrl_analog_set(SCTRL_ANALOG_CTRL4, (sctrl_analog_get(SCTRL_ANALOG_CTRL4) & ~(1 << 12)) | (!!enable << 12)); } void temperature_led_ble(bool onoff){ //GPIO1 if(onoff){ bk_gpio_config_output(1); bk_gpio_output(1,1); }else{ bk_gpio_config_output(1); bk_gpio_output(1,0); } } void record_init(void){ app_detect_record_t record; memset((void *)&record, 0, sizeof(record)); volume_read_record(&record); rt_kprintf("record.volume=%d record.temperature_value=%d record.timestamp=%d\r\n", record.volume,record.temperature_value,record.timestamp); if(record.volume==0&&record.temperature_value==0){ record.volume=70; volume_save_record(&record); } } void temperature_init(void){ extern long list_memheap(void); //rt_thread_mdelay(3000); list_memheap(); //bk_wlan_stop(1); //bk_wlan_stop(0); temperature_led_ble(0); // 查询绑定设备 //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(); //初始化互斥锁 app_mode_mutex = rt_mutex_create("app_mode_lock", RT_IPC_FLAG_FIFO); //初始化HALL按键检测 box_switch_init(); timer_check_device_run_callback(NULL); //霍尔检测 50ms一次 中断不好使 先这样处理 rtos_init_timer(&timer_hall_detect, BLE_TEMPERATURE_HALL_DETECT_INTERVAL, 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); //初始化电量 box_init_power(); //user_app_start(); app_enter_ui(UI_BOX_BATTERY); rt_thread_mdelay(2000); easyflash_init(); ef_print_env(); temperature_dev_config_init(); //app_enter_bind_mode(false); RingQueue_init(&ring_queue); //app_show_last_detect_info(); app_enter_ui(UI_SHOW_MEMORY_INFO); app_show_wait_temperature(); //app_enter_ui(UI_WAIT_TEMPERATURE); //注册WIFI回调 bk_wlan_status_register_cb(wifi_status_cb); //自动联网 //if(wifi_auto_connect) wifi_init(); rt_thread_mdelay(3000); //初始化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, BLE_TEMPERATURE_DETECT_DEVICE_INTERVAL, timer_check_device_run_callback, NULL); rtos_start_timer(&timer_detect); rtos_init_timer(&timer_battery_refresh, 2000, timer_battery_refresh_callback, NULL); //rtos_start_timer(&timer_battery_refresh); //rtos_init_timer(&timer_charge_hell, 300000, timer_hall_detect_callback, NULL); //rtos_start_timer(&timer_charge_hell); charger_module_enable(0); //sctrl_ctrl(CMD_SCTRL_USB_CHARGE_STOP, 0); voice_player_mute(1); voice_player_init(); record_init(); list_memheap(); //belon_ble_scan_stop(); //belon_ble_deinit_adv(); //app_tcp_init(); //app_tcp_connect(); //char m_data[128] ={0x12}; //app_tcp_send(m_data,sizeof(m_data)); //voice_play(1); //rt_thread_mdelay(1000); //voice_play(2); //rt_thread_mdelay(1000); //voice_play(3); //rt_thread_mdelay(1000); /* voice_play(4); rt_thread_mdelay(1000); voice_play(5); rt_thread_mdelay(1000); voice_play(6); rt_thread_mdelay(1000); voice_play(7); rt_thread_mdelay(1000); voice_play(8); rt_thread_mdelay(1000); voice_play(9); rt_thread_mdelay(1000); voice_play(10); rt_thread_mdelay(1000); voice_play(11); rt_thread_mdelay(1000); voice_play(0);*/ }