基于HMI-Board的智能宿舍空调管理系统设计案例

发布者:快乐家庭最新更新时间:2024-04-29 来源: elecfans 手机看文章 扫描二维码
随时随地手机看文章

概述

为解决寝室空调总是忘关的问题,基于HMI-Board设计了一款智能空调管理器,可通过onenet指令下发实现远程关闭空调。


设计思路

HMI-Board使用板载RW-007WiFi模块,通过MQTT协议连接Onenet平台,上报当前状态信息,接收并解析Onenet平台的下发指令。客户端进入Onenet云平台,可查阅HMI-Board上报数据流,也可通过MQTT指令下发,远程控制空调和其他设备。


开发环境

  • RT-Thread Studio

  • RA Smart Configurator

  • HMI-Board开发板
    设计过程
    本次设计的主要功能可分为两个部分。

1.红外数据的编解码:

为获取红外指令的编码数据并解析,临时自制了一款示波器,通过该示波器采集了如下波形数据:

1.jpg

通过该波形数据,分析遥控器红外编码协议,并通过红外发射管将红外遥控数据复现。

最初使用的正点原子的F407开发板,搭配RT-Thread Studio的infrared软件包进行红外遥控数据的复现工作,通过修改NEC相关代码,使之适配RTT的HWTIMER和PWM设备驱动框架。并最终调试通过。

在移植到HMI-Board开发板时,发现Renesas的底层设备驱动代码与RTT设备驱动框架的对接工作任务量有点儿大。时间有限,为尽快完成设计,使用了Renesas的PWM的底层驱动函数搭配阻塞延时的方式,最终实现红外数据的复现。

2.Onenet下发指令的接收与解析

Onenet下发指令的接收,使用了RTT提供的命令接受回调函数”onenet_set_cmd_rsp_cb”,在该函数内通过查询的方式将接收的字符数据与本地指令库进行比对,并执行相应操作。

工程代码

上电自动连接网络

#define WLAN_SSID 'test_ssid'
#define WLAN_PASSWORD '12345678'
rt_wlan_connect(WLAN_SSID, WLAN_PASSWORD);//连接WiFi热点
初始化MQTT,并连接Onenet平台
onenet_mqtt_init();//MQTT初始化
onenet_upload_cycle();//开启MQTT定时上传
onenet_set_cmd_rsp_cb(onenet_cmd_rsp_cb);//开启命令接收回调
红外遥控数据编码
//红外发送数据装载
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
//红外遥控数据编码
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;
}
红外编码数据发送
//红外编码数据发送
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[] = { '���������' };//接收指令数据
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);
}


引用地址:基于HMI-Board的智能宿舍空调管理系统设计案例

上一篇:260W功率音频放大器电路图
下一篇:LCD1602工作原理 LCD1602液晶屏原理图 LCD1602显示控制

小广播
最新嵌入式文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved