前言
本篇教程是MQTT的进阶篇,在云服务器搭建好了MQTT服务器后,使用网页连接MQTT服务器,并发布相关的控制信息到服务器指定的Topic,ESP32在本地连接WIFI,订阅相同的Topic,收到控制信息后开启关闭响应的灯光。
该项目主要有四个步骤
1.控制端网页的编写以及连接MQTT
2.硬件实现部分
3.实现效果
4.资源下载
EMQ X服务器的编写请参考
https://blog.csdn.net/weixin_44636409/article/details/115897253
一、网页的编写
网页使用Bootstrap进行界面布局,再使用jQuery监测按钮时间,使用Bootstrap编写的网页是响应式网页,可以在不同的客户端自适应,显得较为美观。网页再通过client.publish(topic, ’ ')函数向服务器发送指令,从而向ESP32发出命令,MQTT部分要通过引用mqtt.min.js来实现。
Bootstrap文档地址:https://v3.bootcss.com/
网页端的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>mqtt.min.js 测试</title>
<script src="mqtt.min.js"></script> <!-- 引处MQTT.MINI.JS库文件 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="js/bootstrap/css/bootstrap.min.css">
<script src="js/jquery-2.1.4.min.js"></script>
<script src="js/jquery.cookie.min.js"></script>
<link rel="stylesheet" href="./css/style.css" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="js/bootstrap/js/bootstrap.min.js"></script>
<script src="js/vue.js"></script>
<script src="js/mqtt.min.js"></script> <!-- 引处MQTT.MINI.JS库文件 -->
<!-- <script src="js/app.js"></script> -->
<title></title>
<meta name="description" />
</head>
<body>
<div class="container text-center">
<button type="button" id="ledRedOn" class="btn btn-success btn-lg">红灯开</button>
<button type="button" id="ledRedOff" class="btn btn-info btn-lg">红灯关</button>
</div>
<br>
<div class="container text-center">
<button type="button" id="ledGreenOn" class="btn btn-success btn-lg">绿灯开</button>
<button type="button" id="ledGreenOff" class="btn btn-info btn-lg">绿灯关</button>
</div>
<br>
<div class="container text-center">
<button type="button" id="ledBlueOn" class="btn btn-success btn-lg">蓝灯开</button>
<button type="button" id="ledBlueOff" class="btn btn-info btn-lg">蓝灯关</button>
</div>
<br>
</body>
<script>
console.log(mqtt)
let receiveClear = document.getElementsByClassName('receiveClear')[0];
let receiveArea = document.getElementsByClassName('receiveArea')[0];
//【考试开始】----------------->请参考https://www.jianshu.com/p/4fd95cae1a9c完成以下js脚本实现连接,订阅,发布/接收消息
var topic_led = '2018A14130/biao';
//var topic_switch ='2018A14130/biao'; //定义两个topic(聊天topict和开关topic)
//连接选项,mqtt用户名和密码,这里面应该还可以加上其他参数,具体看官方文档: https://www.npmjs.com/package/mqtt#connect 和https://github.com/mqttjs/mqtt-packet#connect
const options = {
connectTimeout: 4000, // 超时时间
username: 'biao',
password: 'biao',
clientId: 'mqttjs_' + (Math.random() * 1000000).toString()
}
// console.log(options.clientId);
//1. 浏览器采用websocket协议,路径固定为/mqtt 【此处请定义mqtt客户端client、声明重连和连接失败报错】
const client = mqtt.connect('ws://这里填写EMQX的地址:8083/mqtt', options)
client.on('reconnect', (error) => {
console.log('正在重连:', error)
})
client.on('error', (error) => {
console.log('连接失败:', error)
})
//2. 建立连接 【此处请建立mqtt连接,并订阅上方定义的两个topic,友情提示:帖子示例中onSubscribeSuccess要加上引号】
client.on('connect', (e) => {
console.log('成功连接服务器')
// 订阅多个主题
client.subscribe(['topic_led','topic_switch'], { qos: 1 }, 'onSubscribeSuccess')
client.publish('topic_led', '11 EMQ', (error) => {
console.log(error || '消息发布成功')
})
})
// 监听接收消息事件
client.on('message', (topic_led, message) => {
console.log('收到来自', topic_led, '的消息', message.toString())
})
//3. 定义发送函数 function send_chat() //判断msg文本框内容是否为空 //判断客户端是否为空 //发送消息后将msg文本框清空
$(function(){
$('#ledRedOn').click(function(){
client.publish('topic_led', "1")
});
$('#ledRedOff').click(function(){
client.publish('topic_led', "2")
});
$('#ledGreenOn').click(function(){
client.publish('topic_led', "3")
});
$('#ledGreenOff').click(function(){
client.publish('topic_led', "4")
});
$('#ledBlueOn').click(function(){
client.publish('topic_led', "5")
});
$('#ledBlueOff').click(function(){
client.publish('topic_led', "6")
});
});
</script>
</html>
效果图
二、硬件实现部分
硬件为乐鑫esp32
软件平台为:arduino I
实现代码:
#include<WiFi.h>
#include<PubSubClient.h>
const char* ssid ="wifi账号";
const char*password = "wifi密码";
const char*mqttServer = "EMQ X服务器地址";
const int mqttPort =端口;
const char*mqttUser = "账号";
const char*mqttPassword = "密码";
char a[20];
int b;
int LED1=15;
int LED2=2;
int LED3=4;
WiFiClient espClient;
PubSubClient client(espClient);
void callback(char*topic, byte* payload, unsigned int length) {
Serial.print("Messagearrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i< length; i++) {
// Serial.print((char)payload[i]);
a[i]=(char)payload[i];
}
Serial.println();
for (int i = 0; i< length; i++) {
Serial.print( a[i]);
}
b= a[0];
if(b=='1')
{
greedledopen();
}
if(b=='2')
{
greedledclose();
}
if(b=='3')
{
redledopen();
}
if(b=='4')
{
redledclose();
}
if(b=='5')
{
yellowledopen();
}
if(b=='6')
{
yellowledclose();
}
Serial.println();
Serial.println("-----------------------");
}
void greedledopen()
{
digitalWrite(LED1,HIGH);
}
void greedledclose()
{
digitalWrite(LED1,LOW);
}
void redledopen()
{
digitalWrite(LED2,HIGH);
}
void redledclose()
{
digitalWrite(LED2,LOW);
}
void yellowledopen()
{
digitalWrite(LED3,HIGH);
}
void yellowledclose()
{
digitalWrite(LED3,LOW);
}
void setup() {
Serial.begin(115200);
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
pinMode(LED3,OUTPUT);
WiFi.begin(ssid,password);
while (WiFi.status()!= WL_CONNECTED) {
delay(500);
Serial.println("Connectingto WiFi..");
}
Serial.println("Connectedto the WiFi network");
client.setServer(mqttServer,mqttPort);
client.setCallback(callback);
while (!client.connected()){
Serial.println("Connectingto MQTT...");
if (client.connect("ESP32Client",mqttUser, mqttPassword )) {
Serial.println("connected");
}else {
Serial.print("failedwith state ");
Serial.print(client.state());
delay(2000);
}
}
client.subscribe("topic_led");
}
void loop() {
client.loop();
}
3.实现效果
打开web端,可以看到EMQ X服务器已经连接成功
按按键会发送对应的msg到对应的topic