stm32连接服务器端
' L. y' s, t) J本章所用到的器件如下:5 C* }) u( f# V
STM32F103ZET6最小系统板
2 p: c4 B; u6 n, S7 Q, Z: vESP8266-01S模块; s; W. s6 C* d- I' I
USB转microUSB数据线
9 Z% c7 z0 w0 {: u- G四根杜邦线* I" D0 \/ Z6 y1 f
连接如下:
0 M$ M8 _$ @' ~' Y32板3.3v----------->ESP8266的3.3v
: W" \8 E8 z7 Q3 A' w% F8 ^32板GND---------->ESP8266的GND
% K* E1 v. X) D" T2 f7 C, A32板的PC10-------->ESP8266的RX
5 K- o4 g2 l/ K* J u( f2 l32板的PC11-------->ESP8266的TX6 V) f# V& h% g" E# w1 U
# \( L. P6 _! A. a- q
在这里说明一下,由于本项目是用在其他项目上的,所以在编写此项目时,是基于另一个项目还未被使用到的串口资源进行设计的,所以我这里用了串口4。各位需根据自己硬件已有的串口资源,自行手动修改串口4初始化的函数。$ o$ c" e F7 l* m& m9 H! a8 O
0 E" @. b! Z8 l* ~( N4 w! i) B2 A7 e
本项目程序是参考onenet平台上的源码进行二次开发的,onenet平台上源码的位置如下:进入onenet官网后,登录账号,在上方有一个社区->论坛,里面就有源码,点进去后就有一个链接是百度网盘的,这里我用的是OneNET标准板中的裸机基础教程->EDP例程。
$ \9 s. g- N" C( _( G Y; ]2 ~
: P$ n3 _- n0 ^" I$ c/ J: c( }4 m+ j9 x
: V! O, \/ ?- r, N/ j; } t4 |2 B
+ |* I6 v9 d* F( C! O: I! \
$ d+ `; c8 n, }8 Q b& I L9 I* p
5 D5 j2 E3 Q6 V$ F4 g* ~7 g
既然用到了MQTT协议,少不了要用到cJSON格式的一个文件,将cJSON.c和cJSON.h文件导入到stm32程序所在的文件夹下,接着在程序中onenet.c文件里面包含头文件cJSON.h,方便我们下面对接收到的cJSON格式的数据进行解析。
5 c* N: |# J$ p* x# E ~1 T( c$ _% I5 x2 y' U! \
' f# D" V1 w1 l( U7 G& o% V m$ U; V8 R+ W! P, G, Z+ D F
接下来,我们需要修改的是esp8266.c文件中的ESP8266_WIFI_INFO及ESP8266_ONENET_INFO,他们分别表示的是ESP8266需要连接的WIFI及服务器地址(修改成自己的WIFI名称、密码和服务器地址、端口号),本项目中给出了五个MQTT服务器地址,其中EMQX服务器是公有服务器,可以直接连接,至于其他三个服务器是自己在其他平台创建的私有服务器,需要用到onenet.c文件中的设备ID和密码。EMQX服务器连接的时候不需要用到设备ID和密码,所以设备ID和密码可以随便写。 1 K! d( W4 J" f1 ^4 a/ Z8 Z
4 j" J7 C# y2 a& f5 E: [9 y3 f
1 t. C2 S( D( P `4 W. I
& j# n9 P, y1 f2 ~3 e5 q+ s- @2 {
7 d9 f. u: Z7 ~: m* r# N: \! m: {& h
最后,需要设置一下主题的发布和订阅,对于公有服务器来说,是没有主题前缀的,而对于私有服务器来说,他有平台自带的主题前缀。 此项目中连接的是EMQX的服务器,是不需要主题前缀的,所以这里我随便写了一个发布主题和订阅主题(同时这两个主题也可用于我创建的私有服务器的设备相对应的主题)。& k8 d: J; A( T3 [& y
" _ D4 C$ R4 M: s" Q
# V' Y( k* b) Z& y% G1 T
6 H) f" x' m9 c3 v% g$ ~ 至此,stm32部分的程序已经搞好了,接下来进行小程序部分的制作。
* M+ c2 e6 i! P* P3 M `
( g% _4 ~; d( i0 n2 W' p% s小程序连接服务器
: b: M( m- ?/ i. T 先上小程序的效果展示图9 g4 G7 E1 x4 O7 z. a* z; E4 D4 ]( N
+ _2 q$ s) _ f$ y' P. S9 h4 @ q
4 A/ [& P9 l% }+ f! i
此项目的小程序我没有用过任何框架,都是使用微信原生框架进行开发,其中首页涉及到天气数据的获取,这里请求的天气数据API接口采用的是和风天气开发平台上的Web API接口,其链接如下:和风天气开发平台
4 @. a% u# H1 O 要请求该平台上面的API接口,需要在该平台上登录账号,然后进入控制台,在上面创建一个应用(目的是获取到一个KEY),如下所示:; }) L( T0 {+ L8 ^' Q7 M+ S8 b+ {
$ ^; S6 g& G x c( ^- T
2 b$ n9 j# D: L8 e! u b; f2 [: U) C; N- B
接着到该平台的开发文档->天气数据Web API开发文档中去找对应的请求地址,上面清楚的写了该地址的格式及请求的参数等信息,下面是小程序端的获取天气数据的自定义函数:
. |% x5 T1 n+ X, s3 }6 D* U% ~+ N! b% v+ v
- weahterdata:function(){ k6 g/ O! j) t
- var that=this
- k# ~0 `4 B% `3 Q* ] - wx.getLocation({//获取位置(经纬度)API
6 @) {3 d5 W7 F2 W8 c) I - type: 'wgs84',! [- c, A d7 ]; o" r
- success (res) {
5 {. Z/ w0 ^9 _3 Z8 h - const latitude = res.latitude
! H7 l' `& J9 r: Q% A - const longitude = res.longitude
D; k0 ]4 e+ t$ A% L# u - const key="432a8840589546338cae4c5a825f47db"//和风天气开发平台上控制台创建的应用得到的KEY,只有得到这个,才能获取各种数据9 D5 I" f6 R+ Y
- wx.request({//网络请求API' |" @9 x- A: Q8 o# E& y4 ?* k, ~6 Z6 s
- //下面使用模板字符串
; r6 | T( |5 z - //获取天气数据的API接口地址
, [# h, Q/ D" s - url: `<a href="https://devapi.qweather.com/v7/weather/now?location=" target="_blank">https://devapi.qweather.com/v7/weather/now?location=</a>${longitude},${latitude}&key=${key}`,
; I1 Q; \$ q, M! ?5 D! E - success (res) {9 l( H# u; L8 J9 k8 I2 r
- const weather_data=res.data.now 1 E' V' Q1 B% o% }2 d
- const weather=weather_data.text //解构赋值* E* p8 [. G1 O8 R" @$ w
- that.setData({ q0 b& m* R& J7 U& S
- weather' o" M! X* q4 W& z
- })
+ R* D) Z* @; e5 k! u" G - }
/ K# {& M) F& ~3 U - }): E4 I/ `# z. l2 \
- wx.request({
# H4 ]* H, U4 w9 ~0 v+ F - //获取地点的API接口地址
+ A8 N5 f: r( H4 Q9 n; W - url: , 8 t& E6 m, ~! M3 H9 r- w: y& e7 B
- success (res) {
& {% _0 R* f d9 n - const location=res.data.location[0]
/ B! m" v: j, j - const {adm2, name}=location //解构赋值% @1 b3 |! y, [7 h6 k% I
- that.setData({, ?: {( j" g* I4 d6 C/ x
- city:adm2,
/ |0 D0 D* q4 M - area:name
0 l; j7 j; _! l" k* A( M1 z - })
- U8 s- P# Y* i - }! M( Z& ^& W; u$ }% T
- })
6 w& T! b4 L/ A' ]+ ^: h, m5 t - wx.request({! T3 i$ K0 y* u
- //获取空气质量的API接口地址; ^1 I5 t! U& z6 V6 Y
- url: `<a href="https://devapi.qweather.com/v7/air/now?location=" target="_blank">https://devapi.qweather.com/v7/air/now?location=</a>${longitude},${latitude}&key=${key}`,
; ^6 x3 K$ [" y7 Q - success (res) {
3 X! h* `) g$ S7 H+ e ? - const air=res.data.now O/ B5 ^, [; e2 Z2 o0 |
- const {aqi, category}=air //解构赋值- ?6 F% {: J0 Y
- that.setData({4 U/ `' J! v" }3 W4 Z
- aqi,
% |7 S+ X" _0 F, x' g/ v - airText:category
* d( @" z0 w( E/ z+ K) W - })* x, ]5 S! r+ e( Y
- }" V% y0 p( `) B: X, C; h) k" ]' x0 d
- })
5 A( g# b3 O2 W6 W# H F o
5 b. z7 Z6 n }$ f, T- wx.request({* h6 S. s. q R3 l7 W
- //获取生活质量的API接口地址
, B2 G, t* ]2 E6 q8 R' L0 R - url:<a href="https://devapi.qweather.com/v7/indices/1d?type=3&location=" target="_blank">type=3&location=</a>${longitude},${latitude}&key=${key}`, # W* u5 r$ U) q4 A/ x/ g
- success (res) {
; E- ]& U8 e3 ^8 U% |* S; Z; R0 V - const {text}=res.data.daily[0] //解构赋值: P9 m3 h- x3 w8 y9 e: Z) S
- that.setData({
- k0 n2 |6 Q6 Y& p* d - weatherAdvice:text
- h. Q! R0 c9 t+ K h5 ]; Z! n - })
$ ^+ d4 a) U5 R' M m - }; |" } n$ K3 w* G: {9 C( A
- })6 g. w; q% B; A
- }
( ^' K# x7 y% Y$ U& m/ R5 V6 ~$ ~ - })
0 ^; m2 N) b% F6 W1 v - }
复制代码 * D! a2 a$ \& T6 s# U
接下来是小程序端的MQTT连接部分,首先需要导入一个连接服务器的库,这个库叫mqtt.min.js。该库的地址如下:mqtt.min.js文件
, r, o* K3 g) U+ z8 c" X5 H( Y 下载后,直接在小程序中建一个文件夹存放解压出来的文件,其中有两个文件分别为mqtt.js、mqtt.min.js,在小程序的js文件中只需引用mqtt.min.js文件即可,详细的引用代码及具体的自定义函数如下所示:(如果连接的是私有服务器需要多修改设备ID和密码,否则只需修改连接的服务器地址及端口号):
9 y: \6 z& h9 J3 y- B' P9 ~6 Y) Q9 h; l1 E$ m) E
- var mqtt=require("../../utils/mqtt.min.js")
* t* B, E) x5 N8 ^$ g) @ - var client=null. K, N C- H, Z2 w
- Page({' |+ _0 I2 r* N( \
- /**: b, N" j0 K0 z3 \) L6 X
- * 页面的初始数据
; i0 c7 `$ k0 i3 \6 j, m. Y4 M - */$ e, N: N8 k4 T6 z* I+ d
- data: {, i4 w8 T l/ v5 k, W
! p4 v/ z8 I+ z4 m6 |: \9 k- },% @3 V. n( ~% u: N5 W! C
: W8 E8 `2 t7 _5 W2 s+ T- ]- onLoad(){* p& s7 r1 T+ W
- this.connectmqtt()
5 K+ y. k3 |# W - },. Y- a. U5 e$ k; |" C! Y$ t/ u7 T# X
- $ Y( l- T) y( E. l! `! O" W
- connectmqtt:function(){+ S/ F/ k' z; B( s, f2 `) P7 x
- var that=this;//this是指外层的对象,如果在这里进行提取,后面进入函数后,他的this就是connectmqtt函数的对象
% h8 P* H% D+ h - /*杰叔叔、EMQX专用*/% ^3 H; p& p% G( ~, ~" h
- const options={
# z2 f& X( P1 V; p& Z - connectTimeout:4000,
) U7 P0 n5 P8 x1 N7 g - clientId:"zsd", //此变量随便写
$ V2 Y" N& z, M* W - port:8084,
m) r; `. _" u3 W% h4 k - //杰叔叔的服务器是私有,所以需要账号和密码,而EMQX的免费服务器不需要账号密码
: p8 X6 i1 }! L! | - username:"f6d61178afa1003ac5d41dc9ae10f0c6",
+ _7 z1 E" U4 y. B1 F5 S - password:"123123"
0 {. T c# x" _ - }' ]- z, z/ y1 ~. ~. D# y6 V
- /*腾讯云MQTT服务器专用*/
( t- t+ d$ j* e7 h3 A" g - /* const options={0 q. P# {" T6 z1 s0 s2 v$ I' G
- connectTimeout:4000,8 F6 o5 M3 B3 q' V2 }8 y
- clientId:"zsd", //此变量随便写
5 _2 v+ w' r0 I g - port:80,) ~1 n, R3 |. |, K/ O
- username:"S2ME0J3F8Xtest1;12010126;bee9c;1656302400000",
n* }) @( U0 `" j# ` - password:"d58ce11e6725c4de9549c61d564f8bc0c7211707642ae92c63dd94b27943f85e;hmacsha256"$ I O$ U( Q' b* u$ Z3 @' r
- }*/5 P% f# g/ u+ R1 p
- /*百度云MQTT服务器专用*/. b- u8 c; a0 P# ?
- /* const options={
8 H* t, t4 ^/ M# a7 M2 k - connectTimeout:4000,4 ^ z4 O6 n: @2 V# o7 f8 W7 z; {
- clientId:"zsd", //此变量随便写
- s" @" V2 p1 z, g; A/ t. u- r3 [ - port:443,: P) W8 E9 _& N/ J, g. j; i) c; E# z
- username:"thingidp@acwbepc|test2|0|SHA256",
9 c6 l! Z1 v. k) D. _ - password:"6fac92df9ce9cb5839cf95da0c0d8f60e3d5d333fff8b7d85bcaf5b5e71d8517"
A. V( k2 c) M/ L- h+ H: s - }*/1 l7 B4 F& a4 K
- /*小程序连接远程服务器时,用wxs(wss)加密连接出去,其他客户端工具,
X( D V4 J: b3 v9 e5 R - 例如emqx在线测试工具可以使用wss协议连接服务器一;mqttbox软件也可以使用mqtt/tcp协议连接服务器一1 T0 o5 ?$ s8 |( K- v/ \( a
- 原因是因为服务器支持这些协议,本质上wss、mqtt都是基于tcp进行封装的
; v. R/ d& Y4 K; r- _8 Y. \1 { - 实际上下面借助wxs协议连接服务器一,而其他工具也是借助服务器支持的协议进行连接,然后就可以进行数据的传输
! z" h' C, V) T5 c/ W - 如果连接的协议是ws或wss,需要在服务器地址后面加上/mqtt,如果不是前面这两个协议的地址,则直接连接服务器地址即可*/
- |: r( V8 l$ W. ]4 X6 e - //client=mqtt.connect("wxs://t.yoyolife.fun/mqtt", options)杰叔叔的服务器地址(wss协议需加上mqtt路径)
8 {" O. u+ H" C, _' Q- I2 T - client=mqtt.connect("wxs://broker-cn.emqx.io/mqtt", options)//EMQX的服务器地址(wss协议需加上mqtt路径)
6 D6 d, Z; \1 L& E - //client=mqtt.connect("wxs://broker.emqx.io/mqtt", options)//EMQX的服务器地址(wss协议需加上mqtt路径)- I8 N4 l9 x& r4 F3 q/ N" K- W
- //client=mqtt.connect("wxs://S2ME0J3F8X.ap-guangzhou.iothub.tencentdevices.com/mqtt", options)//腾讯云服务器地址(wss协议需加上mqtt路径)/ ]$ S3 i: h: {. q* n
- //client=mqtt.connect("wxs://acwbepc.iot.gz.baidubce.com/mqtt", options)//百度云服务器地址(wss协议需加上mqtt路径)0 k9 j" f9 t; V# u5 P1 o
- client.on("connect",(e)=>{$ X% l* s% `$ }4 p3 u+ c% F* F
- console.log("服务器连接成功");/ {6 `( t. m: }0 [
- client.subscribe("/iot/1009/zsd2", {qos:0}, function(err){//杰叔叔的服务器需要主题前缀、EMQX服务器不需要主题前缀
- b: |, [2 f2 T" K0 m6 _ - if(!err){8 O# i* p0 y' g. u
- console.log("订阅成功");
1 G+ ] V" b" i7 o3 F) v' i# I - }
6 w: b& g7 e/ D' r& U9 |& f - })" N9 l. |/ ?' m- b- \
- /* client.subscribe("S2ME0J3F8X/test1/data", {qos:0}, function(err){//腾讯云服务器需要主题前缀3 x: a9 N, ~2 ^" V! x! e
- if(!err){
# J7 t' E7 d0 Y3 R3 ^ - console.log("订阅成功");
2 N+ j; K9 _3 J( g' z4 U, M) B - }: k2 C+ ?9 P7 [/ X# \. L
- })*/
2 ~0 b# V q% B: J, F - /* client.subscribe("$iot/test2/user/test2", {qos:0}, function(err){//百度云服务器需要主题前缀
+ O2 F# O& c, x' F W4 a' V- N - if(!err){
4 \* O* O8 o# y1 j9 G. C0 w1 P - console.log("订阅成功");) o& K) V' J5 u
- }% S4 ?! ]& A: i) @8 t6 W& H: h
- })*// N% u5 c% N7 G0 ]
- })
; V" ^. w7 i7 K) R0 Y' c4 q - //信息监听事件
2 P! K" M( H) u - client.on("message", function(topic, message){7 |( c3 {1 t# k, |. Y1 \8 T
- let tem=JSON.parse(message)
6 O2 Y) v9 E* b6 r - console.log(tem);2 L( {/ j+ N# X" j1 Y
- that.setData({- l9 v* x7 r1 z8 {' H9 A- E1 G
- temp:tem.a,
9 x# e3 l: q9 w* A5 ~2 p! ^4 y. x - humi:tem.b
. \9 b! G. T+ h - })5 r8 L, y2 K# s
- console.log("收到"+message.toString());
3 x3 k+ {: W% {+ M, i2 y1 z - })+ K; J# M, l, ~5 w/ {5 B! `
- //发送reconnect类型给服务器,一旦连接中断,就会触发重新连接+ |2 M+ h: Z/ q4 O t
- client.on("reconnect", (err)=>{
0 S6 y1 g6 X. F$ E - console.log("正在重新连接",err);
1 ]% V7 c9 G+ D |5 T; x- Z - })7 `" |( j: y) Z% w! h8 T
- client.on("error", (err)=>{
5 L% P! O$ ], L7 U, Z - console.log("连接失败",err);8 O; w" b: B# Y5 h
- })
) f0 [7 t/ B( z w4 J' ` - }
: l0 |) e% l4 a# x3 s6 b
: Y$ P0 ~9 Z. ~1 m h' {4 C; y. R- })
( C' V" ` I) W' x: [5 b; K" ]
复制代码
, g& o+ E5 K) A 至此,小程序部分的天气数据获取和MQTT连接已经基本完成,至于界面的优化,那就需要各位去学习小程序的界面优化啦。5 ~/ Z; o) [0 }" v+ q
————————————————
Z5 V; k; s1 U, r, P版权声明:i土豆
D/ Q c$ h) d, \7 c% b( m3 G; z+ ~: m# j+ a
, j* d! G2 e2 X7 b2 W) C
|