专栏首页腾讯云IoT【AIoT应用创新大赛-基于TencentOS Tiny 的智能取暖器】
原创

【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显示屏内容的更换,这里用消息队列来接收按键的消息

四.云平台

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

物模型:

智能取暖器物模型

腾讯连连面板:

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

五.演示视频:

视频内容

六.致谢

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

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

登录 后参与评论
0 条评论

相关文章

  • AIoT应用创新大赛-基于TencentOS Tiny Locator

    项目代码: TOS-AIOT: TencentOS-Tiny,RT1062,SX1276,ESP8266 (gitee.com)

    用户5503541
  • AIoT应用创新大赛-基于TencentOS Tiny的智能车钥匙

    UWB数字钥匙是全新的无钥匙进入系统,在接近车辆时,根据距离车辆会自动首先开启迎宾灯,然后随着距离的接近,会自动调整座椅位置等,然后靠近车门时,则自动解锁;当远...

    大盛
  • AIoT应用创新大赛-基于TencentOS Tiny的智能车钥匙

    UWB数字钥匙是全新的无钥匙进入系统,在接近车辆时,根据距离车辆会自动首先开启迎宾灯,然后随着距离的接近,会自动调整座椅位置等,然后靠近车门时,则自动解锁;当远...

    大盛
  • AIoT应用创新大赛-基于TencentOS Tiny 的智能图书漂流箱

    基于TencentOS Tiny,实现自动登记图书漂流会员和图书,并自动绑定人物与书籍的所属关系,留存开锁取放图书的视频监控截图,登记到图书漂流网。另外,实现自...

    三宝殿
  • AIoT应用创新大赛-基于TencentOS Tiny AIoT 手写数字识别

    很荣幸这次能拿到AIoT应用创新大赛的初赛资格。 深度学习和机器学习在安防、金融、消费等各个方面有着广泛的应用。随着神经网络算法的发展,模型精度越来越高,但是模...

    用户9281026
  • AIoT应用创新大赛-基于TencentOS Tiny的护眼台灯

    现如今由于新冠疫情影响,疫情催生着在线教育,让很多学习场景从学校、教室转移至家庭、宿舍。作为开学即隔离的学生党感受颇深QAQ,每天的网课和作业对用眼需求更大,昏...

    JGMMS
  • AIoT应用创新大赛-基于TencentOS Tiny 的遥控小车

    很早就有做个智能小车的想法,但由于时间有限和囊中羞涩,一直没有付出行动,感谢腾讯TencentOS Tiny团队的信任,给了这么一次机会,虽然离自己的设想的功能...

    用户9320370
  • AIoT应用创新大赛-基于TencentOS Tiny 的智慧灯

    snprintf(report_buf, sizeof(report_buf), REPORT_DATA_TEMPLATE, lux);

    百特曼
  • AIoT应用创新大赛-基于TencentOS Tiny AIoT NXP自动摄像仪

    TencentOS tiny联合NXP推出的RT1062开发板让人眼前一亮,能够实现众多的强大功能,但是我只能选取一瓢来实现本次比赛的作品。看到摄像头的功能,和...

    极速紫韵
  • AIoT应用创新大赛-基于TencentOS Tiny的PCB加热台

    非常感谢 腾讯TencentOS 团队、恩智浦半导体、安谋科技(Arm China)、腾讯连连 组织了这一次大赛。也很荣幸获得了参赛资格,有机会接触到RT106...

    忙碌的死龙
  • AIoT应用创新大赛-基于TencentOS Tiny 人脸计数的实践

    这次的项目主要是对比赛提供的资源的一次简单实践,将摄像头所识别的人脸数目传送到微信小程序上,模型是提前训练好的,在比赛的板子上进行推理,然后将识别到的人数,以j...

    用户8204584
  • AIoT应用创新大赛-基于TencentOS Tiny 的智能家居中控

    随着科技水平的不断提高,生活水平的改善,智能家居产品正在不断走进日常生活。智能家居可以让家电更智能,更能让生活更舒适。智能家居也是互联网不断深化发展的产物。互联...

    羽翰尘
  • AIoT应用创新大赛-基于TencentOS Tiny 疫情显示系统

    2022年,新冠疫情卷土重来,家乡山东都在抗疫,作为志愿者,抽空写报告。基于TencentOS 加持LVGL,做新冠疫情显示平台。实现疫情数据的获取,数据的图表...

    用户9552019
  • AIoT应用创新大赛-基于TencentOS Tiny 的人脸识别应用

    如上图所示,硬件部分由TencentOS Tiny官方的RT1062开发板,OV5640摄像头,LCD显示屏等组成;其中: TencentOS Tiny官方的R...

    用户6354611
  • AIoT应用创新大赛-基于TencentOS Tiny xxx方案、软件、产品

    https://cloud.tencent.com/developer/competition/introduction/10032?subTab=2

    用户1274637
  • AIoT应用创新大赛-基于TencentOS Tiny 蓝牙网关llsync(二)

    这篇文章主要介绍llsync SDK的移植到其他协议栈需要理解的部分。属于移植到其他协议栈或者其他芯片的时候,需要做的前期的预习准备工作。理解本文,基本上可以知...

    用户9526019
  • AIoT应用创新大赛-基于TencentOS Tiny 蓝牙方案llsync(一)

    llsync是一款智能家居产品,用于蓝牙相关的,通过蓝牙接入腾讯连连小程序的一款SDK。可以通过蓝牙来点灯,与其他的蓝牙example不同的是,这个可以移植到很...

    用户9526019
  • AIoT应用创新大赛-基于TencentOS Tiny 香水定制机方案

    人们对生活品味的提升,个性的解放,结合物联网新技术,为个人提供差异化服务,香水作为女性日常消费的一部分,存在市场需求。本定制机依据香水调制的一般原理,提供便捷的...

    用户1258616
  • AIoT应用创新大赛-基于TencentOS Tiny 实时手语交互方案

    AIoT创新应用比赛是一个命题作文,AIoT = AI + IoT 是基本了解;要求使用RT1062和TencentOS-tiny是限制条件,也是IDEA创意的...

    flavorfan

扫码关注腾讯云开发者

领取腾讯云代金券