物联网(Iot)台灯设计完整教程(长图文)

2023-05-16

现如今随着物联网的概念深入人心,物联网的设备也越来越普及,本篇文章介绍的就是一个物联网台灯的设计。该设计主要包含物联网芯片开发、微信客户端开发、后台服务器端开发以及三个组件之间互联等,其总体设计逻辑框图如图1所示。

图 1远程控制台灯设计逻辑图

本设计中,采用的物联网芯片为四博智联科技公司生产的Esp8266只能WiFi模块。生产该类WiFi模块的公司有很多,除了四博智联之外,相对更有名的应该是乐鑫以及安信可公司,但不知道什么原因,设计过程中购得的所有芯片都是四博智联的。当然,不论厂家是哪一个,芯片逻辑以及开发工具基本都是通用的。

最初设计时由于之前研究生过程中做过电路设计相关的课题工作,所以自认为可以直接对芯片进行电路设计以及软件调试。但在调试了一段时间之后,发现自己连接的电路完成不了通信,使用电脑串口调试完全没有反应。其实这个模块的电路设计很简单,但也可能是因为连接线接触不好的原因(使用杜邦线以及面包板实现的连接),致使一直不能实现串口调试。后来考虑到时间成本,于是网上又选购了一个带有调试接口的wifi模块。该模块入手即可串口调试,很是方便,节省了大量开发时间。所以对于电路知识储备不足的同学,可以选择开发模块入手。网购的傻瓜式模块如图所示。

图 2 傻瓜式wifi模块

 

本设计中WiFi模块需要完成自动入网以及和MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)服务器通信的功能,所以在此对于基础的AT指令操作不进行介绍,我们直接进行WiFi模块自主联网的设计。

WiFi模块开发环境,选用的是安信可的IDE设计工具AiThinkerIDE_V0.5。之所以选择这个软件是因为本人做dsp开发时采用的工具是Code Composer Studio,安信可的IDE设计软件和平常用到的Code Composer Studio开发环境类似,所以上手相对容易。其开发环境如下图所示,用过linux中Eclipse软件的同学对这个界面应该同样熟悉。

图 3 AiThinkerIDE开发环境

 

该软件中还自带一些示例工程,其中包含Wifi连接的示例程序,所以可以直接将例子中的程序模块拿来使用。需要修改的地方主要为宏定义,包括需要连接的wifi名称以及密码等,其他的函数方法都已经封装完成。

Wifi模块与服务器端进行数据交互采用的是MQTT协议。MQTT是IBM开发的一个即时通讯协议,是面向M2M(Machine-to-Machine/Man)和物联网的连接协议,采用轻量级发布和订阅消息传输机制。总的来说,就是因为集成简单,消息发布接收迅捷,适合在硬件这些本来有限的开发空间,实现远程控制。

MQTT通信的基本方式为发布与订阅。在一个通信网络中,设备既可以发布消息,也可以接收消息。假设某一个设备A在网络中充当的是发布消息的一方,发布消息的格式为“主题”+“内容”,如果另一个设备B想要接收到A发布的消息,则只需要启动订阅功能,并且将订阅的“主题”与A发布的“主题”一致,则B可以接收到A发布的消息内容;若设备B订阅的消息主题与A发布的主题不一致,则设备B就不会收到A发布的消息了。因此,在我看来,这个主题实际上充当了“filter”的功能,匹配则通过,否则滤掉。

MQTT客户端

IDE中对于MQTT客户端的配置通过例程修改的话相对比较简单,主要需要修改的内容如下图所示:

图 4 MQTT客户端配置

 

其中各个宏定义的意思主要为:

MQTT_HOST:MQTT服务器所在的IP地址。

MQTT_PORT:MQTT通信使用的端口号,该协议使用的就是1883端口。

MQTT_CLIENT_ID:这是客户端的ID,一般每一个客户端都拥有自己单独的ID,同一个局域网络内不能有重复的ID,所以也可以使用系统登陆时间作为ID。

MQTT_USER:MQTT客户端登陆到服务器端的账号。

MQTT_PASS:MQTT客户端登陆进入服务器的密码。

STA_SSID:本地的WIFI账号名称。

STA_PASS:本地WIFI登陆密码。

代码中关于发布或者订阅消息的模块在函数mqttConnectedCb中进行配置,具体代码如下所示,该段代码中订阅了两个主题,并且依次发布了三个主题消息。函数MQTT_Subscribe以及MQTT_Publish中的第二个参数为主题名称。

void mqttConnectedCb(uint32_t *args)

{

         u32_t ret = 0;

         os_printf("MQTT: Begin to subscribe\r\n");

    MQTT_Client* client = (MQTT_Client*)args;

    INFO("MQTT: Connected\r\n");

    ret = MQTT_Subscribe(client, "/lol_get/0", 0);

    os_printf("MQTT subscribe result is : %d\r\n",ret);

    MQTT_Subscribe(client, "/Shutdown/", 1);

    MQTT_Subscribe(client, "/Lighton/", 2);



    MQTT_Publish(client, "/lol/0", "hello0", 6, 0, 0);

    MQTT_Publish(client, "/lol/1", "hello1", 6, 1, 0);

    MQTT_Publish(client, "/lol/2", "hello2", 6, 2, 0);

}

程序修改完成之后,切记一定要点击保存所有的按钮,否则即使使用编译选项,也只是编译的修改前的内容,这也是IDE的一个漏洞。保存并且编译成功之后,在IDE的控制台(console)界面会显示如图5所示的信息。这就是代码烧写到wifi模块flash上的地址。


图 5 IDE程序编译结果

接下来我们需要进行程序的烧写,使用数据线连接wifi模块之后,打开我们的烧写软件ESPFlashDownloadTool_v3.4.4,然后按照图6的设置将待烧写的文件配置好,点击“START”即可进行烧写操作。另外由于各个芯片及模块的SPI主频以及flash等参数不一致,所以需要各位翻阅用户手册后选择合适的参数配置。

图 6 IDE程序烧写配置

 

在程序固化过程中,软件底部的进度条会显示程序固化的进度,所有程序固化完成之后的显示信息如图7所示:

图 7烧写成功提示

 

这样我们修改后的MQTT的客户端代码就固化到我们的wifi模块中,重新上电wifi模块,将会看到如图8所示的内容:wifi模块的MQTT客户端程序联网成功(Connect to broker,这里的broker其实就是EMQ服务器端)并且订阅发布了消息。

 

图 8 Esp8266wifi模块调试结果

 

这就说明我们的Esp8266 wifi模块的MQTT客户端已经配置成功。此时就可以通过另一个MQTT的节点与其通信测试。经过验证,同一个MQTT的网络中只需要有一个服务器端,即目前的EMQ服务器(稍后会进行介绍),网络内所有与该服务器相连的客户端节点均可以通过发布订阅消息实现点对点的交互。

EMQ服务器端

Esp8266的wifi模块中即使加入了程序,也只能是做客户端,所以需要有一个服务器端来与之通信并且进行后台信息处理。在此,我们选用的是免费开源的EMQ服务器,EMQ是基于Erlang/OTP语言平台开发,百万级分布式开源物联网MQTT消息服务器。为了保证服务器能够长时间处于开启的状态,我们选择了阿里云的服务器作为EMQ服务器的运载平台。

阿里云服务器需要购买,但是即使最基本的配置,一年租用下来的费用也要200左右,最早在看到这个价格之后,首先选用的是按量付费的方式,这样在不使用的情况下可以关闭服务器,但是后来发现即使不使用并且将服务器关闭了,但服务器后台的费用仍然在扣除,虽然不多(一小时大概1分钱左右),但是时间长了不用的话,白白扣除余额也是挺不爽的。

后来观察到,阿里云对于新用户有一次免费申请云服务器的机会,基础系统配置免费使用一个月,但是需要每天10点准时抢购,抢购的难度也不大,或许本来使用云服务器的个体就很少吧,公司的话应该看不上这基础配置。再有一个更好的消息就是新用户免费服务器用完续费的话首年年费是99元,之后就恢复原价,我看到的2年的年费大概600左右,所以首年的年费99元还是相当划算了。

阿里云服务器购买的过程主要以图片形式进行介绍,步骤如下:

  1. 首先注册一个阿里云的账号,由于阿里云与淘宝是一个机构,所以我使用的淘宝账号进行登陆。
  2. 登陆账号之后进入主界面,点击“创建实例”来选购一个服务器。

 

图 9阿里云创建服务器实例
  1. 进入创建实例的页面以后,根据自己的需求选择处理器能力、区域以及操作系统等,在此,我们可以看出每一月的费用都要200+。

 

图 10确认系统配置
  1. 之后确认订单之后就完成了服务器的建立。
  2. 另外可以选择先进行免费主机的领取试用,这个页面如果找不到的话可以在阿里云网站内部的搜索引擎内搜索“免费云主机试用一年”后选择第一个链接进入。

 

图 11免费主机申请
  1. 进入该链接后可以找到个人免费套餐产品,一般都是要早上10点开始抢,图12中我已经在使用了,所以显示的是直接去控制台的按钮。
图 12福利免费服务器
  1. 如果已经抢到了免费服务器,在续费菜单中选择自动续费,还会有优惠,首年99元。图13是已经续费成功的服务器主机,虽然处理能力不是挺强大,但个人使用已经足够并且极其实惠了。
    图 13续费优惠

     

服务器购买完成之后,接下来就是在服务器平台上安装我们要使用的EMQ服务器了。由于选用的是linux的操作系统,系统版本是64位的CentOS7.4,因此,安装软件的过程中也是按照linux操作系统的shell指令来进行安装。在此附一份linux操作指令大全(http://www.cnblogs.com/sxdcgaq8080/p/7470796.html)以供各位参考。

安装EMQ服务器的过程中,我们首先需要选择对应版本的EMQ安装包进行下载(下载地址为http://emqtt.com/downloads)或者直接在阿里云服务器控制台内输入如下的shell指令来完成云服务器端的下载。

wget http://emqtt.com/static/brokers/emqttd-centos7-v2.3.1.zip

在此再向各位推荐一个个人认为比较好用的虚拟主机与本地电脑之间互传文件的小工具“Winscp”,网上可以直接搜索下载或者从我的百度云盘中(链接:https://pan.baidu.com/s/1E94pVf9RI066hbsarPhA5w 提取码:rgm7)获取。该软件操作界面如图14所示,登陆过程中只需要像登陆云服务器一样输入root用户名以及密码即可,文件协议选择sftp,端口号默认即可。

 

图 14 Winscp登陆配置

之后进入EMQ安装包所在的位置,因为刚配置好的云服务器平台没有unzip解压缩软件,而EMQ服务器的安装包中除了prm包就是zip包,所以我们需要先在阿里云服务器平台内安装unzip软件,安装指令是用的是“yum install”,具体指令如下所示:

yum install unzip –y

之后对于刚才下载的EMQ的压缩包进行解压,操作指令如下:

unzip emqttd-centos7-v2.3.1.zip

当控制台出现一串信息时,此时文件正在解压,之后通过“ll”指令来查看解压缩以后的效果,如下图所示:

 

图 15查看文件指令

图15中的第一个文件夹emqttd即我们压缩包解压后的文件所在,接下来通过cd指令进入该文件夹。

cd emqttd

此时,我们需要通过指令将该mqtt服务器打开,其操作指令为:

./bin/emqttd console

如果控制台打印出如图16所示的信息时,说明我们的emq服务器已经运行成功。

 

图 16 emq控制台启动

但此时我们整个服务器都被这一个软件进程占用,所以我们可以通过先“ctrl+c”退出当前进程,使用另外一个指令来后台运行EMQ服务器。

./bin/emqttd start

假如其运行结果如下图所示,则说明EMQ服务器已经在后台成功运行。若是提示某些端口被占用,则可以先关闭占用端口的进程,然后重新后台启动EMQ服务器。

 

图 17 EMQ服务器后台启动

由于阿里云默认的网络端口只有几个,并不包含EMQ的端口18083和1883,因此我们需要在我们的云服务器中添加对应的端口。首先在服务器实例详情中选择“配置规则”。

 

图 18安全组规则配置

进入界面之后,按照图19所示分别添加8083、1883(TCP)、1883(UDP)、18083等端口信息。

 

图 19添加MQTT端口

接下来我们可以在浏览器中输入主机的公网IP和端口号18083(例如:11.22.33.44:18083)来再次确认我们的MQTT服务器已经启动。如果出现图20所示的界面,则表示服务器完美运行,此时我们需要输入登录信息来登陆这个EMQ的控制平台。默认账号为admin,密码为public。

 

图 20 EMQ控制台

登陆进入后的页面如图所示,到了这一阶段,我们就可以通过这个EMQ控制台中的Websocket工具来和我们先前固化好程序的wifi模块进行通信调试了。

 

图 21Websocket控制台

调试结果如图22所示,我们通过EMQ控制台发布消息,在wifi模块的信息显示端查看订阅到的消息。在本设计当中,我们的wifi模块订阅的主题为“/Shutdown/”,因此我们通过EMQ控制台的websocket工具下发一个相同主题的信息,测试结果如图22所示。Websocket工具中显示已经发送一个主题为“/Shutdown/”,内容为“Hello World”的消息;同时,连接wifi模块的串口工具中也显示已经接收到一个同样的消息。因此,我们关于wifi模块与EMQ服务器之间的MQTT协议的通信已经测试成功。

 

图 22 MQTT协议调试

微信小程序客户端开发

微信小程序的开发主要包含三个方面:小程序界面开发、小程序后台开发以及小程序与后台的通信。

首先,如果要开发小程序,我们需要选择一个开发环境。微信小程序官方网站就带有“微信web小程序开发者工具”,所以我们直接到官网下载即可。

使用微信登陆开发者工具之后,发现需要一个AppID才能够登陆工具,因此选择注册之后,就来到了官方网站中。在网上看到,其实早期的开发者工具是不需要AppID就可以登陆的,但目前的版本没有ID已经无法实现登陆了,即使查看别人的例程也需要自己拥有一个AppID。

 

图 23小程序AppID

申请资料可以根据自身的情况填写,本设计中填写的是个人开发者类型,填写的内容也相对较少。申请完成会后可以到设置菜单下查看自己的AppID。接下来就可以打开开发者工具的开发环境了。具体步骤可以参阅官方的新手介绍

(https://developers.weixin.qq.com/miniprogram/introduction/#%E6%B3%A8%E5%86%8C%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%B8%90%E5%8F%B7)。

 

图 24查看AppID

使用AppID登陆进入之后,选择一个普通的快速启动模板即可,开发者工具默认提供的就是一个如图25所示的可以运行的例程,所以我们只需要按照自己的想法添加元素、功能即可。

 

图 25开发者工具界面

初始的模板程序中包含两个文件夹,分别是Pages和utitls,我们最开始显示的界面是Pages/index/index.wxml文件配置的。所以对于界面的设计,我们可以通过编辑index.wxml来实现。另外对于程序中需要调用的函数,我们可以在.js文件内来进行定义。以下是每个类型文件及其简要的说明。

  • WXML:是WeiXin Markup Language的缩写,它是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。我们所需要的界面设计,添加按钮、文字等显示的信息都可以通过这个文件来进行配置。下图中圆形以及矩形所标注的位置就是代码及其显示效果。

 

图 26 WXML界面配置
  • WXSS:WXSS(WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。它可以用来决定 WXML 的组件应该怎么显示。主要可以定义按钮颜色、形状、文字大小、颜色等。
  • JS:即JavaScript脚本语言,主要完成与用户交互的动作:响应用户的点击、获取用户的位置等等。在小程序里边,我们就通过编写 JS 脚本文件来处理用户的操作。

本设计中,微信小程序界面的开发其实按照本设计的要求只需要有两个按钮即可,也就是“打开”和“关闭”的按钮,分别来控制台灯的开关,因此我们需要修改wxml文件来显示两个按钮,再通过修改JS文件来添加按钮的功能。小程序界面显示如图27所示。

 

图 27小程序界面

在此由于一开始的意愿是创建两个圆形的按钮,但是查阅好多资料都没能够实现将按钮中的文字居中的设置,所以看到本篇文章的朋友如果有知道如何配置的希望可以抬一手。关于圆形图标ON目前的配置如图28所示:

 

图 28圆形button配置

 

界面设计完成以后,我们需要实现的方法设计。本设计中微信小程序连接mqtt服务器的思路是小程序通过websocket长连接的方式与后台服务器保持通信状态,后端程序中接收到小程序下发的指令以后再进行发布消息给Esp8266模块,从而实现小程序控制wifi模块的目的。

由于小程序中处于安全的考虑,所以对于访问的链接方式主要有wss以及https协议,因此,我们在小程序连接功能测试之前,需要为我们的云服务器申请一个域名及证书,并且通过代理的方式使服务器能够支持https协议和wss协议的访问。

阿里云服务器配置

阿里云服务器的配置主要包含域名配置以及服务器环境的搭建,比如为了使用https协议,我们需要安装nginx代理服务器,并且通过nginx的配置来实现http转https,接下来将一一详细介绍。

域名&&证书

域名的申请比较简单,登陆阿里云的域名网站之后,输入你想要的域名,如果该域名已经被注册,则需要花费时间以及额外的金钱来购买,当然我们也可以换一个域名申请。选定域名之后,接下来就是下订单租用域名。

 

图 29域名申请

域名申请完成以后,为了网站的安全,我们需要为域名购买SSL(Secure Sockets Layer 安全套接层)证书。我们可以在云盾控制台的页面中找到证书服务。如图30所示,在左侧的菜单中打开“云盾控制台概览”的页面之后,下拉就能找到一个“证书服务”的链接。

 

图 30证书申请

阿里云的证书中有一种类别是免费的证书,虽然只是保护一个域名,但个人使用已经足够,本设计中选择的就是这种。

 

图 31免费证书配置

证书购买以后,在证书控制台中点击申请后,按照要求,将申请到的域名与证书绑定然后提交审核,大概一天左右的时间,审核通过的证书就可以下载使用了。

 

图 32证书域名绑定

之后对于域名证书的配置需要使用nginx代理服务器。使用之前我们首先需要在阿里云服务器中安装nginx。同样我们可以先在本地下载好需要的nginx版本,通过winscp软件将其导入到阿里云服务器中。

安装nginx之前首先要确保服务器中已经安装jdk(Java Development Kit)、zlib、pcre(Perl Compatible Regular Expressions)以及openssl等库环境。其中JDK是 Java 语言的软件开发工具包,包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具;zlib是提供数据压缩用的函式库,可以通过zlib针对特定类型的数据进行优化;pcre是一个用C语言编写的正则表达式函数库;openssl是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信。如果上述文件都没有安装的话,可以通过以下的方式来进行安装。

安装JDK

JDK,由于JDK官网(https://www.oracle.com/technetwork/java/javase/downloads/ jdk8-downloads-2133151.html)中在下载JDK安装包时需要勾选一个许可证协议,如图33所示,所以不建议使用yum指令安装。因此,可以将文件下载到本地之后,再通过winscp软件上传到云服务器中进行解压安装。

 

图 33  JDK下载界面

压缩包上传到服务器之后,首先通过解压缩指令将压缩包解压缩。

tar –zxvf jdk-8u181-linux-x64.tar.gz

之后需要通过修改系统文件的方式使软件生效,首先需要通过vim指令来修改文件profile。

vim /etc/profile

打开文件以后,一直下滑到文件最底端,添加java的环境变量即可。

#java environment
export JAVA_HOME=/usr/java/jdk1.8.0_181
export CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
export PATH=$PATH:${JAVA_HOME}/bin

其中第二行对应的软件路径需要修改为解压缩后jdk文件夹所在的路径,之后保存退出即可,修改后的profile文件如图34所示。

 

图 34 java环境变量配置

接下来就需要将修改的系统文件执行使其生效,然后就可以通过java指令来查看版本信息了,具体操作指令如下。

source /etc/profile
java -version

 

图 35 Java版本信息查看

安装zlib、pcre、openssl

安装zlib以及pcre库的时候操作基本一致,都是将对应的压缩文件解压后,然后进入文件夹进行编译和安装操作,具体实现指令如下。

zlib

tar –zxvf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure && make && make install

pcre

tar –zxvf pcre-8.42.tar.gz
cd pcre-8.42
./configure && make && make install

openssl

openssl的安装相对更简单,同样也可以如同安装pcre以及zlib的方式进行安装,但对于环境变量的配置相对比较麻烦,所以本服务器中直接使用的yum安装,指令如下所示。

yum install openssl openssl-devel

之后会有提示询问是否下载安装包,输入“y”表示同意后,文件便开始下载并自行安装。安装完毕后可以通过openssl指令查看版本信息,注意该指令不需要加横线“-”。

openssl version

 

图 36 openssl版本信息

安装配置Nginx

同样需要先到官网(http://nginx.org/download/)下载一个nginx版本,然后通过winscp软件上传服务器之后,接下来解压、连接openssl然后编译安装,具体指令如下。

tar –zxvf nginx-1.15.5.tar.gz
cd nginx-1.15.5
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make&&make install

上述指令中,已经实现了nginx的安装,接下来我们需要对nginx进行相关配置,使其可以支持https以及wss的服务。首先我们需要进入nginx的conf文件夹,该文件夹下包含有nginx的系统配置文件,可以通过修改这个文件的设置来达到开启ssl服务的目的。编辑conf文件我们通过以下指令来实现。

cd /usr/local/nginx/conf
vim nginx.conf

上面两条指令我们就打开了nginx的配置文件,在nginx.conf文件中找到如下的代码段。

    #server {

    #    listen       443 ssl;

    #    server_name  localhost;

    #    ssl_certificate      cert.pem;

    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;

    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;

    #    ssl_prefer_server_ciphers  on;

    #    location / {

    #        root   html;

    #        index  index.html index.htm;

    #    }

    #}

以上文段是nginx默认自带的开启https服务的配置,我们将注释去掉,即删除前面的“#”,并且将server_name后面的localhost改成自己的域名,接下来两行的cert.pem以及cert.key替换成自己证书的路径名称,这样保存就完成了http转成https的配置。

另外,由于我们需要与微信小程序端通过websocket协议进行通信,同样需要在该文件中进行配置。具体添加的代码内容如下所示。

    map $http_upgrade $connection_upgrade {

    default upgrade;

    ''   close;

    }

    upstream websocket {

    #ip_hash;

    server localhost:8010;

    server localhost:8011;

    }

    server {

          listen 8020;

          location / {

               root html;

               index index.html index.htm;

          proxy_pass http://websocket;

          proxy_read_timeout 600s;

          proxy_set_header Host $host;

          proxy_set_header X-Real-IP $remote_addr;

          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

          proxy_http_version 1.1;

          proxy_set_header Upgrade $http_upgrade;

          proxy_set_header Connection $connection_upgrade;

           }

上面关于websocket以及https的配置保存以后,nginx的配置文件如图37所示。

 

图 37 Nginx.conf文件配置

接下来需要测试一下nginx的配置文件是否正确,我们需要先进入到nginx可执行文件所在的文件夹内直接调用nginx来测试配置文件。

 

cd /usr/local/nginx/sbin
./nginx –t

如果出现图38中的提示,则表明nginx.conf文件已经配置正确,接下来我们直接输入指令启动nginx。

./nginx

如果不太确定已经运行nginx,可以使用以下指令来查看当前的进程中是否有nginx的任务。

netstat -nptl

 

图 39当前运行线程

如果出现上图所示的线程,则表示nginx已经启动,我们可以看到第三列对应的几个端口号也是我们在conf文件中配置过的。但是我们在尝试登陆我们的域名网站之前,需要对自己的域名进行DNS解析处理,否则登陆还是不会成功的。这个解析当时由于没做,导致我反复检查配置文件,浪费了很多时间。

 

图 40域名解析

域名解析之后,在浏览器中输入自己的域名网址,如果出现图40所示情况,则表示我们的https配置已经成功。其实这个欢迎页面就是nginx.conf文件中location所设定的index.html文件。

 

图 41域名配置成功

安装Node

关于websocket的测试,我们需要借助wscat软件。如果系统内没有安装该软件,我们首先需要完成node的安装(安装node之前需要安装g++),具体指令如下。

wget http://nodejs.org/dist/v0.10.24/node-v0.10.24.tar.gz 
tar xf  node-v0.10.24.tar.gz                             
cd node-v0.10.24/                                            
./configure --prefix=/usr/local/node_modules
make&&make install
vim /etc/profile

然后编辑系统内环境变量的配置文件,配置node的环境,即在文件的最底部添加如下语句:

#set for nodejs

export NODE_HOME=/usr/local/node_modules

export PATH=$NODE_HOME/bin:$PATH

之后使用source命令让配置好的node的环境变量生效。使用node指令查看版本信息后则出现下图所示的消息。

source /etc/profile
node -v

 

图 42 Nodejs版本查看

wscat

nodejs环境配置完成之后,我们就可以使用js的npm安装指令来实现wscat的安装,根据wscat官方说明,wscat安装时需要全局使能。因此需要输入如下指令:

npm install wscat –g

然后进入到wscat的可执行文件目录下,输入wscat的测试指令就可以实现对我们的服务器进行websocket的测试了。测试结果如图43所示

./wscat –connect ws://127.0.0.1:8010
./wscat –connect wss://域名

 

图 43 wscat测试

使用wss协议来进行域名的通信测试是因为我们在nginx的配置文件中给域名添加了ssl证书,因此其访问方式也由原来的ws协议升级为wss协议。接下来我们需要通过微信小程序端对网站进行websocket访问,从而实现微信小程序端与服务器的通信。

微信小程序websocket连接服务器

微信小程序端的设计思路相对简单一些,就是在点击按钮的时候,可以向服务器端发送一个消息,而其通信方式则是通过websocket协议来进行连接。WebSocket 连接允许客户端和服务器之间进行全双工通信,以便任一方都可以通过建立的连接将数据推送到另一端。因此,WebSocket 只需要建立一次连接,就可以一直保持连接状态,这也就是所谓的长连接。这相比于http的轮询方式,效率有显著的提高。

在微信小程序开发者工具中,微信小程序也提供了关于websocket的api可以直接调用。目前设计中需要使用的就是建立websocket连接、发送数据、接收数据、关闭websocket连接等,分别对应的api接口为wx.connectSocket、wx.sendSocketMessage、wx.onSocketMessage、wx.onSocketClose。

本设计中,我们让小程序在启动的时候就自动建立websocket连接,然后在“打开”、“关闭”按钮被点击的时候分别发送不同的消息。当然在建立websocket连接的过程中,如果连接没有建立成功,就调取函数关闭websocket。具体代码实现如下所示:

  • 程序启动后建立websocket连接并且判定建立情况
onLoad: function (options) {

    wx.connectSocket({

      url: 'wss://备案后的域名'

    })

    wx.onSocketOpen(function (res) {

      console.log('WebSocket连接已打开!')

    wx.onSocketMessage(function (res) {

      console.log('from server!')

      console.log(res)

    })

    wx.onSocketClose(function (res) {

      console.log(res)

      console.log('WebSocket连接已关闭!')

    })

  },

其中建立websocket连接时,api中的url需要是已经备案过的域名,否则将会显示连接不成功。备案的话可以到所在云服务器的备案系统中进行域名备案,由于中间需要拍照采集信息等,所以一般审核时间大概在20天左右。当然微信开发者工具中还提供了一个比较方便的调试通道,即在项目工程的详情设置里面勾选不校验域名的选项,如图44所示。这样就可以在域名还没有完成备案之前使用开发者工具中进行调试,但正式上线运营的话必须使用备案后的域名。

 

图 44域名不校验配置
  • 点击打开台灯时的函数操作
  CliButton_lighton: function () 
  {

    wx.sendSocketMessage
    ({

      data: 'This is the command On!',

    })

    this.setData({ SwitchOn: "台灯已打开" })

    this.setData({ SwitchOff: "关闭台灯" })

  },
  • 点击关闭台灯时的操作
  CliButton2_Lightoff: function () 
  {

    wx.sendSocketMessage
    ({

      data: 'This is the command Off!',

    })

    this.setData({ SwitchOn: "打开台灯" })

    this.setData({ SwitchOff: "台灯已关闭" })

  }

以上两段代码分别是打开与关闭按钮的响应函数,相对应与打开和关闭按钮,小程序端分别发送不同的消息内容,这样服务器上的websocket后端程序就可以根据消息内容进行不同的操作。

后台服务器端使用js脚本语言开发,在建立websocket连接之后,后台程序就开始监听小程序的websocket消息并且做出不同的响应。服务器端程序代码如下。

  console.log("Server started");

  wss.on('connection', function(ws) 
  {

       ws.on('message', function(message) 
       {

           console.log('Received from client: %s', message);

           ws.send('Server received from client: ' + message);

       });

   });

Websocket服务端连接Esp8266

本设计中websocket的后端程序需要在收到小程序下发的websocket消息之后,根据消息内容向esp8266模块发布不同的mqtt指令。因此我们的websocket后台服务端还需要能够实现mqtt协议的通信,即可以自如发布或者订阅消息。

在使用mqtt之前,我们首先需要为nodejs环境安装mqtt的相关库,否则在程序调用mqtt时将会返回mqtt没有定义的报错。安装mqtt的操作指令如下:

npm install mqtt -g

然后我们就可以创建一个新的mqtt客户端,前文也已经介绍过,由于我们的阿里云服务器中安装了EMQ的mqtt服务器,因此所有与这个服务其相连的mqtt客户端之间均可以实现通信。因此我们在js的程序中同样见了一个mqtt客户端,使其能够连接到我们的EMQ服务器。然后在根据接收到的小程序端下发的websocket消息内容,决定发布不同主题的mqtt消息。我们将websocket的后台程序与mqtt的响应程序整合到一块,具体代码如下所示:

console.log("Server started");

var Msg = '';

var WebSocketServer = require('ws').Server

  , wss = new WebSocketServer({port: 8010});

  wss.on('connection', function(ws) {

    ws.on('message', function(message) {

    console.log('Received from client: %s', message);

    var mqtt = require('mqtt');

         var client = mqtt.connect('mqtt://域名:1883');

         var num = 0;

         var qtt = {};

         qtt.aa = 'hello';

         qtt.bb = 'shut down please!';

          

         if(message == 'This is the command On!')

         {

                   client.publish('/Lighton/',JSON.stringify(qtt),{qos:1,retain:true});//hello mqtt + num++

         }

         else if (message == 'This is the command Off!')

         {

                   client.publish('/Shutdown/',JSON.stringify(qtt),{qos:1,retain:true});//hello mqtt + num++

         }

    console.log('I have published a message');

    ws.send('Server received from client: ' + message);

  });

 });

当微信小程序按动“关闭台灯”时,将会通过websocket协议向服务器发送“This is the command On”的指令;后端接收到这个消息内容后进行判定,进而通过mqtt协议发布了一个主题为“'/Lighton/”的消息;接下来,esp8266在订阅“'/Lighton/”主题的前提下,收到开灯的消息,然后通过控制wifi模块中的gpio管脚来打开台灯。最终的成果如下图所示。

图 45远程控制台灯成果图

以上就是物联网台灯的所有设计操作流程,目前只有控制按钮,还没有添加账号登录的功能。通过这个远程控制台灯的设计实现,从中学习了服务器、websocket、mqtt、JS语言以及Python语言的使用。虽然最终没有选用Python编写websocket的后台,但在测试过程中一直使用Python程序进行调试。以前看到小米的远程台灯总感觉很简单的事情,甚至在做目前这个设计的过程中也一直感觉逻辑很简单,但在实现的过程中处处是坑。虽然网上有很多教程,但实际上都有些许的漏洞以及不通用性,在此仍然向各位留下宝贵经验的前辈致以衷心的谢意。由于翻阅的内容太多,在此不一一列举,文末参考文献中会将所有的文档整理归类并且将所有的源码一一附上。

参考文献

小程序

微信小程序官网:https://mp.weixin.qq.com/

小程序教程:https://blog.csdn.net/g8433373/article/details/80722001

小程序例子:https://www.zhihu.com/question/50907897

物联网小程序例子:https://blog.csdn.net/FanMLei/article/details/78824170

小程序例子:https://blog.csdn.net/li420248878/article/details/79120604

小程序后台

Emqtt客户端:https://blog.csdn.net/z1012178837/article/details/82121378

Emqtt客户端:https://blog.csdn.net/itas109/article/details/78873257

websocket客户端:https://blog.csdn.net/leytton/article/details/51896951

websocket例子:https://www.cnblogs.com/lichmama/p/3931212.html

云服务器配置

Nginx安装:https://blog.csdn.net/cxm19881208/article/details/62047392

Http配置:https://blog.csdn.net/cslucifer/article/details/79077831

Openssl安装:https://blog.csdn.net/uniom/article/details/54092570

Openssl安装:https://blog.csdn.net/ikownyou/article/details/53021686

Openssl安装:https://blog.csdn.net/ikownyou/article/details/53021686

JDK安装:https://www.cnblogs.com/sxdcgaq8080/p/7492426.html

Linux指令:http://www.cnblogs.com/sxdcgaq8080/p/7470796.html

Python安装:https://www.linuxidc.com/Linux/2016-04/129784.htm

Nginx安装:https://blog.csdn.net/tunrijituan/article/details/62249344

Nginx错误解决:https://blog.csdn.net/fuckomg/article/details/68952753

Nginx教程:https://www.yiibai.com/nginx/beginners_guide.html

Nginx配置:https://www.jb51.net/article/145390.htm

Esp8266相关

远程台灯例子:https://blog.csdn.net/xh870189248/article/details/78867173

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

物联网(Iot)台灯设计完整教程(长图文) 的相关文章

  • conda:离线环境安装

    Aanconda的离线环境安装的必要条件是有一台可以联网的电脑 在后文中 xff0c 分别称可以联网的电脑为On line xff0c 不可以联网的电脑为Off line 以下即为对应的操作步骤 1 On line 下载annconda安装
  • Ubuntu:pip install gdal

    方法 sudo apt get update 必须首先安装gdal的lib xff0c python只是针对该lib的调用 sudo apt install gdal bin libgdal dev pip安装的版本必须和gdal一致 pi
  • Git:使用笔记

    git局部配置 git config user name 34 username 34 git config user email 34 email 34 git带用户密码clone git clone https username pas
  • Pytorch:conda安装不同版本的cuda

    我不会是最后一个知道可以用conda安装不同版本的cuda的人吧 通常的pytorch安装流程是 xff1a 首先安装NVIDIA驱动 xff0c 然后安装对应版本的cuda和cudnn最后再安装cuda支持的pytorch版本 然而实际上
  • obsidian使用技巧

    背景 obsidian是一个非常牛逼的本地笔记工具 xff0c 极大的提高了本人的学习能力 xff0c 卷的更加厉害了 此处简要记录一下在使用过程中遇到问题和对应的解决方案 xff0c 至于具体的使用方法网上多的是就不介绍了 三方插件推荐
  • ubuntu:命令行查询文件(夹)大小

    背景 使用命令行查询文件文件 夹 大小 参考 https www cnblogs com zhengyiqun1992 p 11183819 html 使用方法 查看当前文件夹下文件大小 ll h 输出如下 xff0c 其中文件夹大小是错误
  • VSCode:remote-ssh多级跳转

    背景 vscode目前是非常流行的编程工具 xff0c 提供了大量的插件 xff0c 尤其是其中的remote ssh xff0c 能够提供远程ssh连接服务器 xff0c 居家办公两不误 然而比较麻烦的事情是 xff0c 通常服务器为了保
  • Jittor:Jittor1.3.1之离线安装

    背景 Jittor是一个非常牛逼的框架 xff0c 维护了大量的官方demo xff0c 非常容易上手 与其他方法相比 xff0c 采用了即时编译的流程 xff0c 因此在效率上往往更高 但是在使用Jittor的过程中 xff0c 也遇到了
  • 灵活的按键处理程序 FlexibleButton,C程序编写,无缝兼容任意的处理器,支持任意 OS 和 non-OS

    灵活的按键处理程序 FlexibleButton 前言概述获取测试DEMO 程序说明程序入口用户初始化代码事件处理代码 FlexibleButton 代码说明按键事件定义按键注册接口按键事件读取接口按键扫描接口 问题和建议 前言 正好工作中
  • http请求头header、请求体body、请求行介绍

    HttpServletRequest对象代表客户端的请求 当客户端通过http协议请求访问 服务器的时候 http请求头的所有信息都封装在这个对象中 xff0c 通过这个对象 xff0c 可以获取客户端请求的所有信息 http请求包含请求行
  • 理解字节序 大端字节序和小端字节序

    以下内容参考了 http www ruanyifeng com blog 2016 11 byte order html https blog csdn net yishengzhiai005 article details 3967252
  • opencvSharp 学习笔记(二)

    参考文章 xff1a https github com shimat opencvsharp samples tree master SamplesCS Samples 参考opencvsharp的官方sample xff0c 在vs201
  • C++局部对象的析构

    class A span class hljs keyword public span A Func span class hljs attribute span span class hljs attribute span A A spa
  • BIND中基数树的建立

    BIND9新引入了视图的概念 xff0c 简单的来讲就是能根据不同的来源IP来返回不同的数据 其中网段的存储 xff0c 网段的快速匹配都是用基数树来实现的 下面是BIND创建基数树的代码 BIND的IP地址结构 span class hl
  • HTTP协议解析及C/C++代码实现

    超文本传输协议 HTTP 是分布式 协作 超媒体信息系统的应用层协议 这是自 1990 年以来万维网数据通信的基础 HTTP 是一种通用且无状态的协议 xff0c 它可以用于其他目的 xff0c 也可以使用其请求方法 错误代码和标头的扩展
  • C语言发邮件(带账号密码认证),简单的libesmtp实例

    需要安装libesmtp开发环境 xff0c centos下可以用yum安装 yum install libesmtp devel 编译时加上 lesmtp选项 xff0c 账号密码等替换成自己的 gcc o mail mail c les
  • 怎样在Markdown中贴图片

    前言 Markdown真的是一个很优秀的文本标记语言 语法也很简单 熟悉之后基本上可以完全抛弃Word了 用来写文档 一些博客 再好不过了 可是Markdown还是有一个痛点 那就是不大好贴图片 贴图 怎么样在markdown中贴图就不多说
  • 【四】【vlc-android】播放控制交互与demux解复用层、媒体数据流拉取层的具体数据传递和控制流程源码分析

    1 VLC中有很多demux mux encoder decoder模块 xff0c 因此需要先了解这些模块的加载原理 xff0c 模块的加载原理基本一致 xff0c 因此举例分析MP4解复用模块如何加载完成的 xff0c 主要流程如下 x
  • vs2013 设置不显示输出窗口

    工具 选项 项目与解决方案 常规 取消 在生成开始时显示输出窗口 的勾选
  • @Param注解的用法解析

    实例一 64 Param注解单一属性 dao层示例 Public User selectUser 64 param userName String name 64 param userpassword String password xml

随机推荐

  • mybatis choose标签的使用

    有时候我们并不想应用所有的条件 xff0c 而只是想从多个选项中选择一个 而使用if标签时 xff0c 只要test中的表达式为 true xff0c 就会执行 if 标签中的条件 MyBatis 提供了 choose 元素 if标签是与
  • Socket长连接实现思路

    长连接的正确实现方式 1 不关闭流实现长连接 xff1f 流关闭了而不关闭Socket xff0c 还是无法达到长连接的效果的 xff0c 所以 xff0c 要长连接 xff0c 流必须不能关闭 xff01 那么 xff0c 是不是直接不关
  • com.jacob.com.ComFailException: VariantChangeType failed

    调用jacob组件出错 com jacob com ComFailException VariantChangeType failed 在C Windows System32 config systemprofile下创建文件夹Deskto
  • CRC8校验 java实现

    以下为CRC8的实现 span class hljs keyword package span server span class hljs javadoc CRC8相关计算 encode utf 8 span class hljs jav
  • Java list add方法和addAll方法效率

    结论是 在数据量较小时 add方法配合for循环遍历比addAll来得快 但是在大量数据时 addAll的方法的效率更高 list addAll 是浅拷贝 只是将内存中的地址进行了拷贝 指向了原先list的末尾做了拼接
  • STM32——USART1重映射

    前言 为了使不同器件封装的外设 IO 功能数量达到最优 xff0c 可以把一些复用功能重新映射到其他一些引脚上 STM32 中有很多内置外设的输入输出引脚都具有重映射 remap 的功能 我们知道每个内置外设都有若干个输入输出引脚 xff0
  • Pg数据库比较时间大小

    postgresql 比较两个时间差大于 N个小时 摘要 PG 中时间想减后为interval xff0c 比较两个时间大于某个小时或者分钟等可以直接通过interval来实现 example1 xff1a 判断两个时间差大于4个小时 se
  • import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; import java.util.Stac

    span class hljs keyword import span java util LinkedList span class hljs keyword import span java util Queue span class
  • 21-《电子入门趣谈》第四章_自己制作电路板-4.2洞洞板的介绍和经典案例使用教程

    好消息 xff1a 请在手机淘宝或闲鱼上搜索 电子入门趣谈 xff0c 有惊喜哦 我把全本电子入门趣谈的电子版 xff08 包括科技提升和理论升华部分 xff0c 共计50余万字 xff09 放到上面开始兜售啦 xff0c 如果您真的喜欢这
  • vlc-添加自定义的demuxer解复用插件----播放h264裸文件

    使用vlc3 0 6 在ubuntu 64bit上编译 xff0c vlc使用插件的方式组织对多种视频源的支持 xff0c 比如 avi mp4 mkv 等等 xff0c 这里想添加一个自己的demuxer xff0c 从一个h 264文件
  • 进程管理(五)--linux进程内核栈

    在进程创建时 xff0c 内核会为进程创建一系列数据结构 xff0c 其中最重要的就是上章学习的task struct结构 xff0c 它就是进程描述符 xff0c 表明进程在生命周期内的所有特征 同时 xff0c 内核为进程创建两个栈 x
  • [802.11]IEEE 802.11认证方式介绍

    一 802 11认证方式 802 11有开放系统认证 xff08 open system authentication xff09 和共享密钥认证 xff08 shared keyauthentication xff09 两种方式 1 1
  • 对‘std::xxx’未定义的引用

    出现一大串 对 std xxx 未定义的引用 的原因 xff1a 对于gcc后缀文件 xff0c 编译的时候可以用gcc g 43 43 xff0c 但是链接的时候要用g 43 43 xff0c 因为gcc和g 43 43 在编译的时候是相
  • 快速傅里叶变换

    FFT xff0c 即为快速傅氏变换 xff0c 是离散傅氏变换的快速算法 xff0c 它是根据离散傅氏变换的奇 偶 虚 实等特性 xff0c 对离散傅立叶变换的算法进行改进获得的 它对傅氏变换的理论并没有新的发现 xff0c 但是对于在计
  • C++项目开发中的一些问题及解决记录

    1 std vector类使用 xff1a https blog csdn net weixin 41743247 article details 90635931 2 vector求和 xff1a include lt numeric g
  • win32和android 的cocos2dx环境搭建详细教程

    转载 请注明出处 xff1a http blog csdn net aa4790139 article details 8086635 详细搭建步骤如下 xff1a 1 Android 开发环境搭建 Android开发环境搭建不是重点 相信
  • 快速傅里叶变换在信号处理中的应用

    傅里叶变换FT xff08 Fourier Transform xff09 是一种将信号从时域变换到频域的变换形式 它在声学 信号处理等领域有广泛的应用 计算机处理信号的要求是 xff1a 在时域和频域都应该是离散的 xff0c 而且都应该
  • 卷积

    随着机器学习的逐渐升温 xff0c 卷积神经网络这个专业词汇也越来越多地出现在我们眼前 卷积神经网络是一种前馈神经网络 xff0c 包括一维 二维以及三维卷积神经网络 这篇文章我们先来学习了解一下卷积的概念 在泛函分析中 xff0c 卷积是
  • 二叉树基础知识总结

    现实生活当中 xff0c 我们每个家庭都会有一个家谱 xff0c 来罗列家庭成员的关系 例如父亲下面的分支里有儿子或者女儿 xff0c 而父亲又属于祖父祖母的下部分支 其实这个家谱在计算机科学中映射的就是树形的表示方法 可见在很久以前 xf
  • 物联网(Iot)台灯设计完整教程(长图文)

    现如今随着物联网的概念深入人心 xff0c 物联网的设备也越来越普及 xff0c 本篇文章介绍的就是一个物联网台灯的设计 该设计主要包含物联网芯片开发 微信客户端开发 后台服务器端开发以及三个组件之间互联等 xff0c 其总体设计逻辑框图如