采用Zigbee和Raspberry Pi的太阳能/燃气热水器自动控制系统_太阳能热水器控制 micropython-程序员宅基地

技术标签: 水位检测  水温测量  Raspberry Pi  Zigbee  #Zigbee  CC2530  嵌入式  

家在顶楼,想着利用太阳能,就安装了太阳能热水器,但毕竟遇上刮风下雨,靠天吃饭不靠谱,太阳能热水器虽然也有电热功能,但水用完了加热等待时间太长,所以也安装了天然气热水器。

大致的管路示意图如下:

原来的太阳能/燃气热水器连接示意图

但这样使用时就稍显麻烦,因为燃气热水器这边直接承受自来水水压,压力较大,如果两边的阀门同时打开,水就会从太阳能热水器的热水管逆向流动,给太阳能热水器反向上水,直至热水器水箱装满溢出也不会停止,因此,两边的阀门不能同时开启。曾经尝试在太阳能这边安装止逆阀,但效果不佳,止逆阀无法完全密封,只是稍微延缓溢出的时间而已。

我家的燃气热水器还有个特点,因为装在露台,是室外机型,待机15分钟就会自动关闭,此时打开水,热水器不会自动点火,必须按动控制器上的开关打开热水器,才会响应用水请求点火。而且更麻烦的是,每次开机后,之前设定的水温又会自动回到40°,而洗澡水温通常要设定到60°,浴室里的水温水压感觉才最合适,意味着每次开机都要重新设定水温。

燃气热水器在露台,而太阳能热水器的控制器又在洗手间,和露台隔着一个大客厅。

综上可见,每次用热水之前,这个过程之麻烦:
1. 到洗手间查看太阳能热水器的水温和水位;
2. a) 如果太阳能的热水合用,则:
2. a) i) 打开太阳能的热水出水阀;
2. a) ii) 跑去露台关闭燃气热水器的进水阀;
2. b) 如果太阳能这边热水不可用,则:
2. b) i) 关闭太阳能出水阀;
2. b) ii) 跑去露台打开燃气热水器的开关;
2. b) iii) 重新设定水温;
2. b) iv) 拧开燃气热水器进水阀。

自己使用习惯了,也就罢了,每次家里来了客人,要洗澡什么的,都得鞍前马后伺候着,因为实在不觉得客人能在短时间之内搞清楚这么复杂的逻辑,直接放弃解释,亲自服务吧。

作为一个Diyer,实在无法忍受这种情况,终于决定要用科技解决这个问题。

方案

决心是下了,大致方向是用单片机采集太阳能的水位水温,并监测太阳能和燃气的用水状态,动态控制两边的阀门和燃气的开关以及温度设置,但具体采用什么方案解决这个问题呢?

因为设备分布在几个不同的地方,肯定需要无线组网,之前Wifi、蓝牙接触较多,但感觉太重量级了。听说过Zigbee,但还从来没用过,调查了一下,作为家庭内部的智能设备组网,确实比蓝牙和Wifi都合适,于是初步设计系统架构如下:

如上图所示,系统主要由4个Zigbee设备和一个Raspberry Pi树莓派组成。

Zigbee Device 1利用自动增压泵上的自动开关监测太阳能热水器的用水状态,并上传至Coordinator;同时还负责控制太阳能热水器的出水阀门。

Zigbee Device 2负责监测太阳能热水器的水位和水温,并上传至Coordinator。

Coordinator作为Zigbee系统的核心,负责组网的同时,接收Zigbee Device 1、2传来的太阳能热水器的各种数据,自身对燃气热水器的开关状态、使用状态进行监测,并根据水温条件,自行对燃气热水器和太阳能热水器的工作状态进行控制。同时,Coordinator上还有按钮,支持手动切换太阳能和燃气热水器的工作状态。

以上三个组件为系统工作的核心组件,缺一不可,下面则为可选组件。

Zigbee device 3和树莓派组成了本系统的网关和远程控制终端。Device 3和Coordinator通过Zigbee协议进行通信,并利用串口将各种状态和命令与树莓派进行通讯,树莓派作为上位机,既可以利用触摸屏通过QT界面对本系统进行控制,也可以接入家中的Wifi,从而接入Internet,利用手机对本系统进行远程监控操作。

系统架构确定了,就开始着手实施,因为这是第一次接触Zigbee,是一个全新的学习过程,故而通过这篇文章记录之。

设计与实现

首先在万能的淘宝上买了四个CC2530的Zigbee模块和仿真器

也是托大,想碰碰运气,就没有买测试板,结果回来飞线开机啥都没有,两眼一抹黑,也不知道是线接的有问题还是程序有问题,毕竟从来没搞过这个模块,完全无从下手,只好老老实实再买一块测试板回来。

然后再对照着教程烧程序,跑马灯跑起来了,但串口还是没输出,只好对着测试版的电路原理图,一边看CC2530芯片手册,一边测波形,一步步排查,原来商家提供的教程和参考代码居然和他们卖的测试板都对不上,教程和参考代码中用的都是串口0,而他们测试板上USB转串口接的是串口1!nnd坑爹!找到原因了,那就对照芯片手册一步步改吧,终于串口有输出了,这才意味着开发过程中可以进行调试、而不是盲人摸象了。

然后参考教程,从流水灯开始,按键、DMA、ADC、透传……感觉能用得上的实验都做了一遍,觉得Zigbee模块基本功能摸得差不多了,可以开始正式进行系统实现了。

当然,当中串口又有个坑:之前调的是裸机程序,上了透传后ZStack中的串口配置又不对了,又是一顿好找,跟着整个流程从配置文件、端口到DMA设置改了个遍,好容易HalUARTWrite(1, “ABC”,  3)看到有输出了,这才终于松了口气。

应用框架

要开发,自然得先搭软件应用层框架。

TI的Zigbee当然是基于ZStack,但即便ZStack中,也分了好多层,从AF、ZDO到ZCL等,其实这个小系统,直接基于AF层搞透传就好了,但毕竟是第一次搞Zigbee,想弄的深入一些,把那些什么profile、device、cluster、endpoint的概念彻底搞清楚,不然看了半天还是云里雾里。因此,这个系统的实现中很多地方应该是有点过度设计了,有点大炮打蚊子的感觉;有的地方甚至是画蛇添足,完全只是为了验证知识点。

为了实现设备间的双向通信,系统中采用了三种办法:

  1. 定时发送Report,主要用于水位水温等状态数据的定时采集;

  2. 发送ZCL Command,主要用于执行开关等动作;

  3. 读写ZCL Attribute,主要用于一些控制量的设置或读取;

另外,为了便于后期调试,Coordinator也利用了AF层进行透传,把一些调试信息发到网关(Device 3)。

要能通信,首先是设备定义。

Zigbee设备之间进行通信,需要几个值匹配:ProfileId,ClusterId,AttributeId。

ProfileId范围最大,是应用所属范围,例如0x0104是智能家居,0x0101是工业自动化;

ClusterId是对设备具体属性的分类,例如0x0005是场景类,0x0006是开关类;

AttributeId则是具体可操作的属性,定义可见zcl_general.h。例如:

#define ATTRID_SCENES_COUNT 0x0000
#define ATTRID_SCENES_CURRENT_SCENE 0x0001
#define ATTRID_SCENES_CURRENT_GROUP 0x0002

就是场景类下的一些属性定义。

此外,还有一个DeviceId,它定义了设备自身的类型,例如0x0001是可以控制挡位的开关,0x0002只有开/关动作的开关,0x0100是灯,0x0303是泵等等;但DeviceId只在逻辑上供应用层使用,并不是协议中达成通信的的必要条件,例如开关可以控制任何灯、水泵、空调,所以任意两种DeviceId的设备之间都可以进行通信,不形成任何约束。而服务请求/绑定/通信时的ProfileId,ClusterId,AttributeId必须一致。

还有人会说还有个Endpoint呢,Endpoint就只是一个数字而已,就好像你去别人家串门,总要知道别人家的门牌号码,但这个号码究竟是几,其实无所谓。也有点类似TCP/IP中的端口号,7777还是8888,无所谓,关键是你知道是几就好。如果不知道呢?那就用服务请求或绑定去找了。

既然是设备定义,那么要根据功能整理出一堆需要操作的变量,例如设备的开关、太阳能的水温等,定义出相应的的Attributes:

{
ZCL_CLUSTER_ID_GEN_ON_OFF,
{ // Attrib

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shaoyie/article/details/103525230

智能推荐

大学生体质测试管理 毕业设计源码42047-程序员宅基地

文章浏览阅读796次,点赞21次,收藏21次。本系统有管理员、学生用户。管理员:后台首页、个人资料(个人信息、修改密码)、轮播图、公告信息管理、系统用户(管理员、学生用户)、交流管理(论坛列表、论坛分类列表)模块管理(目标信息、目标记录、学习科普、学习类别)。学生用户;首页、我的(个人信息、我的账户、我的收藏)、交流论坛、公告信息、目标信息、学习科普等功能模块。

01.JS的进阶——基础总结与深入_console.log(b1.b2[2]()) ;// 'abc' undefined-程序员宅基地

文章浏览阅读86次。提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档目录1.数据类型2.数据类型23.数据_变量_内存14.数据_变量_内存25.数据_变量_内存36.数据_变量_内存47.数据_变量_内存58.对象9.对象210.函数11.回调函数12.IIFE立即执行函数13.函数中的this总结1.数据类型<!DOCTYPE html><html> <head> <meta cha._console.log(b1.b2[2]()) ;// 'abc' undefined

hdu 2243 考研路茫茫——单词情结-程序员宅基地

文章浏览阅读5.3k次。题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243题目大意:问长度为1~N的串中包含了模式串的串总共有几个。题目思路:求出长度不大于l的包含模式串的字符串数,方法是改求不包含模式串的字符串总数,当然先要处理出总的字符串个数,可以用矩阵也可以用二分幂和的方法。而求不包含模式串的字符串数同样是构造矩阵,同时还要建立一个虚结点,储存长度小于l的_hdu 2243

ad导出元件清单_【教程】PADS如何导出SMT贴片机用的坐标文件-程序员宅基地

文章浏览阅读1.6k次。步骤0, 本教程必须先添加脚本注意: 本教程需要使用脚本, 脚本可在这个帖子中下载: http://club.szlcsc.com/article/details_1940_1.html //(就不再本帖中贴出附件,脚本可能会有更新,到时多处修改很麻烦)添加脚本的方式:注意: 脚本的存放路径必须 和 PADS自带的脚本 放在相同路径下.添加完成后:简述步骤: 设置左下角为原点; 工具-..._ad出贴片清单

[Kubernetes]K8S中的Service实现方式以及IPVS介绍_kubernetes service ipvs-程序员宅基地

文章浏览阅读685次。service通过什么方式实现的?正常情况下,service是一个抽象的概念,它是通过调用iptables工具实现的pod之间的通信,而iptables是系统内核netfiter模块的一个工具,主要是用来管理一张端口转发表,每一次的转发都需要轮询一遍转发表,因此,当集群数量较大的时候,相应的转发性能会下降。所以在kubernets1.11版本以后,将IPVS引入GA,通过IPVS实现SVC。实现service功能,通过kube-proxy,是kubernets核心组件,能否替代?常见概念_kubernetes service ipvs

基于lcov实现的增量代码UT覆盖率检查-程序员宅基地

文章浏览阅读1.2k次。背景介绍配合CppUTest单元测试框架,lcov提供了一套比较完整的工程工具来对UT覆盖率进行度量。但对有些团队来说,历史负担太重,大量的遗留代码没有相应的UT。在这种情况下,对新增代码进行覆盖率检查,可能对团队来说是一种可行性较强的措施。在此目标基础上,并提出如下需求:1)利用现有的lcov资源;2)可以对指定git cmmit提交的代码进行UT覆盖率检查;3)可以指定需要UT..._lcov增量覆盖率

随便推点

Cortex-M3双堆栈MSP和PSP_stm32 msp psp-程序员宅基地

文章浏览阅读5.5k次,点赞19次,收藏78次。什么是栈?在谈M3堆栈之前我们先回忆一下数据结构中的栈。栈是一种先进后出的数据结构(类似于枪支的弹夹,先放入的子弹最后打出,后放入的子弹先打出)。M3内核的堆栈也不例外,也是先进后出的。栈的作用?局部变量内存的开销,函数的调用都离不开栈。了解了栈的概念和基本作用后我们来看M3的双堆栈栈cortex-M3内核使用了双堆栈,即MSP和PSP,这极大的方便了OS的设计。MSP的含义是Main..._stm32 msp psp

计算机图形学绘图程序设计_绘图程序计算机图形学-程序员宅基地

文章浏览阅读1.6k次。VC++的图形工作方式物理坐标系设备场景MFC中的设备场景CDC类的部分成员函数Windows的图形对象1.建立图形对象2.对该对象进行初始化3.将该对象选入当前设备场景,并保留初始对象4.画图5.恢复原始对象实例实验一 二维图形绘制金刚石一笔绘三种方法..._绘图程序计算机图形学

数字证书及CA的扫盲介绍_rsa和ca的区别-程序员宅基地

文章浏览阅读751次。★ 先说一个通俗的例子  考虑到证书体系的相关知识比较枯燥、晦涩。俺先拿一个通俗的例子来说事儿。  ◇ 普通的介绍信  想必大伙儿都听说过介绍信的例子吧?假设 A 公司的张三先生要到 B 公司去拜访,但是 B 公司的所有人都不认识他,他咋办捏?常用的办法是带公司开的一张介绍信,在信中说:兹有张三先生前往贵公司办理业务,请给予接洽......云云。然后在信上敲上A公司的公章。_rsa和ca的区别

B站C语言——指针_c语言a[4][4]-程序员宅基地

文章浏览阅读467次。学C语言就是学内存int *p = NULL;这里的/*是在定义时使用的,说明p是指针变量,而不是普通变量printf("%d\n",*p);这里的/*的表示取p保存的地址编号对应空间的内容..._c语言a[4][4]

vue2.0引入icon.styl不断报错-程序员宅基地

文章浏览阅读359次。解决方法:在import icon.styl的地方引入icon.css.这样至少不报错,不过估计有问题,后续再看。_icon.styl

Unity-EasyTouch插件之One Finger-程序员宅基地

文章浏览阅读155次。这节课,我们主要讲下单个手指的测试。比如单击啊,双击啊,拖动,单手滑动等。单击:public class TouchTest : MonoBehaviour { // Subscribe to events void OnEnable(){ //启动On_SimpleTap监听,也就是手指单击屏幕,就会触发On_MySimpleTap的方法执行 Ea..._unity easytounch 获取第一跟手指

推荐文章

热门文章

相关标签