本帖最后由 numenjian 于 2016-8-2 13:44 编辑
背景: 在新房装修前,一直计划着家里布置一套监控系统,能够实时掌控家里的状况,外加控制一些用电设备。
然而理想是美好的,现实却(装修时实在太忙了,没顾上)。。。。。。。。
虽然未能实现,不管怎么样,亡羊补牢,未为晚也。现在比较流行智能家居,恰好本人又是做无线监控系统的,所以就临时改变了一下方案:无线监控。
正文:
首先说一下利用的平台:
软件平台: Yeelink (不深入探讨了,需要了解的人自己百度吧)
硬件平台: STM32F051(还有一块F429开发板在用,过几天移植一下换过来,毕竟能用的资源比较多)+W5100(arduino开发板的网络模块)+射频模块(暂用CC2520,公司的)
主要功能:
目前仅做了一款温度传感器数据采集,采用的是DS18B20,监控主站主要负责无线传感器数据采集接收,并通过以太网将数据传送到Yeelink平台,无线传感器数量可以任意增加(需先软件配置),传感器数据上传间隔为12s(yeelink限制了最小间隔为10s).
监控主站
传感器
效果如下:
主站温度 传感器温度
主站放在客厅,传感器放厨房(暂时只加了1台传感器),采用2.4G进行传输(发射功率4.5dBm,仅单向传输没有加入协议栈)暂时还是比较稳定的,上图是3天的稳定记录。但是ZigBee的穿透和绕射能力较弱,通过提升功率(手里还有加了PA的板子,能到+20dBm)也能覆盖一套房子,但是过大的发射功率很多人不能接受(比如辐射、功耗)。过几天准备换个频段(433MHz,刚好手里也有Sx1278、Si4463)试试全覆盖测试。
也许有朋友比较关心代码,我也附一些吧。STM32的函数库就不分享了,官网很多,我就是用的官方例程。12864LCD、18B20这些驱动网上也很多,需要的朋友可以私信我。重点讲一下W5100是怎样连接yeelink的吧。
W5100的驱动用的是百度来的,就w5100.c和w5100.h,一搜一堆。
首先是IO初始化:
这里定义了PB12~PB15,用硬件SPI2;W5100还有RST引脚需要控制;还有一个中断引脚(可以查询寄存器,不一定用)
其次是 W5100硬件初始化:
W5100_HARTRESET(); //强制复位
W5100_Init(); //寄存器初始化,包括配置网关、IP、物理地址、重发次数
Socket_Init(0,S0_Port,S0_DPort,S0_DIP); //socket0初始化,主要是设置目的地址(远程主机地址)
Socket_Connect(0); //设置为客户端模式
到此,W5100已经能够完成作为客户端连接远程服务器了。
需要注意的是,本机网关、IP设置需要与家里的路由器匹配,否则上不了网,传不了数据;远程主机IP必须为 42.96.164.52,端口号80 (yeelink)
配置完成后就是在任务中添加上传函数,上传函数必须按照yeelink的固定格式,可以采用以下函数(EmbedNet论坛飞鸿踏雪大神的字符串生成方法)
char* Yeelink_PostString(const char *device_id,const char *sensors_id,float value)
{
char remote_server[] = "api.yeelink.net";
char str_tmp[128] = {0};
// Http内容,表单内容
char http_content[32] = {0};
//表头的内容
sprintf(str_tmp,"/v1.0/device/%s/sensor/%s/datapoints",device_id,sensors_id);
// 确定提交内容的值 例如 {"value":20。1}
sprintf( http_content , "{\"value\":%.1f}" , value);
// 确定 HTTP请求首部
// 例如POST /v1.0/device/dbeacfc4943e593ebe2bcf46a684f794/1/1/datapoints/add HTTP/1.1\r\n
sprintf( http_request , "POST %s HTTP/1.1\r\n",str_tmp);
// 增加属性 例如 Host: api.machtalk.net\r\n
sprintf( str_tmp , "Host: %s\r\n" , remote_server);
strcat( http_request , str_tmp);
// 增加密码 例如 APIKey: dbeacfc4943e593ebe2bcf46a684f794
sprintf( str_tmp , "U-ApiKey:%s\r\n" , APIKEY);//需要替换为自己的APIKey
strcat( http_request , str_tmp);
strcat( http_request , "Accept: */*\r\n");
// 增加提交表单内容的长度 例如 Content-Length:12\r\n
sprintf( str_tmp , "Content-Length: %d\r\n" ,strlen(http_content) );
strcat( http_request , str_tmp);
// 增加表单编码格式 Content-Type:application/x-www-form-urlencoded\r\n
strcat( http_request , "Content-Type: application/x-www-form-urlencoded\r\n");
// HTTP首部和HTTP内容 分隔部分
strcat( http_request , "\r\n");
// HTTP负载内容
strcat( http_request , http_content);
return http_request;//返回生成的所需要发送的字符串指针
}
发送函数,在每次发送前都必须先连接( 调用Socket_Connect(0),并判断连接状态,连接成功方可发送数据),因为yeelink每次传送完数据都会主动断开连接!
void Yeelink_SendTCPC (char *pYeelinkStr,SOCKET s)
{
unsigned int i=0;
while(pYeelinkStr!=0x00)
{
Tx_Buffer=pYeelinkStr;
i++;
}
S_tx_process(s,i); //发送TxBuf[]内容
}
至此,已经能够完成基本数据上传了,需要注意的是,每个传感器上传间隔都必须设置的大于10s,否则yeelink会返回错误命令,导致数据丢失。
|