赞
踩
目的:局域网模式下,手机连接ESP8266开放的热点,通过手机浏览器访问ESP8266提供的Web服务,在打开的网站上:http://192.168.4.1直接操作按钮控制三个灯的亮和熄灭。此文章重点讲解写入ESP8266的源码。
硬件:ESP8266开发板一块、三个继电器、三个小灯、杜邦线、5V充电头、手机充电线一根
连线方案:看文章最后的详细指导视频
先看成品,手机展示界面:这里我定义了三个灯,所以展示的是三个灯的数据,如果灯是开启的状态就是开,关闭的就是关,通过操作列可以对灯进行控制
源码讲解:
调用库文件,因为需要使用ESP8266的wifi功能,所以需要wifi库,然后我们需要使用ESP8266来为我们提供Web服务,让我们用手机就可以访问它的网站,所以还需要一个webserver库
- #include <ESP8266WiFi.h>
- #include <ESP8266WebServer.h>
接下来是定义的各种变量,由于代码中有详细的注释,这里就不统一讲解,值得注意的是我们提供的web服务需要使用账号密码进行登录,所以我在这里设置了用户名和密码,在代码中是
String Setting_UserName="8266iot";//设置:用户名
String Setting_PassWord="8266iot.cn";//设置:密码
这里可以根据自己的需求进行更改,这里的密码也是我提供的物联网平台的域名,有兴趣的可以浏览器打开看看。
- ESP8266WebServer esp8266_server(80);// 建立ESP8266WebServer对象,对象名称为esp8266_server
- String Setting_UserName="8266iot";//设置:用户名
- String Setting_PassWord="8266iot.cn";//设置:密码
- const int SwitchNum=3;//有几个继电器控制几个灯就改数量
- const int SwitchPin[SwitchNum]={D0,D1,D2};//定义继电器电平输出引脚
- String SwichName[SwitchNum]={"A灯","B灯","C灯"};//对应更改灯或者继电器的显示名称
- int SwitchStatus[SwitchNum]={0,0,0};//初始数据都是0
- String login="<!DOCTYPE html><html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0'><title>登录</title><style>body {font-family: Arial, sans-serif;background-color: #f4f4f4;display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;}.login-container {width: 300px;padding: 40px;background-color: #fff;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);text-align: center; border-radius: 50px;}.login-container h2 {margin-bottom: 20px;}.form-group {margin-bottom: 15px;}.form-group label {display: block;margin-bottom: 5px;text-align: left; }.form-group input[type='text'],.form-group input[type='password'] {width: 100%;padding: 10px;border: 1px solid #ddd;border-radius: 4px;font-size: 16px;}.form-group input[type='submit'] {padding: 10px 20px; border: none;border-radius: 4px;background-color: #5cb85c;color: white;cursor: pointer;width: 108%; }.form-group input[type='submit']:hover {background-color: #4cae4c;}</style></head><body><div class='login-container'><h2>董哥物联网</h2><h2>控制平台登录</h2><form method='post'><div class='form-group'><label for='username'>用户名:</label><input type='text' id='username' name='username' required><input type='hidden' name='id' value='1' /></div><div class='form-group'><label for='password'>密码:</label><input type='password' id='password' name='password' required></div><div class='form-group'><input type='submit' value='Login'></div></form></div></body></html>";
- String loginerror="<!DOCTYPE html><html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0'><title>登录</title><style>body {font-family: Arial, sans-serif;background-color: #f4f4f4;display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;}.login-container {width: 300px;padding: 40px;background-color: #fff;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);text-align: center; border-radius: 50px;}.login-container h2 {margin-bottom: 20px;}.form-group {margin-bottom: 15px;}.form-group label {display: block;margin-bottom: 5px;text-align: left; }.form-group input[type='text'],.form-group input[type='password'] {width: 100%;padding: 10px;border: 1px solid #ddd;border-radius: 4px;font-size: 16px;}.form-group input[type='submit'] {padding: 10px 20px; border: none;border-radius: 4px;background-color: #5cb85c;color: white;cursor: pointer;width: 108%; }.form-group input[type='submit']:hover {background-color: #4cae4c;}</style></head><body><div class='login-container'><h2>董哥物联网</h2><h2>控制平台登录</h2><form method='post'><div class='form-group'><label for='username'>用户名:</label><input type='text' id='username' name='username' required><input type='hidden' name='id' value='1' /></div><div class='form-group'><label for='password'>密码:</label><input type='password' id='password' name='password' required></div><h2>账号/密码有误</h2><div class='form-group'><input type='submit' value='Login'></div></form></div></body></html>";
上面定义的是打开的第一个页面,用户登录后才可以控制开关灯的两个页面,一个是用户打开后显示界面login,还有就是用户登录错误的显示界面。
这里还定义了一个函数用于直接开放热点给我们的手机或者电脑连接,wifi名称是ESP8266_AP,密码是password,实际过程中可以自己根据自己的情况进行更改
- void wifiap(){
- WiFi.softAP("ESP8266_AP", "password");
- }
然后是单片机启动的时候的初始化程序,这里的串口初始化是方便调试的时候看输出的,正式项目不需要,调用的wifiap()函数是启动一个wifi给我们连接,网络服务功能就是为我们提供web服务,就像你打开百度一样。for循环就是为了初始化三个控制引脚,三个控制引脚分别连接三个继电器的IN引脚。
- void setup() {
- Serial.begin(9600); //初始化串口设置
- wifiap();
- //--------"启动网络服务功能"程序部分开始-------- //
- esp8266_server.begin();
- esp8266_server.on("/", deal);
- esp8266_server.onNotFound(NotFound);
- //--------"启动网络服务功能"程序部分结束--------
- for(int i=0;i<SwitchNum;i++){
- pinMode(SwitchPin[i],OUTPUT);//初始化引脚控制为输出模式
- digitalWrite(SwitchPin[i],LOW);//初始化引脚为低电平
- }
- }
单片机启动后会反复执行的程序如下:
- void loop() {
- //本地创建服务器提供手机连接AP的wifi进行控制
- esp8266_server.handleClient(); // 处理http服务器访问
- }
这里是因为我们的单片机提供的web服务需要不断的处理,所以这里要反复执行去等待用户请求,然后就是整个程序的关键部分,这里是为了处理用户的请求,这里我用了一个选择分支结构来做判断,分别执行不同的操作,只有当用户点击页面的按钮才会触发,因为手机浏览器打开的永远是192.168.4.1的ip地址,但是处理逻辑是页面提供的表单数据来做判断的。如果不能理解的话需要你懂html的基础逻辑,实在没办法就直接复制粘贴用吧。代码中有详细的注释,这里就不做介绍。因为考虑到小白也能看懂,所以代码没有做任何优化,都是用的基础语法来写的。
- void deal() { //处理网站根目录“/”的访问请求
- //请求地址 http://192.168.4.1
- String id="0";
- if(esp8266_server.arg("id").length()>0){
- id=esp8266_server.arg("id");//使用id来区分请求
- }
- int x=((int)id[0]-48);//把id转换为int方便使用switch case判断
- switch(x){
- case 1:{
- String UserName=esp8266_server.arg("username");//获取用户名
- String PassWord=esp8266_server.arg("password");//获取密码
- if(UserName==Setting_UserName && PassWord==Setting_PassWord){//判断提交的用户名和密码是否匹配
- if(esp8266_server.arg("do")=="update"){//如果提交的参数有update就说明需要更改状态
- for(int i=0;i<SwitchNum;i++){//遍历去找需要更改的
- if(esp8266_server.arg("s"+String(i)).length()>0){//找到需要更改的那个,长度一定>0
- if(esp8266_server.arg("s"+String(i))=="0"){//判断需要更新的数据是否为0
- SwitchStatus[i]=0;//为0置0
- }else{
- SwitchStatus[i]=1;//不为0置1
- }
- }
- }
- }
- for(int i=0;i<SwitchNum;i++){//根据状态把引脚处理好
- if(SwitchStatus[i]==0){
- digitalWrite(SwitchPin[i],LOW);//为0置为低电平
- }else if(SwitchStatus[i]==1){
- digitalWrite(SwitchPin[i],HIGH);//为1置为高电平
- }
- }
- //以下是为了显示登录成功后的数据页面
- String str="<!DOCTYPE html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'><title>主页展示</title><style>body {font-family: Arial, sans-serif;background-color: #f4f4f4;justify-content: center;align-items: center;height: 100vh;margin: 0;}.login-container {width: 300px;padding: 40px;background-color: #fff;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);text-align: center; border-radius: 50px;}table {width: 100%;border-collapse: collapse;}th, td {padding: 10px;text-align: left;border-bottom: 1px solid #ddd;}th {background-color: #f2f2f2;}tr:nth-child(even) {background-color: #f9f9f9;}tr:hover {background-color: #ddd;}a {display: inline-block; padding: 10px 20px; font-size: 16px; text-decoration: none; color: #3498db;background-color: #f0f0f0; border: none; border-radius: 4px; cursor: pointer; transition: background-color 0.3s ease; }a:hover {background-color: #ddd; }a:visited {color: #3498db; }.button {display: inline-block; padding: 10px 20px; color: #fff; font-size: 16px; text-decoration: none; text-align: center;border: none; border-radius: 4px; cursor: pointer; transition: background-color 0.3s ease; }.green-button {background-color: #4CAF50;}.gray-button {background-color: #9E9E9E;}.button:hover {opacity: 0.8; }</style></head><body><div class='login-container'><h2>数据展示列表</h2>";
- str+="<table><thead><tr><th>名称</th><th>状态</th><th>操作</th></tr></thead><tbody>";
- //以上两句是页面显示样式
- for(int i=0;i<SwitchNum;i++){//循环遍历输出所有的数据记录
- str+="<tr><td>"+SwichName[i]+"</td>";//输出的名称
- if(SwitchStatus[i]==1){//判断状态是否打开 1就是打开的
- str+="<td><a class='button green-button'>开</a></td>";//输出状态 开
- //再输出关掉的操作
- str+="<td><a href='http://192.168.4.1/?id=1&do=update&username=" +UserName +"&password=" +PassWord +"&s"+String(i)+"=0'>关掉</a></td>";
- }else{
- str+="<td><a class='button gray-button'>关</a></td>";
- str+="<td><a href='http://192.168.4.1/?id=1&do=update&username=" +UserName +"&password=" +PassWord +"&s"+String(i)+"=1'>打开</a></td>";
- }
- str+="</tr>";
- }
- str+="</tbody></table></div></body></html>";//最后把网页补充完整
- esp8266_server.send(200, "text/html", str);//直接输出到页面
- }else{//不匹配返回登录错误提示
- esp8266_server.send(200, "text/html", loginerror);
- }
- }
- break;
-
-
-
- default:{
- esp8266_server.send(200, "text/html", login);
- }
- }
- }
其实为了防止用户访问的乱改访问参数,还做了限制处理
- void NotFound(){// 当浏览器请求的网络资源无法在服务器找到时,
- esp8266_server.send(200, "text/html", login);
- }
这里的限制处理是用户改了浏览器的地址栏的参数后会直接让你重新去登录,返回的是登录界面
最后附上详细的制作讲解过程视频
单片机和手机通信使用HTML技术手机浏览器直接访问页面精美简单实现数据交互控制-超级详细的讲解教程_哔哩哔哩_bilibili
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。