stm32连接服务器端* ^* q% K& a |* o( }* c
本章所用到的器件如下:
/ m) B. w: X7 g# \+ t: m4 e SSTM32F103ZET6最小系统板
9 S# }1 G- H* E/ d: ]ESP8266-01S模块
( ?2 z7 S) Z6 D F& CUSB转microUSB数据线" F( q r' ^4 n
四根杜邦线
% T& \" _0 g7 \% p E7 k d$ L8 ?连接如下:
- h3 ~* Z0 b8 p' n* t32板3.3v----------->ESP8266的3.3v6 _0 d @( I5 ^! s& D( }1 J( m
32板GND---------->ESP8266的GND
: w+ n H' I- Z, K% v$ _32板的PC10-------->ESP8266的RX) {' y$ ~ b! {1 F
32板的PC11-------->ESP8266的TX* |% f" B8 M5 g$ e- N, P5 x
% w! u$ M" w b$ ?3 N
在这里说明一下,由于本项目是用在其他项目上的,所以在编写此项目时,是基于另一个项目还未被使用到的串口资源进行设计的,所以我这里用了串口4。各位需根据自己硬件已有的串口资源,自行手动修改串口4初始化的函数。* O3 } V( N: K$ }3 L+ n- F# T: g* {
" D) q# @# W/ X5 u0 B 本项目程序是参考onenet平台上的源码进行二次开发的,onenet平台上源码的位置如下:进入onenet官网后,登录账号,在上方有一个社区->论坛,里面就有源码,点进去后就有一个链接是百度网盘的,这里我用的是OneNET标准板中的裸机基础教程->EDP例程。# E' c) C9 Q- P
( ?( i+ V. x* ~2 ?8 d+ `/ e* I; j3 L* ~. W& Z8 z
' _: |' a( S" N7 D3 X! a
! l2 [2 l$ D* I; i2 s/ O3 [1 S% ~, Y0 D- Y& m
/ H9 T2 L" x" z5 H: x$ r5 I" i
3 X* h1 R7 _+ ^+ M" A" t) S 既然用到了MQTT协议,少不了要用到cJSON格式的一个文件,将cJSON.c和cJSON.h文件导入到stm32程序所在的文件夹下,接着在程序中onenet.c文件里面包含头文件cJSON.h,方便我们下面对接收到的cJSON格式的数据进行解析。
- y4 {0 z; n' x N& s/ o5 a m% o9 ^- J
9 f) q0 f( ], v; u! f& z+ c
8 ^4 N& ]! b( ?' Q* {, ?6 ^' d
接下来,我们需要修改的是esp8266.c文件中的ESP8266_WIFI_INFO及ESP8266_ONENET_INFO,他们分别表示的是ESP8266需要连接的WIFI及服务器地址(修改成自己的WIFI名称、密码和服务器地址、端口号),本项目中给出了五个MQTT服务器地址,其中EMQX服务器是公有服务器,可以直接连接,至于其他三个服务器是自己在其他平台创建的私有服务器,需要用到onenet.c文件中的设备ID和密码。EMQX服务器连接的时候不需要用到设备ID和密码,所以设备ID和密码可以随便写。 / _- S. a u& O) M
& a$ A% [5 D1 o+ m
; K* I- R% v& |! C$ {& ~7 s! l4 u* t+ H5 {+ q7 G
- _- l8 a* a+ H2 M9 f, n
5 q( n. C8 V% B) k4 o 最后,需要设置一下主题的发布和订阅,对于公有服务器来说,是没有主题前缀的,而对于私有服务器来说,他有平台自带的主题前缀。 此项目中连接的是EMQX的服务器,是不需要主题前缀的,所以这里我随便写了一个发布主题和订阅主题(同时这两个主题也可用于我创建的私有服务器的设备相对应的主题)。
; P3 W$ ]) f7 t1 t2 f! r0 u P( S5 `' I
$ X W6 @: @ P9 H, ^- n. e* U
6 F& b, z; n- W( e2 p2 ^0 W- q- G1 o. U 至此,stm32部分的程序已经搞好了,接下来进行小程序部分的制作。$ v' w5 O9 n/ `4 A3 B! a0 a* f3 j
; V% b; J# ]2 N) \4 t$ E小程序连接服务器
3 a4 ]) G& M2 O& Q% M 先上小程序的效果展示图
1 P+ a$ |9 q$ ] Z# {2 W" R2 f; {1 C; K: y
& @% l$ |' b6 [8 t+ u8 O6 a# R5 I! X- S# |. F1 H
* A" j) p: L) Q$ j6 W 此项目的小程序我没有用过任何框架,都是使用微信原生框架进行开发,其中首页涉及到天气数据的获取,这里请求的天气数据API接口采用的是和风天气开发平台上的Web API接口,其链接如下:和风天气开发平台# o5 U+ R3 @4 B. \. x
要请求该平台上面的API接口,需要在该平台上登录账号,然后进入控制台,在上面创建一个应用(目的是获取到一个KEY),如下所示:+ _, Z/ @6 w1 @
0 j% D" v. R v) A1 Q- }4 g- M& s
2 ^! S7 U: u, k8 }* u
4 S1 E2 m0 A5 z 接着到该平台的开发文档->天气数据Web API开发文档中去找对应的请求地址,上面清楚的写了该地址的格式及请求的参数等信息,下面是小程序端的获取天气数据的自定义函数:2 y/ G* T" J! p
# N6 v6 C- P' e
- weahterdata:function(){
& n9 i( C: q# U$ `2 F - var that=this
1 n4 K9 z0 \ R* C- Z - wx.getLocation({//获取位置(经纬度)API7 P+ q& |- A7 o O# s3 b" s
- type: 'wgs84',, d$ e- W& Y( T, D, @
- success (res) {' l. e$ @. l# M9 s0 u- D
- const latitude = res.latitude
; k0 ]$ H \5 V+ Q( L! ^2 v - const longitude = res.longitude1 z- a3 C1 n7 }8 `: I
- const key="432a8840589546338cae4c5a825f47db"//和风天气开发平台上控制台创建的应用得到的KEY,只有得到这个,才能获取各种数据; J3 f! v6 I: ^6 s# d$ ]( m
- wx.request({//网络请求API$ g5 n! b, [& ]1 L% G
- //下面使用模板字符串8 I9 A0 s5 s, l! Z
- //获取天气数据的API接口地址
2 ~- F. i( u; [' [7 {: T - 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}`, : V1 x# w* P% v9 G9 w4 c
- success (res) {
7 s4 M8 C, f z, v2 P* ] - const weather_data=res.data.now 0 Q" |; `5 D" c8 ^/ K
- const weather=weather_data.text //解构赋值0 d8 y$ P" P' [( R. W
- that.setData({
" b$ @* g/ a/ h9 {1 q - weather
( R: V1 J' k( Y- G: S0 S: @0 o - })* [2 N( N/ h& N$ o1 n: X# A; R) M$ z
- }
+ |0 X2 |" h. d7 Z - })1 U& E. F6 V5 P" ]2 U% O" n& @7 h L( N
- wx.request({7 i# a' `: {5 G$ R$ k; q% E/ `
- //获取地点的API接口地址
{6 A: E) Q7 F3 @( b - url: , 2 Z' P- }+ ^1 G) i$ M- b
- success (res) {
' P$ q+ ?% _5 @& T5 l4 W2 @6 l6 f' [$ S - const location=res.data.location[0]
% Z7 k6 A. [9 j4 Q, Z- P - const {adm2, name}=location //解构赋值2 H8 v V- I0 `: ]# ~- }6 A" f) u
- that.setData({$ @. g6 u- V$ E3 l0 X, V# Y+ f8 U
- city:adm2," d6 W+ C9 y3 G; q/ o; Y' `& B" @
- area:name4 r. g: ]- j$ p" e$ G) P% T
- })
& @ W1 b: U) X, W - }( _* j2 w3 c, M: L$ g* m9 u
- })
6 {$ v3 W' T4 S3 [8 X2 t8 {8 Y - wx.request({
, K& ] H1 B/ l - //获取空气质量的API接口地址
# e/ @( X# O4 o* J& V - 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}`,
9 N9 ~8 D& h# E& F& Z W9 L - success (res) {5 A7 i8 u; B" D9 ^0 h
- const air=res.data.now
' e+ f8 U+ z1 N7 z - const {aqi, category}=air //解构赋值
1 p' a! I% j$ M$ m5 W# H - that.setData({8 Q: `# F4 b' a
- aqi,
+ N6 J# c3 |# S" K6 X( Z3 Z4 \ b - airText:category
4 a4 x# K o+ o3 N- M - })
5 @& F$ l9 @. J+ T0 ~: m - }8 _/ ~& w9 O- V. Q3 B
- })
( h+ D3 @2 U# | - ( x) c& {, _* N
- wx.request({* @" G* t6 y' H
- //获取生活质量的API接口地址" W0 D% m7 O8 ^5 x9 z
- url:<a href="https://devapi.qweather.com/v7/indices/1d?type=3&location=" target="_blank">type=3&location=</a>${longitude},${latitude}&key=${key}`,
) S$ w2 X+ d6 T8 j - success (res) {/ i; i F0 B4 O+ k
- const {text}=res.data.daily[0] //解构赋值' D" j: } o9 F; d6 w5 e
- that.setData({
4 H/ D/ t9 z- |; l - weatherAdvice:text
9 ~" k- [8 V1 B6 V - })
" p3 T4 I$ ~! ]- n* L, a/ j7 X - }2 H4 p9 M" E" S& U- _8 D5 R
- })
* R8 o# @* J+ ^" I& B' X2 h - }1 m4 O- i) b' a" p
- })
t+ O8 c! A- J3 T( b - }
复制代码
T& f; R/ j1 X( F- I( B 接下来是小程序端的MQTT连接部分,首先需要导入一个连接服务器的库,这个库叫mqtt.min.js。该库的地址如下:mqtt.min.js文件
: a e0 O8 q' B' B; e! E4 U% h# V6 _ 下载后,直接在小程序中建一个文件夹存放解压出来的文件,其中有两个文件分别为mqtt.js、mqtt.min.js,在小程序的js文件中只需引用mqtt.min.js文件即可,详细的引用代码及具体的自定义函数如下所示:(如果连接的是私有服务器需要多修改设备ID和密码,否则只需修改连接的服务器地址及端口号):" \( h, Q C4 @
8 {, Z& ?2 U) r- j! V
- var mqtt=require("../../utils/mqtt.min.js")
! E3 h! {' C o" |% v! @ - var client=null
# ?* G+ f9 q& y: x- u# d - Page({
4 I2 Q5 i" t0 Q - /**
. T4 j$ S7 D. y' }+ I - * 页面的初始数据
3 q% v/ L# ^4 u) l+ k/ f - */
) ~6 L) \4 Q4 e - data: {
9 c& F+ D$ F8 Y! d
+ Y2 G& A5 ]6 j8 c# n- },
, X$ b$ N0 O1 Y7 j! Y - , p0 }9 P) S3 }
- onLoad(){. T" ?# ?: s1 E5 `$ S- O8 }
- this.connectmqtt()+ b" T2 _: b( A" N! t
- },
6 N8 P/ _5 y8 }. l
5 p. I# |& b# a8 U( b+ g3 ~& |- connectmqtt:function(){5 f0 ]5 q, d7 W/ K
- var that=this;//this是指外层的对象,如果在这里进行提取,后面进入函数后,他的this就是connectmqtt函数的对象! G# w, {& Z4 K2 P2 n' x, p* `% ?
- /*杰叔叔、EMQX专用*/, ^! I' t0 M/ A# f# m( K
- const options={
% u& @# l# U, P4 `& M& f - connectTimeout:4000,
& X7 m; H- H* C3 Y5 e8 E, C! r1 n, b, U - clientId:"zsd", //此变量随便写
5 @1 g' V C4 a+ \6 ]( i4 s, h - port:8084,: l H$ t; J0 D" u
- //杰叔叔的服务器是私有,所以需要账号和密码,而EMQX的免费服务器不需要账号密码" X. p) K b4 g8 l4 Z: L) N
- username:"f6d61178afa1003ac5d41dc9ae10f0c6",
2 \# D$ w! C- H+ _ - password:"123123"- O1 _- |9 L% E
- }
4 b+ z. V7 ^/ S$ \8 a( ?3 w5 e - /*腾讯云MQTT服务器专用*/
+ z9 P( g/ ~+ H2 V `* x) I - /* const options={
% ]8 F! f; z& ^0 M+ c - connectTimeout:4000,
: k9 T! q4 y1 l2 u5 a, Q - clientId:"zsd", //此变量随便写
5 V/ y: K: e6 }1 }: H& m6 A - port:80,
$ w% K! m, S! W/ b. \ - username:"S2ME0J3F8Xtest1;12010126;bee9c;1656302400000",
, |+ v9 ^# a4 B3 |! c2 H( Z# d/ P - password:"d58ce11e6725c4de9549c61d564f8bc0c7211707642ae92c63dd94b27943f85e;hmacsha256" v& k! Q. u6 q( u3 x% ?$ b
- }*/
6 Z: J( G1 v; c$ O) t0 r - /*百度云MQTT服务器专用*/
8 d: `; E9 u6 s( z4 x - /* const options={$ Z3 G) k% [+ D5 ?9 j
- connectTimeout:4000,
Y7 b2 O' [, X" P - clientId:"zsd", //此变量随便写
4 {8 H) ?3 o" Y" F R5 t& T - port:443,! Y5 h3 o9 Z" b$ A4 c
- username:"thingidp@acwbepc|test2|0|SHA256",* R H# _) o X. e% r
- password:"6fac92df9ce9cb5839cf95da0c0d8f60e3d5d333fff8b7d85bcaf5b5e71d8517". U! H* v) z0 B- t
- }*/
' ]) r2 @0 u H, o; U- A8 M0 }3 r! [% o - /*小程序连接远程服务器时,用wxs(wss)加密连接出去,其他客户端工具,
/ Q p# y+ t9 Q& A - 例如emqx在线测试工具可以使用wss协议连接服务器一;mqttbox软件也可以使用mqtt/tcp协议连接服务器一
6 e5 \0 @0 l$ j( G9 x! u. W" Z - 原因是因为服务器支持这些协议,本质上wss、mqtt都是基于tcp进行封装的
( v) B2 k! X G' c; C1 d. g - 实际上下面借助wxs协议连接服务器一,而其他工具也是借助服务器支持的协议进行连接,然后就可以进行数据的传输8 Z2 P4 N; @- `! _0 Y7 `. T
- 如果连接的协议是ws或wss,需要在服务器地址后面加上/mqtt,如果不是前面这两个协议的地址,则直接连接服务器地址即可*/! y& b0 y+ \, h! E
- //client=mqtt.connect("wxs://t.yoyolife.fun/mqtt", options)杰叔叔的服务器地址(wss协议需加上mqtt路径)
: ]/ j! U q2 ?' o1 C - client=mqtt.connect("wxs://broker-cn.emqx.io/mqtt", options)//EMQX的服务器地址(wss协议需加上mqtt路径)- n6 K/ N0 N3 M4 o* ]
- //client=mqtt.connect("wxs://broker.emqx.io/mqtt", options)//EMQX的服务器地址(wss协议需加上mqtt路径) a0 b* U0 {+ e" ]
- //client=mqtt.connect("wxs://S2ME0J3F8X.ap-guangzhou.iothub.tencentdevices.com/mqtt", options)//腾讯云服务器地址(wss协议需加上mqtt路径)3 [/ u4 B6 H# f0 B2 ?( {& z e7 |
- //client=mqtt.connect("wxs://acwbepc.iot.gz.baidubce.com/mqtt", options)//百度云服务器地址(wss协议需加上mqtt路径). f* t& r7 j& ]% i5 l5 H2 _
- client.on("connect",(e)=>{
: ~4 w5 }7 |% k+ c/ T, ?7 A - console.log("服务器连接成功");
! ?" Y- b6 U/ A# E8 @. N - client.subscribe("/iot/1009/zsd2", {qos:0}, function(err){//杰叔叔的服务器需要主题前缀、EMQX服务器不需要主题前缀& t5 s! i# G q3 i# W5 ]
- if(!err){4 c7 _7 s) _/ r+ s7 j- Z
- console.log("订阅成功");
- N& _' O0 L- l, c+ y - }3 O ~' t/ s- h& \" M7 L3 |: H
- })
6 g6 h6 `8 ?; Q- E; } - /* client.subscribe("S2ME0J3F8X/test1/data", {qos:0}, function(err){//腾讯云服务器需要主题前缀+ u. {/ V/ ^0 t; S4 [
- if(!err){" o7 b/ o% A, G& i/ b
- console.log("订阅成功");9 C, c! q. | Z
- }
# N2 O( F9 e0 S# M/ g' c - })*/
1 e) D. t0 q, |- y5 T, Y - /* client.subscribe("$iot/test2/user/test2", {qos:0}, function(err){//百度云服务器需要主题前缀
5 _: t+ f% C% s% m- M; }3 K. d/ Q - if(!err){- w( A2 N) u% g$ Y
- console.log("订阅成功");
4 c3 o$ m. ]) i# ~' I3 \$ e7 U - }
9 x* l/ C. L" r2 [. Q& O6 F - })*/6 g% k H) P! [& T) p* R( R+ N
- })
6 C) @/ n" V5 {9 |3 s - //信息监听事件6 f; W- X, Z9 [4 Y6 u e
- client.on("message", function(topic, message){
7 {- ^6 H4 [* G4 k - let tem=JSON.parse(message). n. U" X* F* @$ R7 I
- console.log(tem);
; Q" ^/ U- }5 t4 D8 d - that.setData({) N, X. w$ i7 Q( z9 i+ v
- temp:tem.a,
6 s/ S2 r/ \7 b9 f G0 g( h6 V - humi:tem.b6 V; l$ f5 C* [4 ?
- })
8 N2 R/ Y& B5 Z* m4 p8 z - console.log("收到"+message.toString());
. r/ `& H. I! {7 l* J& m9 K1 G - })
) g' w4 n. a5 O. T - //发送reconnect类型给服务器,一旦连接中断,就会触发重新连接
# N: F& _# t& \ - client.on("reconnect", (err)=>{3 l8 h \6 I/ S& |
- console.log("正在重新连接",err);
7 L7 N3 x5 l! v1 D% b7 N - })6 y/ b5 a K9 @# @6 |1 P# `* t
- client.on("error", (err)=>{5 [& E4 i# R: v' j
- console.log("连接失败",err);
: R4 I+ K9 P4 v4 ]7 Y8 {& v5 S - })5 _% H2 }7 O, Q
- }5 @& q# ^6 R; ~2 U* O
- % W( W3 @0 N" N
- })
* o) N0 l: I) f0 O
复制代码 : B9 o+ d8 j2 q
至此,小程序部分的天气数据获取和MQTT连接已经基本完成,至于界面的优化,那就需要各位去学习小程序的界面优化啦。
3 H0 O4 P, Z. k————————————————& I Z9 I7 F! P$ o( U
版权声明:i土豆
% T5 w+ s; ?4 o+ R) T* B! N
A" ], F3 s/ K# N1 d) C9 [
7 j/ w9 v3 v# y9 u; W$ r4 A+ J |