前言
当需要手机连接开发板(nodemcu
)的wifi
,并且和它进行数据通信时,就需要用到本文内容。
本文使用 nodemcu
搭建一个 http
服务和一个webSocket
服务,前者用于提供web
页面,后者用于在页面中和开发板进行实时通信。
nodemcu http和wss服务搭建
下面代码在 Arduino IDE
中编译。
c
#include <WiFiClient.h> // 调用WiFiClient库,用于建立wifi连接
#include <ESP8266WebServer.h> // 调用WebServer库,用于构建html页面
#include <WebSocketsServer.h> // 用于构建ws服务
#include <Arduino_JSON.h>
// wifi 账号密码
String wifi_name = "test";
String wifi_pwd = "12345678";
// 建立WebServer,端口为80
ESP8266WebServer server(80);
// socket 服务
WebSocketsServer webSocket = WebSocketsServer(81);
#define USE_SERIAL Serial
// 处理接到的消息,代码中演示 json 解析方法
void msg_cb(uint8_t* payload) {
JSONVar infosObj = JSON.parse((char*)payload); // 将 payload 转换为 char*
// if (JSON.typeof(infosObj) == "undefined") {
// return;
// }
//if (infosObj.hasOwnProperty("dj_deg")) {
// dj_deg = (int)infosObj["dj_deg"];
//}
}
void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) {
switch (type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[%u] Disconnected!\n", num);
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
// send message to client
webSocket.sendTXT(num, "Connected");
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
msg_cb(payload);
// send message to client
// webSocket.sendTXT(num, "message here");
// send data to all connected clients
// webSocket.broadcastTXT("message here");
break;
case WStype_BIN:
USE_SERIAL.printf("[%u] get binary length: %u\n", num, length);
hexdump(payload, length);
// send message to client
// webSocket.sendBIN(num, payload, length);
break;
}
}
// http 服务 "/" 路由处理函数,返回一个 html 文件
// 这页面文件会直接写到代码中,也可以使用 `FS.h` 存入闪存。
void ctrl_page() {
String content = "<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'><meta name='viewport'content='width=device-width, initial-scale=1.0'><title>测试</title><style>body{margin:0;padding:0;width:100%;height:100%}</style></head><body><input id='dj_range'type='range'min='0'max='180'step='1'value='90'style='width: 100%;margin: 50px 0px;'></body></html><script>var server='ws://192.168.4.1:81';var socket=new WebSocket(server);socket.onopen=function(event){console.log('WebSocket 连接已建立');document.querySelector('#dj_range').addEventListener('input',function(e){var val=Number(e.target.value);socket.send(JSON.stringify({dj_deg:val}))})};socket.onmessage=function(event){console.log('收到消息:',event.data)};socket.onclose=function(event){console.log('WebSocket 连接已关闭')};socket.onerror=function(error){console.error('WebSocket 发生错误:',error)};</script>";
server.send(200, "text/html", content);
}
// 对外接口
void initServer() {
// 手机控制页面
server.on("/", ctrl_page);
server.begin();
}
void setup() {
Serial.begin(115200); // 初始化串口,波特率为 115200
WiFi.mode(WIFI_AP); // 将WiFi模式设为AP
WiFi.softAP(wifi_name, wifi_pwd); // 开启热点
IPAddress ip = WiFi.softAPIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
String httpUrl = "http://" + ipStr;
Serial.println("AP IP:");
Serial.println(ipStr);
// http 服务
initServer();
// ws 服务
webSocket.begin();
webSocket.onEvent(webSocketEvent);
}
void loop() {
// 处理客户端请求
server.handleClient();
webSocket.loop();
}
页面代码
页面代码最后写完后压缩后,放到了上面代码中。
需要注意的是这里用不了 socket.io.js
这个很棒的插件。因为这个插件太大了,放板子里太多余,所以需要手写 js
提供的 api
, 详细学习见: developer.mozilla.org/en-US/docs/...
html 文件压缩工具:www.jyshare.com/front-end/4...
html
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>测试</title>
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<input id='dj_range' type='range' min='0' max='180' step='1' value='90' style='width: 100%;margin: 50px 0px;'>
</body>
</html>
<script>
// 板子的ip
var server = 'ws://192.168.4.1:81';
// 创建 WebSocket 连接
var socket = new WebSocket(server);
// 当连接建立时
socket.onopen = function (event) {
console.log('WebSocket 连接已建立');
document.querySelector('#dj_range').addEventListener('input', function (e) {
var val = Number(e.target.value);
// 发送 Socket.IO 握手消息
socket.send(JSON.stringify({ dj_deg: val }));
})
};
// 当收到消息时
socket.onmessage = function (event) {
console.log('收到消息:', event.data);
};
// 当连接关闭时
socket.onclose = function (event) {
console.log('WebSocket 连接已关闭');
};
// 当发生错误时
socket.onerror = function (error) {
console.error('WebSocket 发生错误:', error);
};
</script>
效果
拖动页面滚动条,板子会实时收到消息。