【AIoT应用创新大赛-基于TencentOS Tiny 的智能取暖器】

首先奉上精美PPT

腾讯AIOT应用创新大赛-智能取暖器.ppt

前言:

取暖器在我们日常生活中已经很常见了,冬天的保命法宝,但是平时浏览新闻的时候发现因取暖器使用不当造成人身财产安全问题的事件频频出现,严重的威胁到生命安全,基于此种现象,此次大赛特设计一款可以接入腾讯云平台的智能取暖器,不仅可以通过手机远程操作取暖器是否工作,还能辅助日常感知环境温度,结合智能硬件带来的智能关停,智能联动提升安全性的同时更让生活多姿多彩.

一. 设计思路

本次结合腾讯AIOT开发板,通过自购的发热丝,温度传感器,液晶显示屏等组成,温湿度传感器负责检测环境温湿度,将数据传送给开发板,主机将该数据显示在液晶显示屏的同时上传到腾讯云物联网平台(以下简称云平台),我们可以通过腾讯连连小程序或者从云平台上的在线调试功能发出指令,控制取暖器的开关,同时腾讯连连还有智能场景功能,可以设置智能场景当温度超过制定值的时候让设备自动关闭加热.

以下是设备图片:

智能取暖器-设备展示

元器件展示:

智能取暖器-元器件

二.原理介绍

系统框架如如下所示:

智能取暖器系统框架图

固件端主要框架:

三.代码介绍:

代码采用keil编辑器编译及编辑,从TencentOS Tiny主仓库拉取,结合Qcloud_SDK_3.20连接云平台收发数据

关于为何使用qcloud_sdk而没有用官方的mqttdemo,看这篇文章:https://cloud.tencent.com/developer/article/1946203

由以下代码启动加云线程


void *data_template_light_thread(const char *arg)
{
	DeviceProperty *pReportDataList[TOTAL_PROPERTY_COUNT];
	int ReportCont;
	Timer reportTimer;
	int rc;
	sReplyPara replyPara;
	//printf("ddffffffffff\n");

	//init connection
	TemplateInitParams init_params = {
		"china", USING_TENCENT_IOT_EXPLORER_PRODUCT_ID, USING_TENCENT_IOT_EXPLORER_DEVICE_NAME, USING_TENCENT_IOT_EXPLORER_DEVICE_SECRET, 2000, 240 * 1000, 1, 1, {0}, NULL};
	rc = _setup_connect_init_params(&init_params);
	if (rc != QCLOUD_RET_SUCCESS)
	{
		Log_e("init params err,rc=%d", rc);
		return NULL;
	}

	void *client = IOT_Template_Construct(&init_params, NULL);
	if (client != NULL)
	{
		led_on(led_green);
		Log_i("Cloud Device Construct Success");
	}
	else
	{
		Log_e("Cloud Device Construct Failed");
		return NULL;
	}
	

	//init data template
	_init_data_template();


#ifdef EVENT_POST_ENABLED
	rc = IOT_Event_Init(client);
	if (rc < 0)
	{
		Log_e("event init failed: %d", rc);
		return NULL;
	}

#endif

	//register data template propertys here
	rc = _register_data_template_property(client);

	if (rc == QCLOUD_RET_SUCCESS)
	{
		Log_i("Register data template propertys Success");
	}
	else
	{
		Log_e("Register data template propertys Failed: %d", rc);
		return NULL;
	}

	//register data template actions here
#ifdef ACTION_ENABLED
	rc = _register_data_template_action(client);

	if (rc == QCLOUD_RET_SUCCESS)
	{
		Log_i("Register data template actions Success");
	}
	else
	{
		Log_e("Register data template actions Failed: %d", rc);
		return NULL;
	}
#endif

	rc = IOT_Template_GetStatus_sync(client, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);

	if (rc != QCLOUD_RET_SUCCESS)
	{
		Log_e("get device shadow failed, err: %d", rc);
		return NULL;
	}

	InitTimer(&reportTimer);
	
	running_state = 1;
	while (IOT_Template_IsConnected(client) || rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT || rc == QCLOUD_RET_MQTT_RECONNECTED || QCLOUD_RET_SUCCESS == rc)
	{

		if (0 == running_state)
		{
			break;
		}

	//	sg_ProductData.m_ill = 0;//getIllumination();
		
		rc = IOT_Template_Yield(client, 2000);
		if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT)
		{
			tos_task_delay(tos_millisec2tick(1000));
			continue;
		}
		else if (rc != QCLOUD_RET_SUCCESS)
		{
			Log_e("Exit loop caused of errCode: %d", rc);
		}

		/*鏈嶅姟绔笅琛屾秷鎭紝涓氬姟澶勭悊閫昏緫1鍏ュ彛*/
	
		if (sg_control_msg_arrived) //(sg_delta_arrived)
		{

			deal_down_stream_user_logic(&sg_ProductData);

			/*涓氬姟閫昏緫澶勭悊瀹屽悗闇�瑕佸悓姝ラ�氱煡鏈嶅姟绔�:璁惧鏁版嵁宸叉洿鏂帮紝鍒犻櫎dseire鏁版嵁*/
			memset((char *)&replyPara, 0, sizeof(sReplyPara));
			replyPara.code = eDEAL_SUCCESS;
			replyPara.timeout_ms = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
			replyPara.status_msg[0] = '\0'; // add extra info to replyPara.status_msg when error occured

			rc = IOT_Template_ControlReply(client, sg_data_report_buffer, sg_data_report_buffersize, &replyPara);
			
			if (rc == QCLOUD_RET_SUCCESS)
			{
			
				sg_control_msg_arrived = false;
		
			}
			else
			{
				Log_e("construct desire failed, err: %d", rc);
			}
		}
		else
		{
			//Log_d("No delta msg received...");
		}

		/*璁惧涓婅娑堟伅,涓氬姟閫昏緫2鍏ュ彛*/
		/*delta娑堟伅鏄睘鎬х殑desire鍜屽睘鎬х殑report鐨勫樊寮傞泦锛屾敹鍒癲eseire娑堟伅澶勭悊鍚庯紝瑕乺eport灞炴�х殑鐘舵��*/
		if (QCLOUD_RET_SUCCESS == deal_up_stream_user_logic(pReportDataList, &ReportCont))
		{
		
			Log_d("report:%s", sg_data_report_buffer);
			rc = IOT_Template_JSON_ConstructReportArray(client, sg_data_report_buffer, sg_data_report_buffersize,
														ReportCont, pReportDataList);
			
			if (rc == QCLOUD_RET_SUCCESS)
			{
				rc = IOT_Template_Report(client, sg_data_report_buffer, sg_data_report_buffersize,
										 OnReportReplyCallback, NULL, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
				
				if (rc == QCLOUD_RET_SUCCESS)
				{
					Log_i("IOT_Template_Report success");
				}
				else
				{
					Log_e("IOT_Template_Report failed, err: %d", rc);
				}
			}
			else
			{
				Log_e("construct reported failed, err: %d", rc);
			}
		}
		else
		{
			Log_d("no data need to be reported");
			ReportCont = TOTAL_PROPERTY_COUNT;
		}

		/*cycle report, just for example*/
		if (QCLOUD_RET_SUCCESS == cycle_report(pReportDataList, &reportTimer))
		{

			rc = IOT_Template_JSON_ConstructReportArray(client, sg_data_report_buffer, sg_data_report_buffersize,
														ReportCont, pReportDataList);
			if (rc == QCLOUD_RET_SUCCESS)
			{
				rc = IOT_Template_Report(client, sg_data_report_buffer, sg_data_report_buffersize,
										 OnReportReplyCallback, NULL, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
				if (rc == QCLOUD_RET_SUCCESS)
				{
					Log_i("IOT_Template_Report success");
				}
				else
				{
					Log_e("IOT_Template_Report failed, err: %d", rc);
				}
			}
			else
			{
				Log_e("construct reported failed, err: %d", rc);
			}
		}

#ifdef EVENT_POST_ENABLED

		// extern int32_t g_temp;

//		sg_ProductData.m_temp = g_temp;
//		sg_temp = g_temp;
		

	//	eventPostCheck(client);
#endif

		printf(">>>>>>>>> delay\n");
		tos_task_delay(tos_millisec2tick(1000));
	}

	rc = IOT_Template_Destroy(client);
	running_state = 0;
	Log_e("Something goes wrong or stoped");
	//rt_thread_delete(rt_thread_self());

	return NULL;
}

再看下控制led灯的:


#define LED_RED_PORT 31 //IOMUXC_GPIO_B1_15_GPIO2_IO31
#define LED_RED_GREEN_PORT 15 //IOMUXC_GPIO_AD_B0_15_GPIO1_IO15
#define LED_RED_YELLOW_PORT 17 //IOMUXC_GPIO_SD_B0_05_GPIO3_IO17

static int light_state = 0;


void led_init(){
	IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0U); 
	IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_GPIO1_IO15, 0U); 
	IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_GPIO3_IO17, 0U); 
	
    gpio_pin_config_t config = {
		.direction = kGPIO_DigitalOutput,
		.outputLogic = 0,
		.interruptMode = kGPIO_NoIntmode,
	};
    GPIO_PinInit(GPIO2, 31, &config);
	GPIO_PinInit(GPIO1, 15, &config);
	GPIO_PinInit(GPIO3, 17, &config);
	

    
}

void led_on(led_name led)
{
	if(led == led_red){
		GPIO_PinWrite(GPIO2, 31, (uint8_t )1);
	}else if(led == led_green){
		GPIO_PinWrite(GPIO1, 15, (uint8_t )1);
	}else if(led == led_yellow){
		GPIO_PinWrite(GPIO3, 17, (uint8_t )1);
	}
}

void led_off(led_name led){
		if(led == led_red){
		GPIO_PinWrite(GPIO2, 31, (uint8_t )0);
	}else if(led == led_green){
		GPIO_PinWrite(GPIO1, 15, (uint8_t )0);
	}else if(led == led_yellow){
		GPIO_PinWrite(GPIO3, 17, (uint8_t )0);
	}
}

控制加热丝的:


static uint8_t heater_state = 0;

void heater_init(){
	IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_GPIO3_IO26, 0U); 
	
    gpio_pin_config_t config = {
		.direction = kGPIO_DigitalOutput,
		.outputLogic = 1,
		.interruptMode = kGPIO_NoIntmode,
	};
    GPIO_PinInit(GPIO3, 26, &config);
}

int heater_toggle(){
	if(heater_state)
	{
		heater_off();
		heater_state = 0;
	}else{
		heater_on();
		heater_state = 1;
	}
	
	return heater_state;
	
}
void heater_on()
{
	GPIO_PinWrite(GPIO3, 26, (uint8_t )0);
}
void heater_off()
{
	GPIO_PinWrite(GPIO3, 26, (uint8_t )1);
	
}

温湿度传感器:


void DelayUs(uint32_t us)
{
	CPU_TS_Tmr_Delay_US(us);
}

void DelayMs(uint32_t ms)
{
	DelayUs(ms*1000);
}


static int sht20_SendData(uint8_t* data, size_t size)
{
	int reVal =0;
	
	lpi2c_master_transfer_t transfer={0};
	
	transfer.flags = 0;                   /*!< Transfer flag which controls the transfer, reserved for FlexIO I2C. */
    transfer.slaveAddress = 0x38;             /*!< 7-bit slave address. */
    transfer.direction = kLPI2C_Write; /*!< Transfer direction, read or write. */
    transfer.subaddress =NULL;              /*!< Sub address. Transferred MSB first. */
    transfer.subaddressSize = 0;           /*!< Size of command buffer. */
    transfer.data = data;           /*!< Transfer buffer. */
    transfer.dataSize = size;         /*!< Transfer size. */
//	FLEXIO_I2C_MasterEnable(&base, true);
	reVal = LPI2C_MasterTransferBlocking(LPI2C1, &transfer);
	
	return reVal;
}
static int sht20_ReadData(uint32_t addr,uint8_t addrsize,uint8_t* data, size_t size)
{
	int reVal =0;
	
	lpi2c_master_transfer_t transfer={0};
	
	transfer.flags = 0;                   /*!< Transfer flag which controls the transfer, reserved for FlexIO I2C. */
    transfer.slaveAddress = 0x38;             /*!< 7-bit slave address. */
    transfer.direction = kLPI2C_Read; /*!< Transfer direction, read or write. */
    transfer.subaddress =addr;              /*!< Sub address. Transferred MSB first. */
    transfer.subaddressSize = addrsize;           /*!< Size of command buffer. */
    transfer.data = data;           /*!< Transfer buffer. */
    transfer.dataSize = size;         /*!< Transfer size. */
//	FLEXIO_I2C_MasterEnable(&base, true);
	reVal = LPI2C_MasterTransferBlocking(LPI2C1, &transfer);
	
	return reVal;
}



int sht20_cmd_send()
{
	uint8_t cmd[2]={};
	sht20_SendData(cmd,sizeof(cmd));
		
}

uint8_t sht20_init()
{
	
	int ret = -1;
	uint8_t rdata[10] = {0};
//	ret = sht20_SendData(0x71 ,1);
//	printf("send 71 ret = %d\n");
	ret = sht20_ReadData(0,0,rdata,1);
	printf("read ret = %d,rdata=%02x\n",ret,rdata[0]);
	if(ret != 0)
	{
		return ret;
	}
	
	if(((rdata[0]>>3) & 0x01) ==0)
	{
		uint8_t sdata[3]={0xbe,0x08,0x00};
		ret = sht20_SendData(sdata ,sizeof(sdata));
		printf("sht20_SendData ret = %d\n");
		
	}
	
	return ret;
	
}

uint8_t sht20_get_temp_humi(uint32_t *temp,uint32_t *humi)
{
	int ret = 0;
	uint8_t sdata[3]={0xac,0x33,0x00};
	
	ret = sht20_SendData(sdata ,sizeof(sdata));
	printf(">> sht20_SendData ret = %d\n",ret);
	
	DelayMs(80);
	
	uint8_t rdata[10] = {0};
//	ret = sht20_SendData(0x71 ,1);
//	printf("send 71 ret = %d\n");
//	while(1){
		
		ret = sht20_ReadData(0,0,rdata,1);
//		printf(">>read ret = %d,rdata=%02x\n",ret,rdata[0]);
//		if(((rdata[0]>>7) & 0x01) ==0)
//		{
			
			ret = sht20_ReadData(0,0,rdata ,6);
//			printf("--sht20_ReadData ret = %d\n",ret);
			printf("temp data %02x %02x %02x %02x %02x %02x\n",
					rdata[0],rdata[1],rdata[2],rdata[3],rdata[4],rdata[5]);

			unsigned int dat1 = 0;  // ??
			unsigned int dat2 = 0;  // ??
			

//			

			dat1 = (dat1 | rdata[1]) << 8;
			dat1 = (dat1 | rdata[2]) << 8;
			dat1 = (dat1 | rdata[3]) >> 4;

			dat2 = (dat2 | rdata[3]) << 8;
			dat2 = (dat2 | rdata[4]) << 8;
			dat2 = (dat2 | rdata[5]) & 0xfffff;
	//		printf("data1 = %08x %d,data2 = %08x %d\n",dat1,dat1,dat2,dat2);

			*humi = (dat1*1000) / 1048576;                 // ??
			*temp = (dat2*2000) / 1048576  - 500;     // ??


			

	
	return ret;
	
}

其中的us级延迟使用了DWT功能

接下来是液晶显示模块:

#define QRCODE_VERSION 6

typedef struct element_info{
	uint8_t x;
	uint8_t y;
	uint8_t w;
	uint8_t h;
	uint32_t dataLen;
	void *data;
}element_info_t;

#define PAGE_0_TITLE_INDEX 0

//element_info_t page_0[4];
//element_info_t page_1[4];
struct {
	element_info_t title;
	element_info_t temp_text;
	element_info_t humi_text;
	element_info_t state_text;
//	element_info_t temp;
//	element_info_t humi;
	element_info_t state;
}page0;

struct {
	element_info_t title;
//	element_info_t info;
	element_info_t qrcode;
//	element_info_t time;
//	element_info_t ip;
}page1;

static int g_page_index = 0;

static char temp_str[8]={'2','5','.','3'};
static char humi_str[8]={'5','8','.','9'};


void init_page0(){
	
	element_info_t *ele=&page0.title;
	ele->x = 20;
	ele->y = 0;
	ele->w = 128;
	ele->h = 16;
	ele->dataLen = 5;
	ele->data = page_title;
	
	ele=&page0.temp_text;
	ele->x = 10;
	ele->y = 16;
	ele->dataLen = 3;
	ele->data = temp_text;
	
	ele=&page0.humi_text;
	ele->x = 10;
	ele->y = 32;
	ele->dataLen = 3;
	ele->data = humi_text;

	ele=&page0.state_text;
	ele->x = 10;
	ele->y = 48;
	ele->dataLen = 3;
	ele->data = state_text;
	
	
//	ele=&page0.temp;
//	ele->x = 60;
//	ele->y = 16;
//	ele->dataLen = 3;
//	ele->data = temp_str;
//	
//	ele=&page0.humi;
//	ele->x = 60;
//	ele->y = 32;
//	ele->dataLen = 3;
//	ele->data = humi_str;

	ele=&page0.state;
	ele->x = 60;
	ele->y = 48;
	ele->dataLen = 2;
	ele->data = state_stop;
	
}

void init_page1()
{
	element_info_t *ele=&page1.title;
	ele->x = 0;
	ele->y = 0;
	ele->w = 128;
	ele->h = 16;
	ele->dataLen = 8;
	ele->data = welcom_msg;
}
static k_msg_q_t msg_q ;
static k_err_t err;
void set_temp_humi(uint32_t temp,uint32_t humi)
{
	sprintf(temp_str,"%02d.%d",temp/10,temp%10);
	sprintf(humi_str,"%02d.%d",humi/10,humi%10);
	err = tos_msg_q_post(&msg_q, NULL);
}

void set_heater_state(int state)
{
	page0.state.data=state?state_open:state_stop;
	err = tos_msg_q_post(&msg_q, NULL);
}

static int page_index=0;

void set_page_index(int index)
{
	page_index=index?1:0;
	err = tos_msg_q_post(&msg_q, NULL);
}

void set_page_switch()
{
	
	set_page_index(page_index?0:1);
}
void show_chineseLine(int x,int y,int len,uint8_t *data)
{
	int num = 0;
	while(num<len){
		ssd1306_DrawRegion(x, y,  font_width ,font_height ,data,Chinese_Char_size , 0);
		x += font_width;
	//	y=y + font_width;
		data += Chinese_Char_size;
		num++;
	}
}

void show_page0(){
	
	show_chineseLine(page0.title.x,page0.title.y,page0.title.dataLen,(uint8_t *)(page0.title.data));
	show_chineseLine(page0.temp_text.x,page0.temp_text.y,page0.temp_text.dataLen,(uint8_t *)(page0.temp_text.data));
	show_chineseLine(page0.humi_text.x,page0.humi_text.y,page0.humi_text.dataLen,(uint8_t *)(page0.humi_text.data));
	show_chineseLine(page0.state_text.x,page0.state_text.y,page0.state_text.dataLen,(uint8_t *)(page0.state_text.data));
	
//	sprintf(temp_str,"%d.%d",20,0);
//	sprintf(humi_str,"%d.%d",20,0);
	ssd1306_SetCursor(56, 16);
	ssd1306_DrawString(temp_str, Font_11x18, White) ;
	ssd1306_SetCursor(56, 32);
	ssd1306_DrawString(humi_str, Font_11x18, White) ;

	show_chineseLine(page0.state.x,page0.state.y,page0.state.dataLen,(uint8_t *)(page0.state.data));
}

QRCode qrcode;
char *qrcode_msg="DIY:Signx WX:cszzlsw  MSG:TencentOS Tiny Study!  \r\n";
char *qrcode_bytes;

void show_page1(){
	
	show_chineseLine(page1.title.x,page1.title.y,page1.title.dataLen,(uint8_t *)(page1.title.data));

	ssd1306_DrawRegion(40, 16, qrcode.size, qrcode.size, qrcode_bytes,qrcode_getBufferSize(QRCODE_VERSION), 0);
//	sprintf(temp_str,"%d.%d",20,0);
//	sprintf(humi_str,"%d.%d",20,0);
//	ssd1306_SetCursor(56, 16);
//	ssd1306_DrawString(temp_str, Font_11x18, White) ;
//	ssd1306_SetCursor(56, 32);
//	ssd1306_DrawString(humi_str, Font_11x18, White) ;

//	show_chineseLine(page0.state.x,page0.state.y,page0.state.dataLen,(uint8_t *)(page0.state.data));
}


static void OLedTask(void *arg)
{	
	printf(">> OLedTask start!\n");
	//ssd1306_Init();
	
//	int buffer_size=qrcode_getBufferSize(QRCODE_VERSION);
//	printf("qrcode buffer_size = %d\n",buffer_size);
//	uint8_t qrcodeBytes[buffer_size] ;
	


	// Allocate a chunk of memory to store the QR code
	err = tos_msg_q_create_dyn(&msg_q, 10);
	
	
	int buffer_size=qrcode_getBufferSize(QRCODE_VERSION);
	printf("qrcode buffer_size = %d\n",buffer_size);
	uint8_t qrcodeBytes[buffer_size] ;
	qrcode_initText(&qrcode, qrcodeBytes, QRCODE_VERSION, ECC_QUARTILE, qrcode_msg);
	qrcode_bytes=qrcodeBytes;

	init_page0();
	init_page1();
	while(1)
	{
		msgq_data *data;
		err = tos_msg_q_pend(&msg_q, &data, tos_millisec2tick(1000));
		if(err == K_ERR_NONE)
		{
			
		}
		ssd1306_Fill(Black);
		ssd1306_SetCursor(0, 0);
		printf("page:%d\n",page_index);
		if(page_index) { 
			show_page1() ;
		} else{
			show_page0();
		}
		ssd1306_UpdateScreen();
			
		
	//	HAL_SleepMs(1350);
		
	}
	
}

	

其余细节就不贴出来了,

下面是按键检测部分:

typedef enum{
	btn_action_click
	
}btn_action;

typedef enum{
	btn_heater_onoff,
	btn_page_switch,
	btn_mute,
	
}btn_name;

typedef struct btn_event
{
	btn_name btn;
	btn_action action;
}btn_event_t;

#endif
extern void HAL_SleepMs( uint32_t ms);

/* ??????????PAD?? */
#define KEY_PAD_CONFIG_DATA            (SRE_0_SLOW_SLEW_RATE| \
                                        DSE_0_OUTPUT_DRIVER_DISABLED| \
                                        SPEED_2_MEDIUM_100MHz| \
                                        ODE_0_OPEN_DRAIN_DISABLED| \
                                        PKE_1_PULL_KEEPER_ENABLED| \
                                        PUE_1_PULL_SELECTED| \
                                        PUS_3_22K_OHM_PULL_UP| \
                                        HYS_1_HYSTERESIS_ENABLED)   

void button_init()
{
	IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_00_GPIO1_IO00, 0U); //mute
	IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_11_GPIO1_IO11, 0U); //heater
	IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_GPIO4_IO20, 0U);   //switch_page
	
	IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_00_GPIO1_IO00, KEY_PAD_CONFIG_DATA);//0x10B0U
	IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_11_GPIO1_IO11, KEY_PAD_CONFIG_DATA);//0x10B0U
	IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_20_GPIO4_IO20, KEY_PAD_CONFIG_DATA);//0x10B0U
//	
    gpio_pin_config_t config = {
		.direction = kGPIO_DigitalInput,
		.outputLogic = 0,
		.interruptMode = kGPIO_NoIntmode,
	};
	
    GPIO_PinInit(GPIO1, 0, &config);
	GPIO_PinInit(GPIO1, 11, &config);
	GPIO_PinInit(GPIO4, 20, &config);
}
msgq_data data;
void* button_task(void *arg)
{
	printf("button_task start...\n");
	btn_event_t event={0};
	
	button_init();
	
	k_msg_q_t *msg_q = arg;
	k_err_t err;

	while(1)
	{
		int event_flag = 0;
		if( GPIO_PinRead(GPIO1, 0) == 0)
		{
					tos_task_delay(tos_millisec2tick(50));
			if( GPIO_PinRead(GPIO1, 0) == 1) continue;
			event.action = btn_action_click;
			event.btn = btn_mute;
			event_flag = 1;
			printf(">> btn_mute clicked\n");
		}
		if( GPIO_PinRead(GPIO1, 11) == 0)
		{
					tos_task_delay(tos_millisec2tick(50));
			if( GPIO_PinRead(GPIO1, 11) == 1) continue;
			event.action = btn_action_click;
			event.btn = btn_heater_onoff;
			event_flag = 1;
			printf(">> btn_heater clicked\n");
		}
		if( GPIO_PinRead(GPIO4, 20) == 0)
		{
			HAL_SleepMs(50);
			if( GPIO_PinRead(GPIO4, 20) == 1) continue;
			event.action = btn_action_click;
			event.btn = btn_page_switch;
			event_flag = 1;
			printf(">> btn_page_switch clicked\n");
		}
		
		if(event_flag)
		{
			//send_event
			
			data.msgq_type= msgq_type_button;
			data.msgq_data = &event;
			err = tos_msg_q_post(msg_q, &data);
			printf("button msgq post ret =%d\n",err);
			//wait for release
			while(( GPIO_PinRead(GPIO4, 20) == 0) || ( GPIO_PinRead(GPIO1, 11) == 0)
				|| ( GPIO_PinRead(GPIO1, 0) == 0)){
							tos_task_delay(tos_millisec2tick(1));
				}
		}
		
		tos_task_delay(tos_millisec2tick(1));
		
	}
	
	
}

按键检测这里用到了消息队列,通过消息队列将按键的输入消息发出去给主线程处理:


void application_entry(void *arg)
{
	printf("application_entry---\r\n");
//	light_init();
	led_init();
	oled_start();
	buzzer_init();  
	heater_init();
	k_err_t err;

	err = tos_msg_q_create_dyn(&msg_q, 10);
	printf("msg_q create ret = %d\n",err);
	
	
	printf(">> HAL_ThreadCreate\n");

    k_task_t *thread = tos_mmheap_alloc(sizeof(k_task_t));
    k_stack_t *thread_stack = (k_stack_t*) tos_mmheap_alloc(1024);
    
    err = tos_task_create((k_task_t *)thread, 
						(char*)"oled", 
                         button_task,
                          &msg_q,
                          8, 
                          thread_stack,
                          1024,
                          0);
	printf("tos_task_create err = %d\n",err);
						

	sht20_init();
						

//	buzzer_on();
						
    iot_thread_start(NULL);
	

	uint32_t temp,humi;
	int i=0;
	
    while (1) {
   //     printf(">>>This is a mqtt demo!\r\n");
	//	Dht11Show();
		msgq_data *data;
		err = tos_msg_q_pend(&msg_q, &data, tos_millisec2tick(1000));
		if(err == K_ERR_NONE)
		{
			printf("msqq_success\n");
			if(data->msgq_type == msgq_type_button){
				btn_event_t *event=data->msgq_data;
				if(event->btn==btn_heater_onoff)
				{
					int state = heater_toggle();
					set_heater_state(state);
					if(state){
						led_on(led_yellow);
						
					}else{
						
						led_off(led_yellow);
					}
					sg_ProductData.m_state = state;
				}
				if(event->btn==btn_page_switch)
				{
					int state =heater_toggle();
					set_page_switch();
				}
				if(event->btn==btn_mute)
				{
					buzzer_off();
				}
				
				
			}
		}
		sht20_get_temp_humi(&temp,&humi);
		printf("temp=%d,humi=%d\n",temp ,humi);
		set_temp_humi(temp,humi);
		sg_ProductData.m_temp = temp*1.0/10;
		sg_ProductData.m_humi = humi*1.0/10;
		
		if(temp >= 600){
			buzzer_on();
		//	IOT_Event_setFlag(client,FLAG_EVENT0);
		}
		
	//	i++;
//		
      //  HAL_SleepMs(1000);
    }
}

可见主线程处理了温湿度,按键,以及oled显示屏内容的更换,这里用消息队列来接收按键的消息

四.云平台

云平台主要是配置物模型和腾讯连连的显示面板,没有太多需要介绍的内容

物模型:

智能取暖器物模型

腾讯连连面板:

都处理完成之后就可以实际演示了

五.演示视频:

视频内容

六.致谢

以上就是作品的全部内容了,感谢大赛组委会派发的开发板,碍于时间关系没有发挥出开发板的全部实力,后续有时间争取做出更好的作品,敬请期待吧.

合智互联客户成功服务热线:400-1565-661

admin
admin管理员

上一篇:tflite模型PC端与嵌入式交叉验证
下一篇:AIoT应用创新大赛-基于TencentOS Tiny的办公区厕所蹲位监控系统

留言评论

暂无留言