zhangguanzhang's Blog

分享下自己做的外网控制硬件

字数统计: 740阅读时长: 2 min
2017/04/17

教程+源码+固件

废话不多说开始

准备东西:
一块单片机开发板(我用的原子的stm32的mini板子)
一块esp-12F(esp-12E,esp-12S均可)
一台云主机(没有也可以用虚拟机来玩局域网控制)
单片机只需要消耗一个串口和一个定时器
先搭建环境
硬件连接服务器一般是socket,tcp,udp,mqtt,websocket之类的
物联网里用得较多的是mqtt,这里我用的是mqtt,服务器端我用的emq,一个mqtt的server端
tcp和udp缺点就不说了,看到很多esp群里怕丢包一个数据发十几次的都有
而mqtt可以说是改良的tcp,mqtt基于主题和消息内容来通讯,客户端订阅主题,有人推送一个主题,只有订阅了这个主题的人才能收到消息
ssh软件连接自己的云主机进入交互式shell界面(怎么连云主机自己摸索)
我的主机是64位centos6.9,ssh软件我用的xshell(xshell老版本被曝被人恶意植入后门,已经安装过的赶紧升级吧)

[root@localhost ~]# yum install -y unzip gcc gcc++ wget &>/dev/null
[root@localhost ~]# wget http://emqtt.com/downloads/2206/centos6 -O emqttd-centos6.8-v2.2.0.zip
http://emqtt.com/downloads/2070/centos6
[root@localhost ~]# unzip emqttd-centos6.8-v2.2.0.zip
[root@localhost ~]# emqttd/bin/emqttd start
emqttd 2.2 is started successfully!

然后输入你的ip加端口:18083进入emq的后台
用户admin密码public
进不去的话看看防火墙加了规则没,没加就加上,不过现在云主机都是安全组规则来控制,云主机的防火墙可以不用开,一般去登陆云主机供应商的网站的控制面板那里改下安全组的规则加端口号允许就行了,用到的端口有18083 8083 8084 1883
进去web后台会有登陆的窗口,默认用户名是admin密码public
登陆进去自行改密码
然后再plugins插件里把这个emq_auth_username给开启了,不然任何人使用mqtt协议都能连接你的server端
t1
然后在emq里增加用户名为test密码为test123456 (随意填写你开心就好)

[root@guan ~]# emqttd/bin/emqttd_ctl users add test test123
ok

然后进web后台的websocket(网页的mqtt客户端,方便调试啥的)输入你添加的用户名和密码点击connect
然后下面的subscribe订阅输入一个主题消息名字点击subscribe
t2
图里我输入的是hello
emq的官方文档里写着推送消息有http接口
在服务器上我们测试下推送一个hello主题,消息内容是ON的消息
t3

[root@localhost ~]# curl -v --basic -u test:test123456 -d "qos=2&retain=0&topic=hello&message=ON" -k http://localhost:8083/mqtt/publish
(输出信息省略)
t4 后台面板可以看到收到了一条消息为ON的 可以看到环境OK ---写个shell来接收主题名字和消息内容方便不用每次来输入一大串的curl
[root@localhost ~]# cat>/usr/bin/publish<<'EOF'
#/bin/bash
curl --basic -u test:test123456 -d 'qos=2&retain=0&topic='"$1"'&message='"$2" -k http://localhost:8083/mqtt/publish
EOF
[root@localhost ~]# chmod 755 /usr/bin/publish

测试下看看能不能用
t5
目前服务器端弄好了暂时


然后是硬件esp-8266,我用的是esp-12系列,10块包邮岂不美哉?
t6
买的时候建议买个转接板方便接线
固件的源码工程我放在了github(readme写得很差,凑合着看吧)
https://github.com/zhangguanzhang/ESP8266_NONOS_SDK-mqtt-uart_set

从乐鑫官方的non_os的mqtt的demo修改,我用的是esp-12系列,12F和12S测试了都可以用
官方的自带的demo好像串口编译不通过,改了一些引用文件和增加了几个定义就能过了
然后定义了协议部分,听说官方的json有问题,全是走的字符串
具体信息可看github里的readme.md
下面是开发软件sdk链接,需要自己改的可以下载后导入我的工程来修改
链接:http://pan.baidu.com/s/1eSIIAdG 密码:vy55
—烧录固件
ESP8266_NONOS_SDK-mqtt-uart_set/bin/里的就是固件
下面是文件名对应的烧写地址
eagle.flash.bin——–>0x00000
eagle.irom0text.bin—->0x10000
上面俩文件是任何时候都必须烧录的,下面俩文件是刚拿到模块初始化必须烧录的
esp_init_data_default.bin—->0x3fc000
blank.bin—->0x3ff000
烧写软件链接:http://pan.baidu.com/s/1c1DgTwO 密码:z2dk
烧写的时候自己用串口电路或者usb转串口模块下载,我是直接接在原子mini板子上的串口电路下载的,GPIO0要拉低,然后点击start后reset引脚触碰下gnd就进入下载了
t7
接线是VCC,GND,RX,TX 另外俩根是一个GND-GPIO0,那根杜邦针式接GND上的
点击了start后杜邦针触碰下reset就下载了
下载过程图如图所示
t8
下载完后拔掉GPIO0的线,然后触碰下reset给个低电平重启下就行了,不拔掉GPIO的线的话不会进入工作模式并且会乱码
然后打开串口调试软件参数如图所示
初始的一些mqtt参数在app/include/mqtt_config.h里宏定义的
t9
我改写了官方固件,通过串口即可设置参数,具体设置协议在我github的readme下拉就能看到
先设置wifi和mqtt的用户名密码和hid和你mqtt的server端的ip和端口,主机有域名也可以直接用域名,wifi名字不能是中文
t10
设置好后发下show看看信息,无误后发送restart重启加载信息
t11
上面的是连接不上的打印,我才意识到我手机开的wifi热点后我手机没打开数据流量,连接上了就是红框部分的下面
然后源码里默认订阅的主题是receive,推送主题名字是send,服务器上推送下一个ON的信息,
打印部份我的代码是判断云端的id部分是不是和自身一样,一样就打印,模块硬件id我设置成testid的上图可以看到
str_cut是我自定的函数,在uart.c里根据传入字符来分割字符串
也就是按照等号分割出第二部分的id写进temp后判断和自身id一致不,不一致就不打印,一致就打印信息
t11
t12
由此可见硬件可以和服务器通信了


8266是一款由wifi能力的mcu,有兴趣和时间的可以自己去研究sdk开发,不过我是只把它当作wifi传送数据的
有串口的单片机拿个串口接8266的串口上就可以传输了
处理云端的数据思路是以下这样: 举例 1假如连接不上wifi就是STATION_IDLE多次串口打印 2心跳包(Send keepalive packet to字样)的打印 所有动作和状态都会从串口输出,内容里包含多个回车换行符,所以建议串口中断不要以回车换行判定接收完成 建议开启一个定时器 串口中断里使能定时器并且接受每一个字节的时候定时器数值清零,溢出了直接标记flag标志位为接收完成并失能定时器,听不懂我这段话的话看下面图 参考原子的代码
t13
然后是单片机部分的源码工程分享,写的很渣,就这样厉害的拿去扩展吧
链接:http://pan.baidu.com/s/1bppj7aB 密码:wkz2


顺带这样暂时处理的只是下发,写的那个publish可以用php调用外部命令来推送
服务器可以接入微信后根据消息type和正则匹配来推送消息给硬件就是微信控制硬件了(已测试过)
也可以自己写个页面然后ajax按钮发送调用那个publish推送就是网页控制硬件了


发下自己之前录制的视频
链接:http://pan.baidu.com/s/1slFf4rr 密码:ebfy

这样只是下发,如果你的硬件要上传的话,可以在服务器上跑一个客户端来订阅硬件端推送的send主题来把消息写到数据库里,至于消息格式啥的我是纯字符串上传的
然后客户端我用的是mosquitto-1.4.5,最后附上它的安装过程和参数使用

字符串处理入库我用的是shell,当初写的,等号分割每一部分,相当于自定义了个通信协议,代码里就是解析字符串后写入数据库
t14
t15
可以用其他语言来直接写个客户端处理或者erlang开发emq的插件
个人思路就是以上的,有疑问欢迎探讨
另外不用最新版的emq是发现开了那个username的插件后就连不上去了不知道怎么回事,还有官方的http接口看文档居然也推送不了,能解决的大佬可以分享下经验


最后是mosquitto安装 安装基本依赖
yum install cmake gcc-c++ openssl-devel  c-ares-devel

我下载的1.4.5,因为我是只用客户端来接收消息,没必要那么高

wget http://mosquitto.org/files/source/mosquitto-1.4.5.tar.gz
tar zxfv mosquitto-1.4.5.tar.gz
cd mosquitto-1.4.5
cmake .
make
make install
install

看下图里的输出就能看到mosquitto安装在哪了 相关配置文件在这个路径下/usr/local/etc/mosquitto/ 配置的是server端的,我只用客户端所以不用配置 如果你用server端的话 启动mosquitto并载入配置文件
cd /usr/local/etc/mosquitto/
mosquitto -c mosquitto.conf -d


推送和订阅的话使用mosquitto_pub和mosquitto_sub 只列出了一些参数,完整的话可以man下这俩命令看看手册就知道了 mosquitto_pub 命令参数说明 1. -d 打印debug信息
  1. -f 将指定文件的内容作为发送消息的内容

  2. -h 指定要连接的域名 默认为localhost

  3. -i 指定要给哪个clientId的用户发送消息

  4. -I 指定给哪个clientId前缀的用户发送消息

  5. -m 消息内容

  6. -n 发送一个空(null)消息

  7. -p 连接端口号

  8. -q 指定QoS的值(0,1,2)

  9. -t 指定topic

  10. -u 指定broker访问用户

  11. -P 指定broker访问密码

  12. -V 指定MQTT协议版本

  13. –will-payload 指定一个消息,该消息当客户端与broker意外断开连接时发出。该参数需要与–will-topic一起使用

  14. –will-qos Will的QoS值。该参数需要与–will-topic一起使用

  15. –will-retain 指定Will消息被当做一个retain消息(即消息被广播后,该消息被保留起来)。该参数需要与–will-topic一起使用

  16. –will-topic 用户发送Will消息的topic
    消除一个retain为0的话mosquitto_pub -r -q 1 -t topicname -m ‘’
    上面是俩单引号,不知道为啥被转换成反引号了


    mosquitto_sub 命令参数说明
  17. -a 将出站连接绑定到本地ip地址/主机名。 如果你使用这个参数,需要限制网络通信到特定接口。

  18. -c 设定‘clean session’为无效状态,这样一直保持订阅状态,即便是已经失去连接,如果再次连接仍旧能够接收的断开期间发送的消息。

  19. -C 在给定的消息计数之后立即断开并退出程序,这在单个状态值为的shell脚本中可能很有用

  20. -d 打印debug信息

  21. -h 指定要连接的域名 默认为localhost

  22. -i 指定clientId

  23. -I 指定clientId前缀

  24. -k keepalive 每隔一段时间,发PING消息通知broker,仍处于连接状态。 默认为60秒。

  25. -p 连接端口,来替代默认的1803

  26. -P 连接时指定用户名,与-u一起使用,用于要链接的server端开启了用户名和密码验证

  27. -q 指定希望接收到QoS为什么的消息 默认QoS为0

  28. -R 不显示陈旧的消息

  29. -t 订阅topic

  30. -u 连接时用户名

  31. -v 打印消息

  32. –will-payload 指定一个消息,该消息当客户端与broker意外断开连接时发出。该参数需要与–will-topic一起使用

  33. –will-qos Will的QoS值。该参数需要与–will-topic一起使用

  34. –will-retain 指定Will消息被当做一个retain消息(即消息被广播后,该消息被保留起来)。该参数需要与–will-topic一起使用

  35. –will-topic 用户发送Will消息的topic

CATALOG
  1. 1. 废话不多说开始