舵机的远程灯控制系统"/>
基于ESP8266和微型舵机的远程灯控制系统
1. 项目简介
本项目基于ESP8266开发板和微型舵机,实现了一套远程灯控系统,达到了通过WIFI控制灯具开关的目的。github地址:远程灯控项目
2.项目所需硬件
-
ESP8266开发版一块
-
具有数据传输功能的USB线一根
-
杜邦线若干(母对母、公对母都要有)
-
SG90微型舵机一个
3.项目所需软件
- Arduino IDE点击访问官网下载
4.项目整体架构
项目整体采用B/S架构,ESP8266充当服务器,通过手机浏览器访问服务器网页,在网页上点击舵机控制按钮,控制舵机按一定角度旋转从而实现开关灯具的功能。
下图是系统整体架构图:
5.前端界面设计
系统前端界面主要有两个:身份验证登录界面、舵机控制界面
身份验证登录界面如下:
前端界面比较简单,主要就是输入密钥进行身份验证。验证过程在后端执行,密钥是一个固定值,也写在后端代码里。一个ip短时间内有3次试错机会,超过3次会暂时无法进入控制界面。
舵机控制界面如下:
点击按钮可以控制舵机进行关灯操作。
5.后端功能设计
后端主要实现了:esp8266热点功能、登录身份验证功能、舵机控制功能
Arduino代码如下:
#include <ESP8266WiFi.h> // 本程序使用 ESP8266WiFi库
#include <ESP8266WebServer.h> // ESP8266WebServer库
#include <FS.h> //esp8266闪存读写库
#include <Servo.h> //舵机控制库
#include <map> //c++字典库
#include <set> //c++集合库Servo myservo; //实例化舵机类
std::map<String, int> userCountMap; //记录用户试错次数
std::set<String> userLogin; //记录用户是否登录成功
const char *ssid = "远程灯控"; //esp8266的wifi热点名称
const char *password = ""; //不设置wifi密码
const String PSW = "2333"; //登录密钥
const char *headerKeys[] = {"Content-Length", "Content-Type", "Connection", "Date"}; //获取登录用户ip
ESP8266WebServer esp8266_server(80); //设置esp8266服务器开发的端口void setup(void){//初始化myservo.attach(2,500,2500); //设置舵机控制信号输出端口myservo.write(0); //舵机归零myservo.detach(); //关闭舵机WiFi.softAP(ssid, password); //打开热点功能SPIFFS.begin();// 启动闪存文件系统esp8266_server.onNotFound(handleUserRequet); //网页资源未找到时启动的回调函数esp8266_server.begin();// 启动网页服务器 esp8266_server.on("/login", handleLogin);//设置登录界面路由 esp8266_server.on("/control", handleControl); //设置控制界面路由 esp8266_server.collectHeaders(headerKeys, sizeof(headerKeys) / sizeof(headerKeys[0])); //设置收集用户ip地址
}void loop(void){esp8266_server.handleClient(); //监听客户端连接
}void handleLogin(){//登录功能实现// 根据ip地址限制试错次数&设置登录状态String key(esp8266_server.arg("password")); //获取前端传过来的密钥String ip(esp8266_server.client().remoteIP().toString()); //获取用户ipif(userCountMap.count(ip)== 0){//首次登录创建用户试错次数字典userCountMap[ip] = 0; //首次登录,试错次数置为0if(PSW.equals(key)){//如果前端密钥和后端密钥一致userLogin.insert(ip); //设置用户为登录状态handleFileRead("/home.html"); //路由至控制界面}else{//如果密钥不一致userCountMap[ip] += 1; //试错次数+1handleFileRead("/index.html"); // 路由至登录界面}}else{//如果之前有登录记录if(userCountMap[ip]>3){//如果试错次数超限handleFileRead("/index.html"); //跳转值登录界面}else{//如果没有超限if(PSW.equals(key)){ //密钥一致userLogin.insert(ip); //设置为登录状态handleFileRead("/home.html"); //跳转至控制界面}else{ //密钥不一致userCountMap[ip] += 1; //试错次数+1handleFileRead("/index.html"); //跳转至首页继续登录}}}
}void handleControl(){//控制功能实现 String ip(esp8266_server.client().remoteIP().toString()); //获取用户ipif(userLogin.count(ip)== 1){ //如果是已经登录的用户就可以控制舵机myservo.attach(2,500,2500); //设置舵机参数myservo.write(0);//复位delay(500);myservo.write(90);//关灯delay(500);myservo.write(0);//复位delay(20);myservo.detach(); //关闭舵机handleFileRead("/home.html"); //继续路由至控制界面}else{ //如果是未登录用户则返回访问受限esp8266_server.send(500, "text/plain", "500: promise deny"); }
}// 处理用户浏览器的HTTP访问
void handleUserRequet() { // 获取用户请求网址信息String webAddress = esp8266_server.uri();// 通过handleFileRead函数处处理用户访问bool fileReadOK = handleFileRead(webAddress);// 如果在SPIFFS无法找到用户访问的资源,则回复404 (Not Found)if (!fileReadOK){ esp8266_server.send(404, "text/plain", "404 Not Found"); }
}bool handleFileRead(String path) { //处理浏览器HTTP访问if (path.endsWith("/")) { // 如果访问地址以"/"为结尾path = "/index.html"; // 则将访问地址修改为/index.html便于SPIFFS访问} String contentType = getContentType(path); // 获取文件类型if (SPIFFS.exists(path)) { // 如果访问的文件可以在SPIFFS中找到File file = SPIFFS.open(path, "r"); // 则尝试打开该文件esp8266_server.streamFile(file, contentType);// 并且将该文件返回给浏览器file.close(); // 并且关闭文件return true; // 返回true}return false; // 如果文件未找到,则返回false
}// 获取文件类型
String getContentType(String filename){if(filename.endsWith(".htm")) return "text/html";else if(filename.endsWith(".html")) return "text/html";else if(filename.endsWith(".css")) return "text/css";else if(filename.endsWith(".js")) return "application/javascript";else if(filename.endsWith(".png")) return "image/png";else if(filename.endsWith(".gif")) return "image/gif";else if(filename.endsWith(".jpg")) return "image/jpeg";else if(filename.endsWith(".ico")) return "image/x-icon";else if(filename.endsWith(".xml")) return "text/xml";else if(filename.endsWith(".pdf")) return "application/x-pdf";else if(filename.endsWith(".zip")) return "application/x-zip";else if(filename.endsWith(".gz")) return "application/x-gzip";return "text/plain";
}
6.整体效果演示
基于ESP8266和微型舵机的远程灯控制系统
更多推荐
基于ESP8266和微型舵机的远程灯控制系统
发布评论