一、安装第三方库
// WIFI自动配网
git clone https://github.com/tzapu/WiFiManager.git
// Json解析
git clone https://github.com/bblanchon/ArduinoJson.git
// MQTT连接
git clone https://github.com/knolleary/pubsubclient.git
// WebSocket连接
git clone https://github.com/Links2004/arduinoWebSockets.git
二、测试效果
三、完整代码
// AutoConnectAP.h
#ifndef AUTO_CONNECT_AP_H
#define AUTO_CONNECT_AP_H
#include "../lib/WiFiManager/WiFiManager.h"
bool autoConnectAP() {
// 创建WIFI管理器
WiFiManager wifiManager;
// 开始自动配网
if (wifiManager.autoConnect("ESP8266-Auto")) {
return true;
} else {
return false;
}
}
#endif // AUTO_CONNECT_AP_H
// ConnectMQTT.h
#ifndef CONNECT_MQTT_H
#define CONNECT_MQTT_H
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <LittleFS.h>
#include "../lib/pubsubclient/src/PubSubClient.h"
#include "../lib/arduinoWebSockets/src/WebSocketsServer.h"
#define MQTT_HOST ""
#define MQTT_PORT 1883
#define MQTT_CLIENT_ID ""
#define MQTT_USER ""
#define MQTT_PASS ""
#define HTTP_PORT 80
// 创建WIFI客户端
WiFiClient wifiClient;
// 创建MQTT客户端
PubSubClient mqttClient(wifiClient);
// 创建HTTP服务器
ESP8266WebServer webServer(HTTP_PORT);
// 创建WS服务器
WebSocketsServer webSocketServer(81);
uint8_t clientId = 0;
// 主页源码
String homeContent = R"(
<html>
<head>
<meta charset="UTF-8"/>
<title>消息列表</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<div>
<input id="msg"/>
<button id="send">发送消息</button>
</div>
<div>消息列表:</div>
<div id="log"></div>
<script>
$(function(){
let ws = new WebSocket("ws://192.168.10.5:81");
ws.onpen = function(res) {
console.log("onpen", res);
}
ws.onclose = function(res) {
console.log("onclose", res);
}
ws.onmessage = function(res) {
console.log("onmessage", res.data);
$("#log").append("<div>" + res.data + "</div>");
}
ws.onerror = function(res) {
console.log("onerror", res);
}
$("#send").click(function(){
let msg = $("#msg").val();
console.log("发送消息: ", msg);
ws.send(msg);
});
})
</script>
</body>
</html>)";
void sendMQTT(const String &payload)
{
// 判断MQTT服务器是否已连接
if (!mqttClient.connected())
{
Serial.println("MQTT服务器未连接");
return;
}
// 定义MQTT主题
String topic = "/a1aeNGS45Gg/";
topic += "ESP8266";
topic += "/user/info";
if (mqttClient.publish(topic.c_str(), payload.c_str()))
{
Serial.println("MQTT消息发送成功");
}
else
{
Serial.println("MQTT消息发送失败");
}
}
void onWebSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
{
clientId = num;
String message = String((char *)payload).substring(0, length);
switch ((int)type)
{
case WStype_CONNECTED:
Serial.println("WebSocket连接成功");
break;
case WStype_DISCONNECTED:
Serial.println("WebSocket断开连接");
break;
case WStype_TEXT:
Serial.println("WebSocket收到消息: " + message);
Serial.println("length: " + String(length));
// 发送消息到MQTT服务器
sendMQTT(message);
break;
}
}
void handleRoot()
{
// 打开页面文件
File file = LittleFS.open("/index.html", "r");
String content = file.readString();
// 响应HTTP请求
webServer.send(200, "text/html", content);
}
void handleNotFound()
{
webServer.send(404, "text/html", "<h1>Not found</h1>");
}
void recvMQTT(char *topic, uint8_t *payload, unsigned int length)
{
String message = String((char *)payload).substring(0, length);
Serial.println("topic: " + String(topic));
Serial.println("payload: " + message);
Serial.println("length: " + String(length));
// 回复WebSocket消息
webSocketServer.sendTXT(clientId, message);
}
void initMQTT()
{
// 配置MQTT服务器
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
// 设置MQTT消息回调函数
mqttClient.setCallback(recvMQTT);
// 启动HTTP服务器
webServer.begin();
// 设置HTTP请求处理函数
webServer.on("/", handleRoot);
webServer.onNotFound(handleNotFound);
// 启动WebSocket服务器
webSocketServer.begin();
webSocketServer.onEvent(onWebSocketEvent);
// 加载文件系统
if (!LittleFS.begin())
{
Serial.println("文件系统加载失败");
return;
}
// 写入页面文件
File file = LittleFS.open("/index.html", "w");
file.print(homeContent);
file.close();
}
void connectMQTT()
{
// 连接MQTT服务器
if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS))
{
Serial.println("MQTT服务器连接成功");
// 定义MQTT主题
String topic = "/a1aeNGS45Gg/";
topic += "ESP8266";
topic += "/user/info";
// 订阅MQTT主题
if (mqttClient.subscribe(topic.c_str()))
{
Serial.println("MQTT主题订阅成功");
}
else
{
Serial.println("MQTT主题订阅失败");
}
}
else
{
Serial.println("MQTT服务器连接失败");
delay(3000);
}
}
void loopMQTT()
{
// 判断MQTT是否已连接
if (mqttClient.connected())
{
// 保持MQTT连接心跳
mqttClient.loop();
}
else
{
// 重新连接MQTT服务器
connectMQTT();
}
// 处理HTTP客户端请求
webServer.handleClient();
// 保持WebSocket服务器心跳
webSocketServer.loop();
}
#endif // CONNECT_MQTT_H
// main.cpp
#include <Arduino.h>
#include "AutoConnectAP.h"
#include "ConnectMQTT.h"
void setup()
{
// put your setup code here, to run once:
// 设置波特率
Serial.begin(9600);
Serial.println();
// 自动配网
if (!autoConnectAP())
{
Serial.println("自动配网失败");
return;
}
Serial.println("自动配网成功");
Serial.println("WIFI名称: " + WiFi.SSID());
Serial.println("IP地址: " + WiFi.localIP().toString());
// 初始化MQTT服务器
initMQTT();
// 连接MQTT服务器
connectMQTT();
}
void loop()
{
// put your main code here, to run repeatedly:
// 保持MQTT连接心跳
loopMQTT();
}