概述
為解決寢室空調(diào)總是忘關(guān)的問題,基于HMI-Board設(shè)計(jì)了一款智能空調(diào)管理器,可通過onenet指令下發(fā)實(shí)現(xiàn)遠(yuǎn)程關(guān)閉空調(diào)。
設(shè)計(jì)思路
HMI-Board使用板載RW-007WiFi模塊,通過MQTT協(xié)議連接Onenet平臺,上報(bào)當(dāng)前狀態(tài)信息,接收并解析Onenet平臺的下發(fā)指令??蛻舳诉M(jìn)入Onenet云平臺,可查閱HMI-Board上報(bào)數(shù)據(jù)流,也可通過MQTT指令下發(fā),遠(yuǎn)程控制空調(diào)和其他設(shè)備。
開發(fā)環(huán)境
- RT-Thread Studio
- RA Smart Configurator
- HMI-Board開發(fā)板
設(shè)計(jì)過程
本次設(shè)計(jì)的主要功能可分為兩個(gè)部分。
1.紅外數(shù)據(jù)的編解碼:
為獲取紅外指令的編碼數(shù)據(jù)并解析,臨時(shí)自制了一款示波器,通過該示波器采集了如下波形數(shù)據(jù):
通過該波形數(shù)據(jù),分析遙控器紅外編碼協(xié)議,并通過紅外發(fā)射管將紅外遙控?cái)?shù)據(jù)復(fù)現(xiàn)。
最初使用的正點(diǎn)原子的F407開發(fā)板,搭配RT-Thread Studio的infrared軟件包進(jìn)行紅外遙控?cái)?shù)據(jù)的復(fù)現(xiàn)工作,通過修改NEC相關(guān)代碼,使之適配RTT的HWTIMER和PWM設(shè)備驅(qū)動(dòng)框架。并最終調(diào)試通過。
在移植到HMI-Board開發(fā)板時(shí),發(fā)現(xiàn)Renesas的底層設(shè)備驅(qū)動(dòng)代碼與RTT設(shè)備驅(qū)動(dòng)框架的對接工作任務(wù)量有點(diǎn)兒大。時(shí)間有限,為盡快完成設(shè)計(jì),使用了Renesas的PWM的底層驅(qū)動(dòng)函數(shù)搭配阻塞延時(shí)的方式,最終實(shí)現(xiàn)紅外數(shù)據(jù)的復(fù)現(xiàn)。
2.Onenet下發(fā)指令的接收與解析
Onenet下發(fā)指令的接收,使用了RTT提供的命令接受回調(diào)函數(shù)”onenet_set_cmd_rsp_cb”,在該函數(shù)內(nèi)通過查詢的方式將接收的字符數(shù)據(jù)與本地指令庫進(jìn)行比對,并執(zhí)行相應(yīng)操作。
工程代碼
上電自動(dòng)連接網(wǎng)絡(luò)
#define WLAN_SSID "test_ssid"
#define WLAN_PASSWORD "12345678"
rt_wlan_connect(WLAN_SSID, WLAN_PASSWORD);//連接WiFi熱點(diǎn)
初始化MQTT,并連接Onenet平臺
onenet_mqtt_init();//MQTT初始化
onenet_upload_cycle();//開啟MQTT定時(shí)上傳
onenet_set_cmd_rsp_cb(onenet_cmd_rsp_cb);//開啟命令接收回調(diào)
紅外遙控?cái)?shù)據(jù)編碼
//紅外發(fā)送數(shù)據(jù)裝載
static rt_size_t infrared_send(struct ir_raw_data* data, rt_size_t size)
{
rt_size_t send_size;
for (send_size = 0; send_size < size; send_size++)
{
infrared_send_buf[send_size] = (data[send_size].level<<28) + (data[send_size].us);
}
infrared_send_buf[size] = 0x5A5A5A5A;
return send_size;
}
#define CARRIER_WAVE 0xA
#define IDLE_SIGNAL 0xB
#define NO_SIGNAL 0x0
//紅外遙控?cái)?shù)據(jù)編碼
static rt_err_t ir_decoder_write(void)
{
rt_uint32_t data_buff_1,data_buff_2;
data_buff_1 = (0x8050040A);
/* guidance code /
write_raw_data[0].level = CARRIER_WAVE;
write_raw_data[0].us = 9000;
write_raw_data[1].level = IDLE_SIGNAL;
write_raw_data[1].us = 4500;
for (rt_uint8_t index = 0; index < 64; index += 2)
{
if (((data_buff_1 << (index / 2)) & 0x80000000)) / Logic 1 /
{
write_raw_data[2 + index].level = CARRIER_WAVE;
write_raw_data[2 + index].us = 646;
write_raw_data[2 + index + 1].level = IDLE_SIGNAL;
write_raw_data[2 + index + 1].us = 1643;
}
else / Logic 0 /
{
write_raw_data[2 + index].level = CARRIER_WAVE;
write_raw_data[2 + index].us = 646;
write_raw_data[2 + index + 1].level = IDLE_SIGNAL;
write_raw_data[2 + index + 1].us = 516;
}
}
write_raw_data[66+0].level = CARRIER_WAVE;
write_raw_data[66+0].us = 646;
write_raw_data[66+1].level = IDLE_SIGNAL;
write_raw_data[66+1].us = 516;
write_raw_data[66+2].level = CARRIER_WAVE;
write_raw_data[66+2].us = 646;
write_raw_data[66+3].level = IDLE_SIGNAL;
write_raw_data[66+3].us = 1643;
write_raw_data[66+4].level = CARRIER_WAVE;
write_raw_data[66+4].us = 646;
write_raw_data[66+5].level = IDLE_SIGNAL;
write_raw_data[66+5].us = 516;
/ connect code /
write_raw_data[72].level = CARRIER_WAVE;
write_raw_data[72].us = 646;
write_raw_data[73].level = IDLE_SIGNAL;
write_raw_data[73].us = 20000;
data_buff_2 = (0x0004000E);
for (rt_uint8_t index = 0; index < 64; index += 2)
{
if (((data_buff_2 << (index / 2)) & 0x80000000)) / Logic 1 /
{
write_raw_data[74 + index].level = CARRIER_WAVE;
write_raw_data[74 + index].us = 560;
write_raw_data[74 + index + 1].level = IDLE_SIGNAL;
write_raw_data[74 + index + 1].us = 1690;
}
else / Logic 0 /
{
write_raw_data[74 + index].level = CARRIER_WAVE;
write_raw_data[74 + index].us = 560;
write_raw_data[74 + index + 1].level = IDLE_SIGNAL;
write_raw_data[74 + index + 1].us = 560;
}
}
/ epilog code /
write_raw_data[138].level = CARRIER_WAVE;
write_raw_data[138].us = 646;
write_raw_data[139].level = IDLE_SIGNAL;
write_raw_data[139].us = 43580;
infrared_send(write_raw_data, 140);
LOG_D("data_buff_1:0x8050040A data_buff_2:0x0004000En");
// rt_kprintf("data_buff_1:0x8050040A data_buff_2:0x0004000En");
// rt_thread_mdelay(200);
return RT_EOK;
}
紅外編碼數(shù)據(jù)發(fā)送
//紅外編碼數(shù)據(jù)發(fā)送
rt_err_t ir_send_data(void)
{
LOG_D("ir_send_startn");
for (rt_size_t i = 0;i<210;i++)
{
if ((infrared_send_buf[i] != 0x5A5A5A5A))/ Determine if it is a stop bit /
{
R_GPT_Stop(&g_timer2_ctrl);
if ((infrared_send_buf[i] & 0xF0000000) == 0xA0000000) / Determine if it is a carrier signal /
{
R_GPT_Start(&g_timer2_ctrl);
}
rt_hw_us_delay(infrared_send_buf[i] & 0x0FFFFFFF);
}
else
{
R_GPT_Stop(&g_timer2_ctrl);
rt_kprintf("nir_send_ok!n");
return RT_EOK;
}
}
rt_kprintf("nir_send_error!n");
return RT_ERROR;
}
Onenet指令接收與解析
/ onenet mqtt command response callback function */
//static void onenet_cmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size)
//#define LED_PIN BSP_IO_PORT_02_PIN_09
void onenet_cmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size)
{
char res_buf[] = { "cmd is received!n" };
char my_res_buf[] = { "?????????" };//接收指令數(shù)據(jù)
LOG_D("recv data is %.*sn", recv_size, recv_data);
// LOG_D("%sn",recv_data);
// LOG_D("recv_size:%d,strlen:%dn",recv_size,strlen(recv_data));
strncpy(my_res_buf,recv_data,recv_size);
LOG_D("my_res_buf:%sn",my_res_buf);
const char *led0_on = "led0_on";
const char *led0_off = "led0_off";
const char *led1_on = "led1_on";
const char *led1_off = "led1_off";
const char *air_on = "air_on";
const char air_off = "air_off";
if(!strcmp(my_res_buf,led0_on)){rt_pin_write(0x0209, PIN_LOW);}
if(!strcmp(my_res_buf,led0_off)){rt_pin_write(0x0209, PIN_HIGH);}
if(!strcmp(my_res_buf,led1_on)){rt_pin_write(0x020A, PIN_LOW);}
if(!strcmp(my_res_buf,led1_off)){rt_pin_write(0x020A, PIN_HIGH);}
if(!strcmp(my_res_buf,air_on)){rt_pin_write(0x020A, PIN_LOW);}
if(!strcmp(my_res_buf,air_off)){ir_send_data();rt_pin_write(0x020A, PIN_LOW);}
/ user have to malloc memory for response data */
*resp_data = (uint8_t *) ONENET_MALLOC(strlen(res_buf));
strncpy((char *)*resp_data, res_buf, strlen(res_buf));
*resp_size = strlen(res_buf);
}
-
接收機(jī)
+關(guān)注
關(guān)注
8文章
1181瀏覽量
53474 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1289瀏覽量
40129 -
紅外編解碼
+關(guān)注
關(guān)注
0文章
3瀏覽量
4756 -
MQTT協(xié)議
+關(guān)注
關(guān)注
0文章
97瀏覽量
5374 -
HMI系統(tǒng)
+關(guān)注
關(guān)注
0文章
20瀏覽量
1027
發(fā)布評論請先 登錄
相關(guān)推薦
評論