From 9026528747fb026f9befb3f5ea53a35f15a32fcc Mon Sep 17 00:00:00 2001 From: iuu <2167162990@qq.com> Date: Thu, 17 Oct 2024 21:46:53 +0800 Subject: [PATCH] =?UTF-8?q?8266=E6=8E=A7=E5=88=B6l298n=E7=94=B5=E6=9C=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wifi-config_a.ino | 755 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 755 insertions(+) create mode 100644 wifi-config_a.ino diff --git a/wifi-config_a.ino b/wifi-config_a.ino new file mode 100644 index 0000000..a484084 --- /dev/null +++ b/wifi-config_a.ino @@ -0,0 +1,755 @@ +#include +#include +#include +#include +#include +#include +#include + + + + +int ENAPin = 14; // D5 ENA +int ENBPin = 12; // D6 ENB + +int IN1Pin = 4; // D2 IN1 +int IN2Pin = 0; // D3 IN2 +int IN3Pin = 13; // D7 IN3 +int IN4Pin = 15; // D8 IN4 + + + + +// 停止所有电机 +void stopMotors() { + digitalWrite(IN1Pin, LOW); + digitalWrite(IN2Pin, LOW); + stopMotorB(); +} + + + + +unsigned long startTime = 0; // 记录电机启动时间 +unsigned long runDuration = 0; // 电机运行的总时长 +bool motorRunning = false; // 电机是否在运行 + + +// 启动副电机 +void startMotorB() { + // 启动电机 正转 + digitalWrite(IN3Pin, LOW); + digitalWrite(IN4Pin, HIGH); + motorRunning = true; + startTime = millis(); // 记录启动时间 +} + +// 停止副电机 +void stopMotorB() { + // 停止电机 + digitalWrite(IN3Pin, LOW); + digitalWrite(IN4Pin, LOW); + motorRunning = false; + runDuration = 0; + startTime = 0; +} + +//AP名称 +const char* AP_NAME = "tiktok-wifi"; + +String nets; + + + +// 前端HTML页面内容定义为字符串 +const char* webpage PROGMEM = R"rawliteral( + + + + + + + 设备控制 + + + + + + + + + + + + + + + +)rawliteral"; + +const char* config_wifi_success_tip_html = "\ +\r\n\ +\r\n\ +\r\n\ + \r\n\ + \r\n\ + 网络配置\r\n\ + \r\n\ +\r\n\ +\r\n\ +
\r\n\ +

网络配置保存成功

\r\n\ +

设备IP地址: %s

\r\n\ +

WS地址: ws://%s:81

\r\n\ +
\r\n\ +\r\n\ +\r\n\ +"; +//POST参数有误 +const char* config_wifi_error_tip_html = "\ +\r\n\ +\r\n\ +\r\n\ + \r\n\ + \r\n\ + 网络配置\r\n\ + \r\n\ +\r\n\ +\r\n\ +

POST参数有误

\r\n\ +\r\n\ +\r\n\ +"; +//重置wifi配置 +const char* reset_wifi_tip_html = "\ +\r\n\ +\r\n\ +\r\n\ + \r\n\ + \r\n\ + 网络配置\r\n\ + \r\n\ +\r\n\ +\r\n\ +

清除WIFI配置信息成功

\r\n\ +\r\n\ +\r\n\ +"; +//配网页面代码 +const char* config_wifi_page_html = "\ +\r\n\ +\r\n\ +\r\n\ + \r\n\ + \r\n\ + 网络配置\r\n\ + \r\n\ +\r\n\ +\r\n\ +

网络配置

\r\n\ +
\r\n\ + \r\n\ + \r\n\ + \r\n\ + \r\n\ + \r\n\ + \r\n\ + \r\n\ +
\r\n\ +
\r\n\ + \r\n\ +
\r\n\ +
\r\n\ + \r\n\ +
\r\n\ +\r\n\ +\r\n\ +"; + +//DNS端口号 +const byte DNS_PORT = 53; +//esp8266-AP-IP地址 +IPAddress apIP(192, 168, 4, 1); +//创建dnsServer实例 +DNSServer dnsServer; +//创建WebServer +ESP8266WebServer server(80); +//创建webSocketServer +WebSocketsServer webSocketServer = WebSocketsServer(81); + + + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { + IPAddress ip; + switch (type) { + case WStype_DISCONNECTED: + Serial.println("对端关闭"); + ip = webSocketServer.remoteIP(num); + nets = String(ip[0]) + String(".") + String(ip[1]) + String(".") + String(ip[2]) + String(".") + String(ip[3]); + Serial.println(nets); + break; + case WStype_CONNECTED: + { + Serial.println("对端连接"); + ip = webSocketServer.remoteIP(num); + nets = String(ip[0]) + String(".") + String(ip[1]) + String(".") + String(ip[2]) + String(".") + String(ip[3]); + Serial.println(nets); + } + break; + case WStype_TEXT: + Serial.println("收到消息"); + showcpu(payload); + break; + } +} + +void showcpu(uint8_t* payload) { + StaticJsonDocument<200> root; + deserializeJson(root, (const char*)payload); + String type = root["type"]; + Serial.println("type-----" + String(type)); + int typeAsInt = type.toInt(); + switch (typeAsInt) { + case 1: + // 增加运行时间 + // 增加运行时间 + runDuration += 10000; // 增加10秒的运行时间 + if (!motorRunning) { + startMotorB(); // 如果电机未运行,则启动电机 + } + break; + default: + // 如果收到的action不是预期的,停止所有电机 + // stopMotors(); + break; + } +} + + +//访问主页回调函数 +void handleRoot() { + server.send(200, "text/html", config_wifi_page_html); +} + +void handleReset() { + for (int i = 0; i < 96; ++i) { + EEPROM.write(2048 + i, 0); + } + EEPROM.commit(); + server.send(200, "text/html", reset_wifi_tip_html); + delay(2000); + Serial.println("准备重启中..."); + Serial.println(); + //重启 + ESP.reset(); +} + +void handleReconfigure() { + Serial.println("正在重新配置Wi-Fi..."); + if (WiFi.status() == WL_CONNECTED) { //如果连接上 就输出IP信息 防止未连接上break后会误输出 + // 断开当前的Wi-Fi连接 + WiFi.disconnect(); + // 启动AP模式 + initSoftAP(); + initDNS(); + } +} + + +//Post回调函数 +void handleRootPost() { + Serial.println("接收POST数据"); + String qsid = server.arg("ssid"); + String qpass = server.arg("password"); + Serial.println("POST-WIFI名称:"); + Serial.println(qsid); + Serial.println("POST-WIFI密码:"); + Serial.println(qpass); + Serial.println(""); + if (qsid.length() > 0 && qpass.length() > 0) { + Serial.println("清除之前的账号密码开始"); + for (int i = 0; i < 96; ++i) { + EEPROM.write(2048 + i, 0); + } + Serial.println("清除之前的账号密码完毕"); + Serial.println("写入新的WIFI名称:"); + for (int i = 0; i < qsid.length(); ++i) { + EEPROM.write(2048 + i, qsid[i]); + } + Serial.println("写入新的WIFI密码:"); + for (int i = 0; i < qpass.length(); ++i) { + EEPROM.write(2048 + 32 + i, qpass[i]); + } + EEPROM.commit(); + // 连接新的Wi-Fi + connectNewWifi(); + // 返回保存成功页面和IP地址 + // String response = "网络配置保存成功
"; + // response += "设备IP地址: " + WiFi.localIP().toString(); + + + char html_buffer[1024]; // 确保数组足够大以容纳字符串 + snprintf(html_buffer, sizeof(html_buffer), config_wifi_success_tip_html, + WiFi.localIP().toString().c_str(), // 插入设备 IP 地址 + WiFi.localIP().toString().c_str() // 插入设备 IP 地址 + ); + + // 打印生成的 HTML + Serial.println(html_buffer); + + server.send(200, "text/html", html_buffer); + } else { + Serial.println("POST参数有误"); + server.send(200, "text/html", config_wifi_error_tip_html); + return; + } + + + + + + + //返回保存成功页面 + // server.send(200, "text/html", "保存成功"); + + + //重启 + delay(2000); + Serial.println("准备重启中..."); + Serial.println(); + ESP.reset(); +} + + + +//初始化基础 +void initBasic(void) { + Serial.begin(115200); + //设置设备名 + // WiFi.hostname("HOMEKIT"); + // 断开之前链接的WIFI + WiFi.disconnect(); + // 初始化 EEPROM + // EEPROM = EEPROMClass(0x3FB); + + EEPROM.begin(4096); +} + +//初始化AP模式 +void initSoftAP(void) { + WiFi.mode(WIFI_AP); + WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); + if (WiFi.softAP(AP_NAME)) { + Serial.println("AP模式设置成功"); + } +} + +//初始化WebServer +void initWebServer(void) { + //设置主页回调函数 + server.on("/", HTTP_GET, handleRoot); + //设置Post请求回调函数 + server.on("/", HTTP_POST, handleRootPost); + + server.on("/reset", HTTP_GET, handleReset); + // 添加重新配置路由 + server.on("/reconfigure", HTTP_GET, handleReconfigure); + + + server.on("/md", HTTP_GET, handleGet); + // server.on("/command", HTTP_POST, handlePost); // 短按命令 + server.on("/start", HTTP_POST, handleStart); // 开始运动的请求 + // server.on("/stop", HTTP_POST, handleStop); // 停止运动的请求 + + //设置无法响应的http请求的回调函数 + server.onNotFound(handleRoot); + + //启动WebServer + server.begin(); + Serial.println(); + Serial.println("HTTP服务启动成功!"); +} +// 处理GET请求以返回HTML页面 +void handleGet() { + if (server.method() == HTTP_GET) { + server.send(200, "text/html", webpage); + } +} + +// 处理POST请求以控制电机 +// void handlePost() { +// if (server.method() == HTTP_POST) { +// StaticJsonDocument<200> doc; +// deserializeJson(doc, server.arg("plain")); +// int action = doc["action"].as(); +// bool longPress = doc["longPress"].as(); // 长按标志 + +// setMotorState(action, longPress); + +// if (!longPress) { +// delay(1000); // 短按持续1秒 +// stopMotors(); // 停止电机 +// } + +// server.send(200, "text/plain", "Action received."); +// } +// } +// 处理开始运动的请求 +void handleStart() { + if (server.method() == HTTP_POST) { + StaticJsonDocument<200> doc; + deserializeJson(doc, server.arg("plain")); + int action = doc["action"].as(); + setMotorState(action, true); // 开始运动 + server.send(200, "text/plain", "Start action received."); + } +} + +// 处理停止运动的请求 +// void handleStop() { +// if (server.method() == HTTP_POST) { +// stopMotors(); // 停止所有电机 +// server.send(200, "text/plain", "Stop action received."); +// } +// } + +void setMotorState(int action, bool continuous) { + Serial.println("如下:"); + Serial.println(action); + // 根据action设置电机状态 + switch (action) { + case 0: // 全部电机停止 + stopMotors(); + break; + case 1: // 主电机关闭 + digitalWrite(IN1Pin, LOW); + digitalWrite(IN2Pin, LOW); + break; + case 2: // 主电机开启 + // 正转 + digitalWrite(IN1Pin, LOW); + digitalWrite(IN2Pin, HIGH); + break; + case 3: // 副电机关闭 + // 停止 + stopMotorB(); + break; + case 4: // 副电机开启 + startMotorB(); + break; + case 5: // 副电机反向 + // 增加运行时间 + runDuration += 5000; // 增加5秒的运行时间 + if (!motorRunning) { + startMotorB(); // 如果电机未运行,则启动电机 + } + break; + case 6: + // 增加运行时间 + runDuration += 10000; // 增加5秒的运行时间 + if (!motorRunning) { + startMotorB(); // 如果电机未运行,则启动电机 + } + break; + case 7: + // 增加运行时间 + runDuration += 20000; // 增加5秒的运行时间 + if (!motorRunning) { + startMotorB(); // 如果电机未运行,则启动电机 + } + break; + default: + // 如果收到的action不是预期的,停止所有电机 + // stopMotors(); + break; + } + // 如果不是长按,不需要在这里停止电机,因为会有单独的停止请求 +} +//初始化DNS服务器 +void initDNS(void) { + //判断将所有地址映射到esp8266的ip上是否成功 + if (dnsServer.start(DNS_PORT, "*", apIP)) { + Serial.println("DNS服务器启动成功."); + } else { + Serial.println("DNS服务器启动失败."); + } +} + +void connectNewWifi(void) { + Serial.println("读取本地缓存的WIFI名称"); + String esid; + for (int i = 0; i < 32; ++i) { + esid += char(EEPROM.read(2048 + i)); + } + Serial.println(esid); + Serial.println("读取本地缓存的WIFI密码"); + String epass = ""; + for (int i = 32; i < 96; ++i) { + epass += char(EEPROM.read(2048 + i)); + } + Serial.println(epass); + // WiFi.hostname("esp8266_test"); + WiFi.begin(esid, epass); // 链接WIFI + Serial.println(""); + Serial.print("正在连接WIFI中"); + int count = 0; + while (WiFi.status() != WL_CONNECTED) { + delay(1000); + count++; + if (count > 10) { //如果5秒内没有连上,就开启Web配网 可适当调整这个时间 + initSoftAP(); + initDNS(); + break; // 跳出 防止无限初始化 + } + Serial.print("."); + } + + + Serial.println(""); + if (WiFi.status() == WL_CONNECTED) { //如果连接上 就输出IP信息 防止未连接上break后会误输出 + Serial.println("WIFI链接成功!"); + Serial.println("IP地址如下:"); + Serial.println(WiFi.localIP()); + // server.stop(); + } +} + + +void setPinsOutput(void) { + // 设置电机驱动引脚为输出模式 + pinMode(ENAPin, OUTPUT); + pinMode(ENBPin, OUTPUT); + pinMode(IN1Pin, OUTPUT); + pinMode(IN2Pin, OUTPUT); + pinMode(IN3Pin, OUTPUT); + pinMode(IN4Pin, OUTPUT); + + // 最大动力旋转 + digitalWrite(ENAPin, HIGH); + digitalWrite(ENBPin, HIGH); +} + + + + + + + + + + +void setup() { + initBasic(); + initWebServer(); + connectNewWifi(); + webSocketServer.begin(); + webSocketServer.onEvent(webSocketEvent); + Serial.println("webSocketServer start"); + // 设置电机驱动引脚为输出模式 + setPinsOutput(); +} + + + +unsigned long previousMillis = 0; // 上次执行的时间 +const long interval = 1000; // 每秒执行一次(1000毫秒) + +void loop() { + server.handleClient(); + dnsServer.processNextRequest(); + webSocketServer.loop(); + + + + unsigned long currentMillis = millis(); // 获取当前时间 + + // 每秒执行一次电机状态检查 + if (currentMillis - previousMillis >= interval) { + previousMillis = currentMillis; // 更新上次执行的时间 + + // 如果电机正在运行,检查运行时间 + if (motorRunning) { + Serial.println("电机运行中"); + Serial.println(millis() - startTime); + Serial.println(runDuration); + if (millis() - startTime >= runDuration) { // 检查是否达到运行时间 + stopMotorB(); // 停止电机 + // motorRunning = false; // 更新电机状态 + } + } else { // 如果电机未运行 + Serial.println("电机未运行"); + Serial.println(millis() - startTime); + Serial.println(runDuration); + if (millis() - startTime < runDuration) { // 检查是否达到运行时间 + startMotorB(); // 停止电机 + } + } + } + + // // 如果电机正在运行,检查运行时间 + // if (motorRunning) { + // Serial.println("电机运行中"); + // Serial.println(millis() - startTime); + // Serial.println(runDuration); + // if (millis() - startTime >= runDuration) { // 检查是否达到运行时间 + // stopMotorB(); // 停止电机 + // } + // } + // if (!motorRunning) { + // Serial.println("电机未运行"); + // Serial.println(millis() - startTime); + // Serial.println(runDuration); + // if (millis() - startTime < runDuration) { // 检查是否达到运行时间 + // startMotorB(); // 停止电机 + // } + // } + delay(5); +}