963 lines
25 KiB
C
963 lines
25 KiB
C
|
||
#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 "sys_ctrl_pub.h"
|
||
#include "sys_ctrl.h"
|
||
#include "target_util_pub.h"
|
||
#include "drv_model_pub.h"
|
||
|
||
#include "app_temperature.h"
|
||
#include "app_voice_player.h"
|
||
#ifdef PKG_USING_EASYFLASH
|
||
#include "easyflash.h"
|
||
#endif
|
||
|
||
#include "saradc_intf.h"
|
||
#include "saradc_pub.h"
|
||
|
||
#include "ring_queue.h"
|
||
#include "opus_encoder.h"
|
||
static app_temperature_info_t temperature_info;
|
||
//static app_dev_info_t dev_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;
|
||
|
||
int start_bind_detect = 0;
|
||
int hall_key_down_count = 0;
|
||
int hall_io_state = 0;
|
||
|
||
static ADC_OBJ box_batt_adc;
|
||
static int box_battery_percent = -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;
|
||
|
||
|
||
/**
|
||
* 当前绑定的设备
|
||
*/
|
||
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 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 跳过!
|
||
if(strstr(str_name,BLE_TEMPERATURE_DEVICE_IT12) == NULL){
|
||
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 == 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);
|
||
}
|
||
|
||
|
||
|
||
//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结构
|
||
}
|
||
//复制设备名称
|
||
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){
|
||
|
||
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(last_body_temp == temp_body){
|
||
//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("\r\n", size);
|
||
//计算平均值
|
||
int sum = 0;
|
||
for(i = 0;i < MAX_SIZE; i++){
|
||
sum += t_datas[i];
|
||
}
|
||
int mean_value = sum / MAX_SIZE;
|
||
bk_printf("mean_value:%d \r\n", mean_value);
|
||
|
||
|
||
//判断温度是否在规定范围
|
||
//if(mean_value < BLE_TEMPERATURE_LIMIT_MIN || mean_value > BLE_TEMPERATURE_LIMIT_MAX){
|
||
// return;
|
||
//}
|
||
|
||
//计算方差
|
||
double sumOfSquares = 0;
|
||
for (int i = 0; i < MAX_SIZE; i++) {
|
||
sumOfSquares += (t_datas[i] - mean_value) * (t_datas[i] - mean_value);
|
||
}
|
||
int variance_value = sumOfSquares / MAX_SIZE; // 注意这里是n,而不是n-1(对于样本方差)
|
||
bk_printf("variance_value:%d \r\n", variance_value);
|
||
//方差小于 20 表示温度稳定 //10
|
||
if(variance_value <= 20){
|
||
//测量完成
|
||
temperature_info.device_state = STATE_DETECT_FINISH;
|
||
bk_printf("detect Finish :%d \r\n", mean_value);
|
||
app_detect_record_t record;
|
||
record.temperature_value = (uint16)mean_value;
|
||
temperature_save_record(&record);
|
||
voice_player_play_tts(VOICE_CN_DETECT_FINISH);
|
||
rt_thread_mdelay(1500);
|
||
voice_player_play_temperature(mean_value);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void timer_temp_run_callback(void *arg){
|
||
|
||
//extern long list_memheap(void);
|
||
//list_memheap();
|
||
}
|
||
|
||
|
||
/**
|
||
* 显示 ... 表示等待
|
||
*/
|
||
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(0+20,0,(u8 *)".",32,1);
|
||
ui_wait_step =2;
|
||
break;
|
||
case 2:
|
||
OLED_ShowString(0+20,0,(u8 *)"..",32,1);
|
||
ui_wait_step =3;
|
||
break;
|
||
case 3:
|
||
OLED_ShowString(0+20,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);
|
||
}
|
||
OLED_Refresh();
|
||
}
|
||
|
||
/**
|
||
* 显示最近一次检测的温度
|
||
*/
|
||
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;
|
||
}
|
||
|
||
OLED_Clear();
|
||
OLED_ShowString(2,1,(u8 *)"M1",16,1);
|
||
char str_temp[12]={0};
|
||
rt_sprintf(str_temp,"%d.%d C\n",record.temperature_value/100,record.temperature_value/10%10);
|
||
//rt_sprintf(str_temp,"")
|
||
//OLED_ShowString(0,18,(u8 *)"36.5 C",24,1);
|
||
OLED_ShowString(0,18,(u8 *)str_temp,24,1);
|
||
OLED_DrawCircle(55,15,4);
|
||
OLED_Refresh();
|
||
rt_thread_mdelay(1000);
|
||
}
|
||
|
||
/**
|
||
* 开机第一次检测到测温设备时 显示设备的名称和电量 然后持续监测温度
|
||
*/
|
||
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_val);
|
||
OLED_ShowString(35,25,(u8 *)str_batt,16,1);
|
||
OLED_Refresh();
|
||
rt_thread_mdelay(2000);
|
||
//app_enter_ui(UI_WAIT_TEMPERATURE);
|
||
}
|
||
/**
|
||
* 显示正在等待测温
|
||
*/
|
||
void app_show_wait_temperature(){
|
||
rt_kprintf("UI->app_show_wait_temperature\r\n");
|
||
if(tid_show_wait_temp){
|
||
rt_thread_detach(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);//整数
|
||
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_ShowChar(61,16,'C',24,1);
|
||
//屏幕上的点(度) 闪烁
|
||
if(ui_show_point){
|
||
OLED_DrawCircle(62,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");
|
||
//退出正在进行的动画线程
|
||
if(tid_show_wait_temp){
|
||
rt_thread_detach(tid_show_wait_temp);
|
||
tid_show_wait_temp = NULL;
|
||
}
|
||
|
||
//退出正在进行测温的动画线程
|
||
if(tid_show_detect_temp){
|
||
rt_thread_detach(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);
|
||
}
|
||
|
||
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();
|
||
}
|
||
void app_enter_ui(app_ui_mode mode){
|
||
if(app_mode == mode){
|
||
return;
|
||
}
|
||
app_mode = mode;
|
||
//等待其它页面线程退出
|
||
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_detach(tid_show_detect_temp);
|
||
tid_show_detect_temp = NULL;
|
||
}
|
||
|
||
switch (mode)
|
||
{
|
||
case UI_BOX_BATTERY:
|
||
app_show_box_battery();
|
||
//app_show_do_detect_temperature();
|
||
break;
|
||
case UI_SHOW_DEVICE_INFO:
|
||
app_show_temperature_device_info();
|
||
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 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 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 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 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(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;
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
// 中断触发的回调函数
|
||
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(){
|
||
|
||
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");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/****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;
|
||
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;
|
||
int batt_max = 4200;
|
||
rt_kprintf("battery_calc --> bat_volt:%d\n",bat_volt);
|
||
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;
|
||
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);
|
||
}
|
||
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_init(void){
|
||
|
||
extern long list_memheap(void);
|
||
list_memheap();
|
||
// 查询绑定设备
|
||
//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));
|
||
box_init_power();
|
||
//初始化GPIO
|
||
gpio_init();
|
||
//初始化OLED显示屏
|
||
OLED_Init();
|
||
// user_app_start();
|
||
rt_thread_mdelay(500);
|
||
while(1){
|
||
if(box_battery_percent >= 0){
|
||
break;
|
||
}
|
||
rt_thread_mdelay(20);
|
||
}
|
||
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_enter_ui(UI_WAIT_TEMPERATURE);
|
||
|
||
//初始化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_INTERVAL, timer_temp_run_callback, NULL);
|
||
rtos_start_timer(&timer_detect);
|
||
|
||
|
||
|
||
//初始化HALL按键检测
|
||
box_switch_init();
|
||
//霍尔检测 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);
|
||
|
||
charger_module_enable(0);
|
||
//sctrl_ctrl(CMD_SCTRL_USB_CHARGE_STOP, 0);
|
||
voice_player_mute(1);
|
||
voice_player_init();
|
||
|
||
list_memheap();
|
||
|
||
|
||
//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);*/
|
||
}
|