数码之家

标题: 介绍我家的智能家居系统(原理细节详细介绍,关键部分开源) [打印本页]

作者: fryefryefrye    时间: 2021-3-17 19:25
标题: 介绍我家的智能家居系统(原理细节详细介绍,关键部分开源)
本帖最后由 fryefryefrye 于 2021-3-21 10:51 编辑

我家这套智能家居系统已经运行了很多年了,自我感觉不错,给大家分享一下。
也是断断续续开发了很多年,一下子不可能讲的很清楚,有兴趣的同学可以提问,我继续回答。

早年买了一些所谓的智能家居硬件设备,最后得到的是手机里一大堆APP,以及薛定谔状态的可用性。最后决定全部自己开发。

现在这套系统的优点:
1:全部自己开发,需要新功能,实现新想法,只要是可行的,就能做出来。
2:大部分功能通过局域网实现,不依赖互联网。只要家里有电,就能正常运行大部分功能(外网控制除外)
3:控制界面就一个,一眼看清所有设备状态,一键即可控制所需设备,无需在一堆APP中,一大堆页面中翻来翻去。

整套系统主要结构如下:
[attach]1108764[/attach]

1:用ESP8266作为节点,每秒发一个UDP包到树莓派服务器,包含节点采集到的数据和状态(比如:温度,湿度,灯已开,灯已关)。
2:树莓派服务器收到节点更新后,回复一个UDP命令包,包含发送给节点的控制命令(比如:开灯,关灯),并缓存节点的IP地址信息。
3:树莓派另开web服务,手机电脑均可访问,可以查看状态,也可以控制,在家通过局域网访问,不依赖互联网,在外需要做一个端口映射(申请公网IP)。
4:收到web的控制命令后,立即给节点发送命令UDP包(之前已经缓存了节点IP信息),可以做到灯一按就亮,几乎无延时。


控制界面是这样的:
[attach]1108765[/attach]

控制界面的实现原理(使用Ajax更新网页里的部分文字):
上图所示的控制界面是一个html文件,只需要加载一次。但是表格中的数据和状态都是每秒使用Ajax更新的。
流程大概是这样
a)浏览器请求 http://192.168.0.17/index   树莓派服务器直接返回一个html文件
b)html文件里面有脚本,每秒执行一次,发起请求  http://192.168.0.17/update
c)树莓派返回一串用“,”隔开的字符串。脚本会按照“,”分割,形成一个字符串数组。
d)把这个数组填个表格的相应部分。

这是html文件的一个简单的例子,我用来显示天气预报的。
https://github.com/fryefryefrye/ ... n/weatherindex.html

树莓派服务器实现原理(web服务):

上一段已经介绍了如何使用Ajax更新网页里的部分文字,其中重要的一点就是服务器需要自动生成一串用“,”隔开的字符串。
这个就需要在树莓派上编程实现。
由于我不喜欢使用现成的web服务软件,我就自己实现了一个最简单的web服务器。
流程大概是这样
a)创建一个socket,在80端口上监听。
b)连接建立之后,一般会收到一个类似“GET /index HTTP/1.1”的请求。
c) 根据请求内容,给予适当的回复,在回复实际内容之前,发送一个http回复的head就行了
const char HttpResponseHeadSimple[]   ="HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
d)上面那个头部,最后两个回车之后,就可以发送实际数据了,不管是一个html文件,还是“,”隔开的字符串,都可以。
e)发完就可以关闭socket,等待下一个连接请求。


树莓派服务器实现原理(UDP数据交换):
为了定义节点与服务器交换的数据格式,我写了一个共用h文件,即被Arduino节点的程序包含,也被服务器的程序包含。
这个h文件里定义数据格式,例子如下。
struct tMeterData
{
        unsigned long DataType; //data type = 5
        unsigned long Mac[6];
        unsigned long Power;                //xx.xxxx W
        unsigned long TotalEnergy;                //xxxxxx.xx kWh
        unsigned long Volt;                        //xxx.x v
        unsigned long Current;                //xxx.xxx A

};

struct tMeterCommand
{
        unsigned long Triger;
        unsigned long On
};

这是一个交流电功率计的数据格式的例子,所有的数据都是用的4字节长整型,以免不同的平台的字节对齐问题。
上传数据的第一组是数据类型,用来检测是哪一种设备发来的,其他的就是数据更新。
下发的命令是每秒都会回复的,当作心跳包。但是没有实际操作请求的时候,triger = false。
如果真的要操作,就设为True,表示这是一个需要执行的命令,节点就会根据下发的数据执行相应的操作。


不同功能的节点,其实很多,我介绍几个大家比较能用的着的:

1:房间灯光控制器
双控一盏灯,既能传统的手动控制,也能用网络控制的方法。
用ESP8266+继电器做一个控制器,就可以通过网络控制这个继电器。
然后单片机一个引脚接出来,接一个普通墙壁开关。单片机程序写一下,这个开关的状态变化一次,就把继电器的状态变一下(不用管开关到底是开,还是关,只检测开关的变化)。这样不仅仅可以传统手动控制,而且手动控制之后的状态,也可以通过网络看到。

2:房间空调控制器
改造已有的空调,让其能继续使用普通遥控器遥控,也能使用网络控制。而且使用遥控器控制的结果,也能通过网络查询到.

a)通过单片机控制空调:买一个2毛钱的红外发光二极管,接在ESP8266的一个引脚上,另一脚接地。用Github上的库,即可发送命令控制空调。
b)监控空调的工作状态:找到空调遥控接收板上的红外接收管,找出数据线,焊接出来,接在ESP8266的一个引脚上,在这个脚上打开外部中断,用Github上的库分析即可。不管是通过网络控制,还是遥控器控制,这样都能取得空调工作状态。
c)监控空调的当前功率,可以更加确切的查看当前空调。而且可以查看累计耗电量,参考下一节。


3:用电功率监视器
淘宝购买“交流功率测量盒”。这个测量盒可以测量一台空调的功率,也能测量整个家庭的功率。 买三个组合起来,还能测量三相动力电的功率。上节所介绍的空调控制器,每台空调都配备了一个功率计。


[attach]1110035[/attach]
测量结果通过TTL串口读取出来,功率,电流,电压,电量这些信息都有。

为了统一节点的代码,上传的数据中还包含了ESP8266的MAC地址,这样每个测量节点的代码都是一样的,只要在树莓派里做个MAC地址列表,就能判断从那个节点发来的。

4:挂在家里的天气预报/时钟(有人有兴趣的话,再详细写吧。)
[attach]1108787[/attach]
5:电动车充电控制器(有人有兴趣的话,再详细写吧。)

不同功能的界面:

1:家门口控制器(有人有兴趣的话,再详细写吧。)
[attach]1108768[/attach]
2:挂在公司的天气预报(有人有兴趣的话,再详细写吧。)[attach]1112072[/attach]














作者: decai    时间: 2021-3-17 19:42
大牛.厉害plus.
墙面的开关面板好像不是86型的.是20型的么求链接
作者: hgq21102    时间: 2021-3-17 19:43
能否跑Modbus ,这样就简单点, 跑步Modbus  TCP,无线Modbus  TCP
作者: fryefryefrye    时间: 2021-3-17 19:49
decai 发表于 2021-3-17 19:42
大牛.厉害plus.
墙面的开关面板好像不是86型的.是20型的么求链接

原来图片上是买的86型遥控面板,由于无法查询状态,不能可靠控制,已经被我淘汰。

现在是这样的,挂了一个接线盒,钉在墙上,盖住了86底盒的洞。

盒子里有一块ESP8266+3个继电器。控制3个灯。上面一个普通86开关做手动控制。

盒子角落还有个距离传感器,检测到人靠近后,发消息给平板打开屏幕。

另外还控制平板的充电,保持电量在70-80%之间(平板上有APP发送电量到树莓派服务器)。

[attach]1108800[/attach]

作者: fryefryefrye    时间: 2021-3-17 19:51
hgq21102 发表于 2021-3-17 19:43
能否跑Modbus ,这样就简单点, 跑步Modbus  TCP,无线Modbus  TCP

懒的弄了,整套系统通信规则很简单,就定义一组合适的数据结构对发就行了,不搞通信协议了。
作者: hgq21102    时间: 2021-3-17 20:00
fryefryefrye 发表于 2021-3-17 19:51
懒的弄了,整套系统通信规则很简单,就定义一组合适的数据结构对发就行了,不搞通信协议了。 ...

走通信协议,开发难度降低很多,后期增加功能也很方便
作者: fryefryefrye    时间: 2021-3-17 20:28
hgq21102 发表于 2021-3-17 20:00
走通信协议,开发难度降低很多,后期增加功能也很方便

我本职工作就是干通信协议的,Modbus,T103,T104,DNP.都搞了10多年了。
我不觉得把这些协议栈搞进来有什么好处。
UDP也是一种通信协议啊,而且我就是要这种无连接协议。服务端就不用维持一大堆TCP/IP连接了。
作者: tetgrt    时间: 2021-3-17 21:34
楼主,就是强,非常有难度的。
作者: tetgrt    时间: 2021-3-17 21:40
请教一下,
1、你手机端不采用APP,那么如果手机端控制,是否需要用浏览器,来打开网页,来实现控制呢
2、如果在互联网情况下,怎样实现控制呢?
作者: 俊输    时间: 2021-3-17 22:26
高端玩法,学不会
作者: fryefryefrye    时间: 2021-3-17 23:22
本帖最后由 fryefryefrye 于 2021-3-18 08:42 编辑
tetgrt 发表于 2021-3-17 21:40
请教一下,
1、你手机端不采用APP,那么如果手机端控制,是否需要用浏览器,来打开网页,来实现控制呢
2、 ...

Android 和 苹果 手机都可以把一个网址做成一个快捷方式放在桌面上。

所需要的操作就是按一下桌面上的图标,和APP一样。 就能自动打开浏览器打开控制界面。然后就可以操作。另外,操作界面里的每一个按钮,其实就是个不同的网址。其实可以直接将某个操作的网址做成快捷图标放在桌面上,比如“关闭所有空调”。解锁手机后,按一次即可。


互联网的话。电信的宽带打一个10000号,就可以申请公网IP地址。然后自己注册一个动态域名,路由器设置一个端口转发。 就可以在互联网上访问了。

作者: 数码家园    时间: 2021-3-18 06:05
这个太牛了,有技术就是玩的好
作者: digitking    时间: 2021-3-18 10:31
土豪,这么多房间
作者: digifix    时间: 2021-3-18 12:21
hgq21102 发表于 2021-3-17 20:00
走通信协议,开发难度降低很多,后期增加功能也很方便

只要能连就必然有协议。
作者: digifix    时间: 2021-3-18 12:24
对空调控制和功率监测部分有兴趣
作者: 上官梦舞    时间: 2021-3-18 15:54
不是啊,你建个群,我就要搞你这一套!!!树莓派什么的我都有就是没有弄成一套。用别人的服务器终究是别人的。就是想搞成你这样的。
作者: 上官梦舞    时间: 2021-3-18 15:55
sim800的可以试试用2.4G模块呢或者lora模块。
作者: hbliwww    时间: 2021-3-18 15:55
太复杂,学不来,:sweat:
作者: pcbboy1991    时间: 2021-3-18 19:39
感觉这个需要不少的编程基础啊,看着楼主娓娓道来,其实工作量不少啊,对于对网络没有基础的人来说入门挺难哦。。。
作者: zyyuan199    时间: 2021-3-18 20:59
树莓派服务器所有数据处理用什么语言写的?
作者: 40560335    时间: 2021-3-19 00:13
树莓派都有了,直接搞个MQTT服务器
作者: fryefryefrye    时间: 2021-3-19 10:37
digifix 发表于 2021-3-18 12:24
对空调控制和功率监测部分有兴趣

已更新主贴。 简单介绍了原理,有兴趣有问题可以继续提问,我会继续更新。
作者: fryefryefrye    时间: 2021-3-19 10:38
上官梦舞 发表于 2021-3-18 15:54
不是啊,你建个群,我就要搞你这一套!!!树莓派什么的我都有就是没有弄成一套。用别人的服务器终究是别人 ...

不想建群,没什么人气的。有问题就在这儿回帖问吧,我会更新的。
作者: fryefryefrye    时间: 2021-3-19 10:41
上官梦舞 发表于 2021-3-18 15:55
sim800的可以试试用2.4G模块呢或者lora模块。

SIM800配合物联网卡,是用在50公里外的老家的一个自建房的。

那里没有宽带,地下室有一个自动抽水系统,偶尔会出故障不抽造成积水,或者抽着不停把泵烧了。

现在装了一个远程功率监控,10秒更新一次当前功率,就能看到运行状态,有问题就可以去修。
作者: fryefryefrye    时间: 2021-3-19 10:44
zyyuan199 发表于 2021-3-18 20:59
树莓派服务器所有数据处理用什么语言写的?

就一个*.c文件,从main()函数开始写。树莓派的linux,直接敲一个命令,就可以把这个c文件编译成一个可执行程序,然后运行就行了。

主要就两个任务,1)处理UDP通信 2)实现简易Web服务。 都是操作socket实现的。做网络编程的都懂。
作者: oydl82    时间: 2021-3-19 13:26
每个继电器模块都有电流电压检测模块吗?
作者: fryefryefrye    时间: 2021-3-19 15:17
oydl82 发表于 2021-3-19 13:26
每个继电器模块都有电流电压检测模块吗?

电流电压模块 每个空调装了一个。

还有一个装在整个家庭电线入户的地方。

这东西毕竟30多元一个呢,不便宜啊。
作者: tetgrt    时间: 2021-3-20 11:14
fryefryefrye 发表于 2021-3-19 10:38
不想建群,没什么人气的。有问题就在这儿回帖问吧,我会更新的。

楼主,真的希望你,建一个群,带一下我们这些会搞一下单片机的初哥,搞一套。
非常感谢!

作者: amo73    时间: 2021-3-20 11:47
tetgrt 发表于 2021-3-20 11:14
楼主,真的希望你,建一个群,带一下我们这些会搞一下单片机的初哥,搞一套。
非常感谢!
...

有兴趣的话可以发个召集帖,统计一下需求,只要有量、报酬合适,我想这个问题不大,毕竟技术是已经实现了,发出去代工生产不存在难题……职业生涯已经见证了很多科技公司就是这么玩着玩着起家的。

要是楼主费心费力免费指导,到时坛友还要来几句经典的“下载还要M币,打包上传到某云吧”,然后安装时在墙上钻几个孔就心甘情愿被水电工收百八十块……想想都魔幻:sweat:
作者: tetgrt    时间: 2021-3-22 11:00
amo73 发表于 2021-3-20 11:47
有兴趣的话可以发个召集帖,统计一下需求,只要有量、报酬合适,我想这个问题不大,毕竟技术是已经实现了 ...

非常支持。
作者: hujj    时间: 2021-3-22 18:43
请教楼主:几个当控制面板用的手机上都是运行网页文件么?在局域网中建立了WEB服务器?
作者: ploestar    时间: 2021-3-22 21:08
是不是可以用ESP8266或esp32替换树莓派做服务器,好像没什么计算量,存储和IO数也没啥要求,主要是便宜和入门低
作者: fryefryefrye    时间: 2021-3-22 22:00
hujj 发表于 2021-3-22 18:43
请教楼主:几个当控制面板用的手机上都是运行网页文件么?在局域网中建立了WEB服务器? ...

树莓派上运行了一个web服务器,在家通过局域网访问,在外通过公网IP+动态域名+端口映射 访问。

iPhone手机的话,就直接在桌面建立一个网址的快捷方式,和APP的图标类似,直接点击就打开浏览器并打开网页。

Android的话也可以像iPhone那样建立一个网址的快捷方式。

只不过我能够开发Android程序,于是就写了一个最简单的APP,界面上就一个控件,是个webView显示指定的网址。另外再加了一些上报手机电量,自动开屏,关屏的功能。
作者: tetgrt    时间: 2021-3-23 08:41
楼主fryefryefrye,怎样的条件?才能带我们跟着你做一套 呢?真的想跟你做一套。希望在你有空的时候能指定一下。
不胜感谢。
作者: fryefryefrye    时间: 2021-3-23 10:30
本帖最后由 fryefryefrye 于 2021-3-23 10:35 编辑
tetgrt 发表于 2021-3-23 08:41
楼主fryefryefrye,怎样的条件?才能带我们跟着你做一套 呢?真的想跟你做一套。希望在你有空的时候能指定 ...

总体架构介绍了,如果想做就开工呗。有问题回帖交流。

DIY作品,每个人的需求不一样的,只能靠每个人自己写代码实现。

要仿造我的这套系统,C语言必须要会的。服务端和物联网节点都是用c语言实现的。

我也是这10几年自己学出来的啊,只要有兴趣,这东西不难的。

作者: fryefryefrye    时间: 2021-3-23 10:38
本帖最后由 fryefryefrye 于 2021-3-23 10:58 编辑
ploestar 发表于 2021-3-22 21:08
是不是可以用ESP8266或esp32替换树莓派做服务器,好像没什么计算量,存储和IO数也没啥要求,主要是便宜和入门 ...

好主意,应该没问题。
我觉得可能的问题是内存消耗对于单片机来说有点高。
内存中要存储每一个节点的上传数据和下发命令。
还要存储html页面,这些也有好几K的。不过html页是静态的,不用变的。应该可以存在Flash里面,在运行的时候直接读取后发给手机。
另外就是生成页面上的可变信息的那一个“,”隔开的字符串。一般几百字节而已。
节点少的话,试试看吧。
主进程大概是这个样子。
        loop()
        {
                handle_udp_msg();   //处理接收到的节点数据
                handle_web_task(); //处理web请求
        }



作者: tetgrt    时间: 2021-3-23 12:00
fryefryefrye 发表于 2021-3-23 10:30
总体架构介绍了,如果想做就开工呗。有问题回帖交流。

DIY作品,每个人的需求不一样的,只能靠每个人自己 ...

楼主,如果涉及到代码问题,你是否愿意,指点或分享呢?
作者: tetgrt    时间: 2021-3-23 12:03
本帖最后由 tetgrt 于 2021-3-23 12:33 编辑

楼主,跟着你做一套,需要购买那些硬件?是否有材料清单或型号?
最好是能够在某宝,截图一下,具体购买那些材料和硬件。我会一些简单的51 和stm32,c语言懂一点,做过几个小DIY。没有搞过草莓派的,不知道是否能够做到呢?



谢谢。

作者: fryefryefrye    时间: 2021-3-23 12:38
本帖最后由 fryefryefrye 于 2021-3-23 12:39 编辑
tetgrt 发表于 2021-3-23 12:00
楼主,如果涉及到代码问题,你是否愿意,指点或分享呢?

如果你是初学者的话,先买两块NodeMCU板子 +1个 继电器模块吧。

先学会Arduino编程,烧进NodeMCU,控制继电器。然后去接线,尝试控制家里的灯。这就算入门单片机控制了。

上面一个同学说的很好,可以用另一块NodeMCU来代替树莓派做为服务器,便宜多了。

然后就可以尝试让两块NodeMCU板之间实现UDP通信,这样就能通过网络来控制灯了。
代码太多太复杂了,做一点,说一点吧。

作者: tetgrt    时间: 2021-4-1 11:36
前辈,请问一下,树莓派服务器,一定需要购买几百块的树莓派主板吗?
实现你的这个制作,一共投资多少钱呢?
请指点一下?
作者: tetgrt    时间: 2021-4-1 11:46
是否可以拿 esp32 代替树莓派做为服务器呢

ESP32+ESP8266 +stm32 这个 结构模式是否可以?
作者: fryefryefrye    时间: 2021-4-1 16:49
tetgrt 发表于 2021-4-1 11:46
是否可以拿 esp32 代替树莓派做为服务器呢

ESP32+ESP8266 +stm32 这个 结构模式是否可以? ...

之前我不是说了嘛,对于初学者,买两块NodeMCU板子,其实上面就是ESP8266芯片,只是大多数引脚都引出了,DIY比较方便。

一块做物联网节点,一块当作服务器。就可以先跑起来了。

等到你觉得一块ESP8266做服务器性能不够了,就可以尝试用ESP32,或者树莓派。
STM32 你准备在这里面做什么角色?

作者: tetgrt    时间: 2021-4-1 17:20
fryefryefrye 发表于 2021-4-1 16:49
之前我不是说了嘛,对于初学者,买两块NodeMCU板子,其实上面就是ESP8266芯片,只是大多数引脚都引出了,D ...

STM32 ,是准备用来,控制一些比较复杂一点 的东西,
我原来打算用STM32 +7寸HMI 串口屏,用来放在客厅作为主显示器的,
原来打算用RS485 来做Modbus通信协议,各个节点,通过RS485,汇聚到 主控的STM32 +7寸HMI 串口屏
现在见到你这种模式,可以比较好,而相对比较简单,所以 想 想跟着你学做一套?
你这里,是不是走MQTT协议的呢?

如果前辈能一步一步指点带 ,就不胜感谢!!!
作者: fryefryefrye    时间: 2021-4-2 11:29
tetgrt 发表于 2021-4-1 17:20
STM32 ,是准备用来,控制一些比较复杂一点 的东西,
我原来打算用STM32 +7寸HMI 串口屏,用来放在客厅作 ...

其实节点没有太复杂,尤其是为了保证每个节点的稳定可靠,我故意让每个节点功能最简化。所以一般一个ESP8266搞定。

按照我的方案做的话,主控制界面是一个网页,这样非常适合手机/电脑, 多平台访问。这个时候,找一台淘汰的安卓手机做为客厅主显示器就是一个最好的方案。这样大大简化了的操作界面的设计复杂度,特别是一处修改,处处可用。

我没有走MQTT协议,我觉得没这个必要。直接把节点需要交换的数据通过UDP协议直接发送就行了。

WiFi的可靠性还是稍微低一点的,偶尔无线频谱的干扰,还是会造成中断,我其实也在考虑过是否要用RS485总线机制。只是还没有很大的迫切性,而且布线也繁琐,所以没搞。 如果真的搞的话,我只要给树莓派添加一个485收发器就行了。连协议都可以沿用原来UDP的数据格式。
作者: tetgrt    时间: 2021-4-2 13:34
fryefryefrye 发表于 2021-4-2 11:29
其实节点没有太复杂,尤其是为了保证每个节点的稳定可靠,我故意让每个节点功能最简化。所以一般一个ESP8 ...

我现在有
一块是
ESP8266串口wifi模块 NodeMCU Lua V3物联网开发板 CH340 内存4M

另一块是
ESP8266 ESP01无线WIFI模块 无线收发 烧录固件 远距离串口透传

是否可以 做 你说那个UDP通信实验呢?

作者: tetgrt    时间: 2021-4-2 13:35
就是这两个板

作者: tetgrt    时间: 2021-4-2 13:51
因为是刚学搞这个,很多细节的东西都不知道,在请教几个问题
1、搞这个需要什么编程工具软件的?
2、需要用什么开发环境和编程语言?
3、会一些简单的C语言和51和stm32单片机方面的知识,能搞得成功吗?

谢谢。
作者: fryefryefrye    时间: 2021-4-2 14:45
本帖最后由 fryefryefrye 于 2021-4-2 14:55 编辑
tetgrt 发表于 2021-4-2 13:51
因为是刚学搞这个,很多细节的东西都不知道,在请教几个问题
1、搞这个需要什么编程工具软件的?
2、需要用 ...

硬件方面,那个8脚的别用了,麻烦。 就用那个NodeMCU挺好的。 如果节点要求小体积,买“ESP8266 D1”。都一样用,都是USB线插上,就可以烧录,熟悉了还可以通过wifi烧录,非常方便。
[attach]1124962[/attach]

软件就是Arduino的那个IDE,用C 写代码。 只是他本身的编辑器不是很好用,我一般用VS2019 或者NotePad++ 编辑代码。然后用Arduino烧录板子。
只要会C语言,就能搞定的。就是要学习一下TCP UDP通讯方面的知识。在Arduino上真的已经很简单了。
另外需要的硬件知识就是用单片机去控制所要控制的设备,比如怎么发射红外遥控信号,怎么控制继电器,采集温度,等等。




作者: fryefryefrye    时间: 2021-4-2 15:13
tetgrt 发表于 2021-4-2 13:51
因为是刚学搞这个,很多细节的东西都不知道,在请教几个问题
1、搞这个需要什么编程工具软件的?
2、需要用 ...

给你一个我的所有节点的模板文件吧。这是一个带OTA功能的模板。
我每次新搞一种类型的节点,就会把这个文件里面的xxxxx改成这个节点的种类的名字,然后改改数据读取的地方。收到数据,执行命令的地方,就可以加入物联网了。
  1. //D0 = GPIO16;
  2. //D1 = GPIO5;
  3. //D2 = GPIO4;        LED on esp8266
  4. //D3 = GPIO0;can not download when connected to low
  5. //D4 = GPIO2;       
  6. //D5 = GPIO14;  
  7. //D6 = GPIO12;
  8. //D7 = GPIO13;
  9. //D8 = GPIO15;  can not start when high input
  10. //D9 = GPIO3; UART RX
  11. //D10 = GPIO1; UART TX
  12. //LED_BUILTIN = GPIO16 (auxiliary constant for the board LED, not a board pin);


  13. #include<ESP8266WiFi.h>
  14. #include<WiFiUdp.h>
  15. #include<ESP8266mDNS.h>
  16. #include<ArduinoOTA.h>
  17. #include<ESP8266WiFiMulti.h>
  18. #include<time.h>
  19. #define timezone 8


  20. const char* ssid = "";  //Wifi名称
  21. const char* password = "";  //Wifi密码
  22. WiFiUDP m_WiFiUDP;

  23. char *time_str;   
  24. char H1,H2,M1,M2,S1,S2;

  25. //#include "datastruct.h"
  26. //下面这两个数据结构的例子,一般放在一个H文件里面,方便和服务器的代码共用
  27. struct tXXXXXXXXData
  28. {
  29.         unsigned long DataType; //data type = 5
  30.         unsigned long Mac[6];
  31.         unsigned long Power;                //xx.xxxx W
  32.         unsigned long TotalEnergy;                //xxxxxx.xx kWh
  33.         unsigned long Volt;                        //xxx.x v
  34.         unsigned long Current;                //xxx.xxx A

  35. };

  36. struct tXXXXXXXXCommand
  37. {
  38.         unsigned long Triger;
  39.         unsigned long On;
  40. };






  41. tXXXXXXXXData XXXXXXXXData;
  42. unsigned long LastServerUpdate;


  43. unsigned long TenthSecondsSinceStart = 0;
  44. void TenthSecondsSinceStartTask();
  45. void OnTenthSecond();
  46. void OnSecond();

  47. void setup()
  48. {      
  49.         delay(50);                     
  50.         Serial.begin(115200);

  51.         XXXXXXXXData.DataType = 0;

  52.         WiFi.disconnect();
  53.         WiFi.mode(WIFI_STA);//设置模式为STA
  54.         byte mac[6];
  55.         WiFi.softAPmacAddress(mac);
  56.         printf("macAddress 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\r\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
  57.         for (byte i=0;i<6;i++)
  58.         {
  59.                 XXXXXXXXData.Mac[i] = mac[i];
  60.         }

  61.         Serial.print("Is connection routing, please wait");  
  62.         WiFi.begin(ssid, password); //Wifi接入到网络
  63.         Serial.println("\nConnecting to WiFi");
  64.         //如果Wifi状态不是WL_CONNECTED,则表示连接失败
  65.         unsigned char WiFiTimeOut = 0;
  66.         while (WiFi.status() != WL_CONNECTED) {  
  67.                 Serial.print(".");
  68.                 delay(1000);    //延时等待接入网络
  69.                 WiFiTimeOut++;
  70.                 if (WiFiTimeOut>10)
  71.                 {
  72.                         break;
  73.                         Serial.println("\nConnecting to WiFi Failed");
  74.                 }
  75.         }

  76.         //设置时间格式以及时间服务器的网址
  77.         configTime(timezone * 3600, 0, "pool.ntp.org", "time.nist.gov");
  78.         Serial.println("\nWaiting for time");
  79.         while (!time(nullptr)) {
  80.                 Serial.print(".");
  81.                 delay(1000);   
  82.         }
  83.         Serial.println("");

  84.         ArduinoOTA.onStart([]() {
  85.                 String type;
  86.                 if (ArduinoOTA.getCommand() == U_FLASH) {
  87.                         type = "sketch";
  88.                 } else { // U_SPIFFS
  89.                         type = "filesystem";
  90.                 }

  91.                 // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
  92.                 Serial.println("Start updating " + type);
  93.         });
  94.         ArduinoOTA.onEnd([]() {
  95.                 Serial.println("\nEnd");
  96.         });
  97.         ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
  98.                 Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  99.         });
  100.         ArduinoOTA.onError([](ota_error_t error) {
  101.                 Serial.printf("Error[%u]: ", error);
  102.                 if (error == OTA_AUTH_ERROR) {
  103.                         Serial.println("Auth Failed");
  104.                 } else if (error == OTA_BEGIN_ERROR) {
  105.                         Serial.println("Begin Failed");
  106.                 } else if (error == OTA_CONNECT_ERROR) {
  107.                         Serial.println("Connect Failed");
  108.                 } else if (error == OTA_RECEIVE_ERROR) {
  109.                         Serial.println("Receive Failed");
  110.                 } else if (error == OTA_END_ERROR) {
  111.                         Serial.println("End Failed");
  112.                 }
  113.         });
  114.         ArduinoOTA.begin();
  115.         Serial.println("Ready");
  116.         Serial.print("IP address: ");
  117.         Serial.println(WiFi.localIP());

  118.         m_WiFiUDP.begin(5050);
  119. }

  120. void loop()
  121. {
  122.         ArduinoOTA.handle();

  123.         TenthSecondsSinceStartTask();


  124.         //接受服务器发来的命令
  125.         m_WiFiUDP.parsePacket();
  126.         unsigned int UdpAvailable = m_WiFiUDP.available();
  127.         if (UdpAvailable == sizeof(tXXXXXXXXCommand))
  128.         {
  129.                 printf("UDP got %d bytes\r\n",UdpAvailable);
  130.                 tXXXXXXXXCommand tempXXXXXXXXCommand;
  131.                 m_WiFiUDP.read((char *)&tempXXXXXXXXCommand,sizeof(tXXXXXXXXCommand));
  132.                 LastServerUpdate = 0;
  133.         }
  134. }

  135. unsigned long LastMillis = 0;
  136. void TenthSecondsSinceStartTask()
  137. {
  138.         unsigned long CurrentMillis = millis();
  139.         if (abs(CurrentMillis - LastMillis) > 100)
  140.         {
  141.                 LastMillis = CurrentMillis;
  142.                 TenthSecondsSinceStart++;
  143.                 OnTenthSecond();
  144.         }
  145. }

  146. void OnSecond()
  147. {
  148.         time_t now = time(nullptr); //获取当前时间
  149.         time_str = ctime(&now);
  150.         H1 = time_str[11];
  151.         H2 = time_str[12];
  152.         M1 = time_str[14];
  153.         M2 = time_str[15];
  154.         S1 = time_str[17];
  155.         S2 = time_str[18];
  156.         printf("%c%c:%c%c:%c%c\n",H1,H2,M1,M2,S1,S2);
  157.         //Serial.printf(time_str);

  158.         struct   tm     *timenow;
  159.         timenow   =   localtime(&now);
  160.         unsigned char Hour = timenow->tm_hour;
  161.         unsigned char Minute = timenow->tm_min;



  162.         //在此,每秒去读取各类数据,功率,温度之类的,并保存在下面的数据结构中
  163.         XXXXXXXXData.Volt = 100;


  164.         //每秒向服务器发送一次数据
  165.         m_WiFiUDP.beginPacket("192.168.0.17", 5050);
  166.         m_WiFiUDP.write((const char*)&XXXXXXXXData, sizeof(tXXXXXXXXData));
  167.         m_WiFiUDP.endPacket();
  168. }

  169. void OnTenthSecond()
  170. {
  171.         if (TenthSecondsSinceStart%10 == 0)
  172.         {
  173.                 OnSecond();
  174.         }
  175. }
复制代码



作者: fryefryefrye    时间: 2021-4-2 15:39
tetgrt 发表于 2021-4-2 13:51
因为是刚学搞这个,很多细节的东西都不知道,在请教几个问题
1、搞这个需要什么编程工具软件的?
2、需要用 ...

你可以照着我写的例子,把UDP通信搞起来。

我准备这段时间,写一个运行在ESP8266上的服务器。
作者: tetgrt    时间: 2021-4-2 16:04
明白一些,非常 感谢,楼主的细心指点。那还有一点疑问的地方?
1、那么现在的系统结构是,一个NodeMCU 作为主机+外加几个节点(节点也是采用NodeMCU)这样理解对吗?
2、NodeMCU 的主机作为服务器,设置ip地址,在手机端或家里的pc机,通过浏览器 ,浏览器 服务器的ip地址,就可以看到 数据信息?
作者: fryefryefrye    时间: 2021-4-2 16:18
tetgrt 发表于 2021-4-2 16:04
明白一些,非常 感谢,楼主的细心指点。那还有一点疑问的地方?
1、那么现在的系统结构是,一个NodeMCU 作 ...

是的,现在第一步,服务器和节点全部都是NodeMCU。 等到有性能问题的时候,再考虑升级服务器。

服务器要设置固定IP地址,这样手机和PC都可以在家访问。通过公网IP、动态域名、网络映射也可以外网访问。

我刚才大概研究了一下ESP8266做服务器的方案:
1:ESP8266 带有文件储存区域,html文件模板上传到这个区域。
2:有一个现成的类 ,叫做ESP8266WebServer,可以直接使用,实现web服务。

已经很简单了。
你可以看看https://cloud.tencent.com/developer/article/1668549

我有时间写一个来开源。
作者: asd3330303    时间: 2021-4-2 21:47
看了下,双控用继电器蛮耗电的,继电器需要5v100ma的电,双控的话关着的时候也可能会需要继电器通着
作者: fryefryefrye    时间: 2021-4-2 23:16
asd3330303 发表于 2021-4-2 21:47
看了下,双控用继电器蛮耗电的,继电器需要5v100ma的电,双控的话关着的时候也可能会需要继电器通着 ...

你搞错了吧,继电器是5v7ma 。

我不知道你是怎么设计电路的,反正我的电路中,灯亮才吸和,灯关就释放了。 开关是直接接到单片机的IO口上的,电流忽略不计。
作者: fryefryefrye    时间: 2021-4-3 08:22
tetgrt 发表于 2021-4-2 16:04
明白一些,非常 感谢,楼主的细心指点。那还有一点疑问的地方?
1、那么现在的系统结构是,一个NodeMCU 作 ...

代码已经放在了:https://gitee.com/fryefryefrye/O ... tomation/ESP8266Web

有时间我再写个说明吧。
作者: tetgrt    时间: 2021-4-3 09:06
fryefryefrye 发表于 2021-4-3 08:22
代码已经放在了:https://gitee.com/fryefryefrye/Open-Source-RKS/tree/master/HomeAutomation/ESP8266W ...

谢谢,前辈的指点
1、现在要再,购买一些元器件模块,那么除了NodeMCU 模块,还需要购买那些元器件呢?
2、比如 节点具体实现某一个功能,或某一应用场景,还需要 购买那些元器件呢?

谢谢。
作者: fryefryefrye    时间: 2021-4-3 10:28
本帖最后由 fryefryefrye 于 2021-4-3 10:31 编辑
tetgrt 发表于 2021-4-3 09:06
谢谢,前辈的指点
1、现在要再,购买一些元器件模块,那么除了NodeMCU 模块,还需要购买那些元器件呢?
2 ...

已公开的代码,节点的功能就是控制两盏灯。暂时只做了通过网络控制开关的功能。
买一个双路继电器模块就行了。 买5v电压的。

作者: nonzhe    时间: 2021-4-4 07:10
太棒了,有没有源代码可以分享,特别是树莓派服务器和安卓显示那部分?
作者: dujq    时间: 2021-4-4 12:42
正在研究这个。可以用esp32s2
作者: fryefryefrye    时间: 2021-4-4 15:51
dujq 发表于 2021-4-4 12:42
正在研究这个。可以用esp32s2

ESP8266确实性能和资源不大够。但是我手头上没有空闲的ESP32,所以先用ESP8266写了。

不过这两块板子的代码,用Arduino烧的话,基本上是完全通用的。
作者: fryefryefrye    时间: 2021-4-4 16:30
nonzhe 发表于 2021-4-4 07:10
太棒了,有没有源代码可以分享,特别是树莓派服务器和安卓显示那部分?

树莓派的代码写的太复杂了,有网友提议用ESP8266/ESP32作为服务器平台,我觉得是个好主意。

我重新写了用ESP8266做服务器,你可以先看55楼。有时间我再写详细介绍。
作者: tetgrt    时间: 2021-4-5 19:50
谢谢,楼主的,指点
近期先学习 nodemcu esp 8266的 ardunio IED 开发板的一些视频教程 ,遇到问题,再向你请教,非常感谢楼主的热情指点。
作者: fryefryefrye    时间: 2021-4-6 10:52
tetgrt 发表于 2021-4-5 19:50
谢谢,楼主的,指点
近期先学习 nodemcu esp 8266的 ardunio IED 开发板的一些视频教程 ,遇到问题,再向你 ...

不着急,慢慢学吧。
除了Arduino里面需要写C代码。

操作面板需要一点基本的html代码的知识,反正模板我都写好了,你只要照样子写html关键字,画出表格,来形成界面。表格中可以填充数据,也可以填充控制按钮。
页面里面,填充的部分,应该算是Java脚本吧?我都不大确定,反正跑起来了,依葫芦画瓢,把逗号分隔的字符串,按顺序填充就行了。

另外就是硬件知识,接上继电器让继电器动起来,还算简单,下面就要接220v强电了,一定要小心操作。
还可以发射红外信号控制空调之类,硬件就是焊一个红外发光二极管就行。软件就要找相应的库来发送空调的控制信号。
作者: jjbboox    时间: 2021-4-6 11:26
fryefryefrye 发表于 2021-3-23 10:38
好主意,应该没问题。
我觉得可能的问题是内存消耗对于单片机来说有点高。
内存中要存储每一个节点的上传 ...

一个基于SPIFFS文件系统的Esp32WebServer的例子。
供你参考

data目录中就是一个小型网站的用到的各种文件。
https://github.com/jjbboox/EspWebServer

作者: srygg    时间: 2021-4-8 19:08
谢谢楼主分享。
慢慢跟着楼主学习!
作者: sadfun    时间: 2021-4-9 18:32
你这也太厉害了吧,最最最~主要的是还有时间搞
作者: h25090    时间: 2021-4-11 11:08
谢谢楼主分享。
慢慢跟着楼主学习!
作者: q826358    时间: 2021-4-11 20:48
风格和借记卡酷酷会很尴尬
作者: liubosen    时间: 2021-4-12 09:22
fryefryefrye 发表于 2021-3-17 23:22
Android 和 苹果 手机都可以把一个网址做成一个快捷方式放在桌面上。

所需要的操作就是按一下桌面上的图 ...

这个很是牛。希望楼主开个专贴教一下。家里有一台小米WIFI路由器,插U盘或移动硬盘只能在家里访问,请问下有没有啥办法在外面也可以访问(读写)的
作者: fphoenix84    时间: 2021-4-12 13:07
高端玩法,学习了
作者: wuzhou    时间: 2021-4-12 18:29
懂编程就是好
作者: tjjtds1    时间: 2021-4-13 20:30
我的想法是把这个web移植到路由器里或者软路由里,这样会方便很多。手里正好有一套8266,想入门。
作者: infozx    时间: 2021-4-14 16:41
看到Ajax不禁老泪纵横
作者: ploestar    时间: 2021-4-14 18:10
liubosen 发表于 2021-4-12 09:22
这个很是牛。希望楼主开个专贴教一下。家里有一台小米WIFI路由器,插U盘或移动硬盘只能在家里访问,请问 ...

端口映射,没公网IP的话,还得穿透
作者: wangshipeng    时间: 2021-4-15 20:31
这个太牛了,有技术就是厉害
作者: msold5    时间: 2021-4-16 11:01
1、不建议用ESP32做服务器,对于今后很可能要扩展出更强大的应用,ESP32铁定了不够用,倒是可以考虑下在旧手机上做安卓端
2、楼主的界面中,建议根据重要性,把不重要的内容改成灰色,这样可以突出重点内容,不至于满屏信息
3、如果做长线智能家居,申请个子版块一起讨论,进而做大做强,还有很多大厂未整合的细节,值得努力去进一步智能化
作者: fryefryefrye    时间: 2021-4-16 15:40
msold5 发表于 2021-4-16 11:01
1、不建议用ESP32做服务器,对于今后很可能要扩展出更强大的应用,ESP32铁定了不够用,倒是可以考虑下在旧 ...

实际我家运行在树莓派上,确实计算资源足够。所有的数据,生成大量的log文件,往NAS上记录,包括读取。

界面中重要的大多数都是状态,我已经用红绿色表示就行了,我一般一眼看过去,都是绿的就行。红色就是要特别关注的。
作者: msold5    时间: 2021-4-18 14:04
fryefryefrye 发表于 2021-4-16 15:40
实际我家运行在树莓派上,确实计算资源足够。所有的数据,生成大量的log文件,往NAS上记录,包括读取。

...

树莓派当然没问题,ESP32虽然省电和省钱,但性能太弱了,多拖一些功能就会捉襟见肘,万一后期要扩充监控类的管理、或者网络类的定时管理什么的,都可能会导致一些麻烦,不易于发展
作者: xuper    时间: 2021-4-20 22:43
这个太厉害了,我现在手机就是一堆“智能”app
作者: tetgrt    时间: 2021-4-21 14:35
请问,能否基于NAS  做web做服务器呢? 这样就满足性能了,楼主探讨一下。
作者: bg4oqx    时间: 2021-5-2 05:14
给楼主点赞,看看能否利用就安卓手机或者平板来实现智能家控系统。
作者: muyan    时间: 2021-5-16 22:22
请教一下 “接一个普通墙壁开关”,普通开关是原先控制220v的还是另外改了开关呢,如果接220v开关,如何判断
作者: muyan    时间: 2021-5-16 22:58
本帖最后由 muyan 于 2021-5-16 22:59 编辑

另外,把8266塞进开关里面,还要电源才行,如果开关里面只有火线,又没法实施了吧,不过看到过声控灯里面只接火线的,不知道如何供电的
作者: fryefryefrye    时间: 2021-5-17 13:20
本帖最后由 fryefryefrye 于 2021-5-17 13:39 编辑
muyan 发表于 2021-5-16 22:22
请教一下 “接一个普通墙壁开关”,普通开关是原先控制220v的还是另外改了开关呢,如果接220v开关,如何判 ...

至少我做的DIY,开关处必须另拉零线。如果实在没有这个条件,你可以试试看淘宝上有单火线供电模块,看看是否可以解决这个问题。

电路方面,灯的亮灭,完全是由继电器控制了。然后把原来的墙壁开关,接到单片机的IO口和地之间(完全是弱电,不接220v),IO口设置为内部上拉,就可以用这个开关产生一个高低电平信号,单片机监视这个高低电平,如果发现变位,就把继电器的当前状态也变一下。
作者: muyan    时间: 2021-5-17 15:10
fryefryefrye 发表于 2021-5-17 13:20
至少我做的DIY,开关处必须另拉零线。如果实在没有这个条件,你可以试试看淘宝上有单火线供电模块,看看是 ...

已经看过万能的x宝了,的确不少方案就是用了单火线供电

这样开关只是作为一个开关了,我原本想着是否共存,万一单片机挂了,还能控制

简单实用,总要有取舍
作者: fryefryefrye    时间: 2021-5-17 15:46
muyan 发表于 2021-5-17 15:10
已经看过万能的x宝了,的确不少方案就是用了单火线供电

这样开关只是作为一个开关了,我原本想着是否共 ...

单片机挂了的概率实在太小了,我加这个开关,其实是为了防止WiFi挂掉。

而且不是就控制顶灯照明吗,就算出问题了,把照明空开关掉,用台灯,也能凑合过一晚。
作者: muyan    时间: 2021-5-17 16:47
fryefryefrye 发表于 2021-5-17 15:46
单片机挂了的概率实在太小了,我加这个开关,其实是为了防止WiFi挂掉。

而且不是就控制顶灯照明吗,就算 ...

了解了,谢谢分享:handshake:
作者: tigerzq    时间: 2021-10-14 18:25
UDP也是协议,是传输层的协议,只能说是不可靠的协议而已,比起TCP而言速度快,简单。
作者: ahyu99    时间: 2021-10-15 20:08
本帖最后由 ahyu99 于 2021-10-15 20:12 编辑

有兴趣的同学还可以玩玩Home Assistant来做智能家居。

不过搂住的做法很好,我本人也是这么做的,用的是树莓派Zero W做服务器,也是通过UDP协议,用C语言写程序,将数据上传到阿里云服务器的。2019年开始运行的,一直到现在很稳定。我的功能没有楼主那么多。

不过,楼主可以安装一个lighttpd做web服务器,然后用它的CGI功能就可以扩展很多的需要的功能了。这样扩展起来也方便,自己专注把智能家居的控制功能写好就可以了。


作者: tvro888    时间: 2021-12-2 15:58
大牛,玩啥都优秀。小白等着大神大作完工,原样抄一下,看不懂代码很尴尬:sweat:
作者: tvro888    时间: 2021-12-2 16:04
牛人,用技术改变生活。软件部分看不懂,拖后腿了。
作者: 牛犇犇牛    时间: 2021-12-6 21:44
太高大上了!
作者: camell    时间: 2021-12-7 11:44
不错, 有医院和高铁的味道
作者: lmn2005    时间: 2021-12-12 14:10
功能太多了,只能观望,楼主真的了不起!
作者: leijunwu1    时间: 2022-10-31 13:57
其实这个不一定要用到树莓派,一台旧老手机。当然要好一点的就更好用,写一个服务器App,做中转,实现控制家电,数据传递。还是不错的。

作者: 84939849    时间: 2022-10-31 16:48
服务器这块,我用openwrt路由代替典型rg100a,这种才10来块,核心是它有wifi,搞个专用的局域网基本不会影响家里的住网络,
作者: 惠明电气    时间: 2022-11-10 10:05
大神,我的目标吧
作者: xdq286    时间: 2022-11-10 11:47
感谢楼主分享,高级,
作者: chinakimb    时间: 2022-12-13 19:15
这个一定要留名关注,这正是我梦想做的。
作者: jjkai2008    时间: 2023-1-6 10:39
楼主太厉害了,这是一个大工程,不是一般人能做出来的。有一张图片里看到楼主家都用到47U机柜了,而且不止一个,看来楼主还有很多后续工作要做啊。




欢迎光临 数码之家 (https://www.mydigit.cn/) Powered by Discuz! X3.4