首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Esp8266 进阶之路32【高级篇】当esp8266遇到 Html,该怎么内置网页控制设备,理清内置网页的实现过程,实现无需路由器手机也可以控制esp8266。(附带固件)

  • 23-11-14 06:02
  • 2071
  • 11942
blog.csdn.net

  • 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。

1、 Esp8266之 搭建开发环境,开始一个“hellow world”串口打印。
2、 Esp8266之 利用GPIO开始使用按钮点亮你的“第一盏灯”。
3、 Esp8266之 利用 "软件定时器 " 定时0.5秒闪烁点亮一盏LED。
4 、Esp8266之 了解PWM,更为深入地用PWM控制一盏LED的亮度变化。
5 、Esp8266之 原生乐鑫SDK高级使用之封装Post与Get请求云端,拿到“天气预报信息”。
6 、Esp8266之 了解 SmartConfig与Airkiss一键配网,给8266配网上云端。无需把wifi名字密码写在固件里。
7 、Esp8266之 了解 softAP热点配网模式原理,仿“机智云”定义自己的热点配网模式协议。
8、 Esp8266之 你要找的8266作为UDP、TCP客户端或服务端的角色通讯,都在这了。
9、 Esp8266进阶之路第1篇: [小实战上篇]Windows系统搭建8266的本地Mqtt服务器,局域网点亮一盏LED灯。
10、 Esp8266进阶之路第2篇: [小实战下篇]Windows系统搭建8266的本地Mqtt服务器,局域网点亮一盏LED灯。
11、 Esp8266进阶之路第3篇: 8266接入阿里智能,点亮一盏LED灯,期待天猫精灵语音控制的不约而至!
12、 Esp8266进阶之路第4篇: 图文并茂学习阿里云主机搭建8266MQTT服务器,实现移动网络远程控制一盏LED。
13、 Esp8266进阶之路第5篇: 动手做个8266毕设小案例,smartConfig + MQTT协议轻松实现远程控制一盏LED。
14、 Esp8266进阶之路第6篇: esp8266的 FreeRtos系统学习的正确姿势 ------ 环境搭建、烧录。
15、 Esp8266进阶之路第7篇: esp8266的 物联网又一股清流,8266接入阿里云平台非阿里智能的SDS服务,点亮一盏LED灯。
16、 Esp8266进阶之路第8篇: esp8266的 基于Nonos移植红外线H1838,实现红外遥控器配网,远程控制一盏灯。
17、 Esp8266进阶之路第9篇: esp8266自研的快速上电开关五次 (开-关为一次) ,无需按键触发则8266进去一键配网模式。
18、 Esp8266进阶之路第10篇: esp8266 基于NONOS 实现 OTA 远程升级,实现无线“ 热修复 ”升级固件程序。
19、 Esp8266进阶之路第11篇: esp8266驱动 ds18b20、dht11 温湿度传感器,采集温湿度传感器到服务器。
20、 Esp8266进阶之路第12篇: 深入学习esp8266的esp now模式,仿机智云做一个小网关,实现无需网络下轻松彼此连接通讯交互数据。
21、 Esp8266进阶之路第13篇: 浅谈 esp8266 如何在本地局域网网络情况下实现最大效率地和前端实现数据交互。
22、 Esp8266进阶之路第14篇: esp8266的工程如何添加第三方静态库文件以及如何自定义文件夹,聊聊那些makeFile的事。。
23、 Esp8266进阶之路第15篇: 再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,接触下 lwip的基本知识。。
24、 Esp8266进阶之路第16篇: 渗透学习回顾下esp8266的外置spi芯片25q系列,熟悉8266代码块在其的分布,得心应手放置图片或其他资料。
25、 Esp8266进阶之路第17篇: 深聊下esp8266的串口 Uart 通讯中断编程,为您准备好了 NONOS 版本 和 RTOS 系统的串口驱动文件。
26、 Esp8266进阶之路第18篇: RTOS分析 MQTT 实现过程,实现移植 MQTT协议在 esp8266 rtos实时系统,可断线重连。
27、 Esp8266进阶之路第19篇: 跟紧脚步,用VisualStudio Code开发 esp8266 rtos SDK v3.0版本,全新的 idf 框架,节省内存模块化开发。
28、 Esp8266进阶之路第20篇: 教你轻松自如使用cJson在乐鑫 esp8266 如何解析一段json数据以及如何生成一段json数据。
29、 Esp8266进阶之路第21篇: 百万条消息免费之乐鑫esp8266使用TCP直连模式MQTT协议接入阿里云物联网平台,支持私家服务器对接支持阿里云规则引擎。
30、 Esp8266进阶之路第22篇: 乐鑫esp8266 SDK编程使用 IIC总线驱动 0.96寸的OLED显示屏,显示天气预报信息。
31、 Esp8266进阶之路第23篇: 当esp8266遇到 Html,该怎么内置网页控制设备,理清内置网页的实现过程,实现无需路由器手机也可以控制esp8266。
32、 Esp8266进阶之路第24篇: 细聊HmacMD5的加密方法带来的安全性,并实践在esp8266上,最大保障传输的过程的信息的安全性。
33、 Esp8266进阶之路第25篇: 如何优雅地像乐鑫原厂封装esp8266底层寄存器的逻辑思维,做成自己的静态库库文件,让第三方人使用?
34、 Esp8266进阶之路第26篇: 乐鑫esp8266 NONOS SDK 3.0编程使用 SPI 驱动基于Max7219芯片的八位数码管,显示日期信息。
35、 Esp8266进阶之路第27篇: 乐鑫esp8266芯片借助机智云平台做一个商业化的七彩RGB灯泡可调整体方案项目,炫彩夺目高大尚。
36、 Esp8266学习rtos3.0笔记第1篇: 认识esp8266 Rtos 3.0 sdk 工程结构,esp8266如何向esp-idf工程靠近的,如何自定义头文件编译?
37、 Esp8266学习rtos3.0笔记第2篇: 你要找的基本外设功能都在这里了,包括Gpio、Pwm 和 Uart 接口使用。
38、 Esp8266学习rtos3.0笔记第3篇: 一篇文章带你搞掂存储技术 NVS 的认识和使用,如何利用NVS保存整型、字符串、数组以及结构体。
39、 Esp8266学习rtos3.0笔记第4篇: 带你捋一捋市面上的微信公众号配网智能设备 esp8266 并绑定设备的过程,移植并成功实现在 esp8266 rtos3.1 sdk。
40、 Esp8266学习rtos3.0笔记第5篇: 基于乐鑫idf框架,研究出超稳定、掉线重连、解决内存泄露问题的Mqtt框架!支持esp8266和esp32!
41、 Esp8266学习rtos3.0笔记第6篇: esp8266-12模块基于rtos3.1版本ota功能远程空中升级固件,官网基础之上增加dns域名解析!


文章目录

      • 一、前言;
      • 二、整体思路;
      • 三、编写一个简单的`Html`文件;
      • 四、`esp8266`编程;
        • 4.1 配置热点模式,开启软路由!
        • 4.2 创建`tcp`服务器!
        • 4.3 对来自客户端数据的处理以及回复!
      • 五、`esp8266`的`flash`读取网页的注意要点;
      • 六、其他注意要点;


一、前言;


  • 这个月也快结束了,时间真快,我服务器知识自学依然在路途中,这几天听到热点网页配置esp8266连接路由器,那么我想这个不是很复杂,不过需要一些通讯协议的基础,以及对esp8266的SDK开发的熟悉,这几天撸了几下也就轻松弄出来了!不过我今天给大家带来的是实现的原理,我是用作于gpio口控制,也就是一盏灯的点亮点灭!当然了,你可以沿着我思路去做网页内置配网哦!

二、整体思路;


Created with Raphaël 2.2.0 确定好要展示的前端界面(越简洁越好) 编写:写一个Html界面,并根据html的表单提交内容编写业务程序! 烧录:html文件烧录到指定程序代码外的位置。 执行:上单后,读取指定位置烧录的 html 代码,之后设备发出热点,手机连接此热点,访问固定ip地址,弹出html界面; 回调:根据html界面请求的是 post 提交,对 gpio 脚做出对应的处理,并且原路返回客户端; 结束

  • 必须要知道的知识:

  • ①:以手机浏览器为例,其访问指定的ip地址,过程是怎么样的?

     我们都在用手机浏览器,很少知道他是怎么实现访问交互数据的。这里我们把esp8266作为服务器端,手机浏览器作为客户端,一般地,都是get请求,除非指定post提交,而请求的数据格式,大家可以去百度下http协议的数据格式,这里不再累赘!而请求之后,esp8266那肯定是要以http协议数据来回复内容的,这内容也就包含了gpio的管脚状态!从而实现了数据交互!

  • ②:编写好的html对应烧录的地址,应该怎么注意什么?

      这里我就不再多说html的文件怎么编写,这需要一定的前端知识。对应的烧录地址必须在代码块外的地址烧录,大家不懂哪些是代码块外的地址,可以去看看我上个月写的25q16存储芯片的分布,点我查看!,之后我们需要在代码中读取这个网页,之后发送给客户端就可以了!


三、编写一个简单的Html文件;


  • 非常簡單,我这里直接上代码:
    • 用的是post提交,不是get请求!
    • 当点击开灯,发送powerOn=1,点击关灯发送powerOn=0!
    • 注意编码是utf-8!




	esp8266内置网页单开关灯
	
		

esp8266热点内置网页单开关灯By半颗心脏

%s

开灯:
关灯:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

用电脑浏览器打开预览如下:

在这里插入图片描述


四、esp8266编程;


看标题大家都知道,这个设备esp8266是作为一个热点让客户端去主动连接,那么esp8266必须要开启热点模式,我这里让它固定一个ip地址192.168.5.1,当然了,你也可以不设置固定地址,因为默认就是192.168.4.1!开启热点之后,等待客户端连接,如果客户端有成功连接后,开启tcp服务器(其实就是web服务器第一步),这时候就是一直处于和客户端连接交互数据的状态了!

4.1 配置热点模式,开启软路由!

下面代码中的webEsp8266是设备发出的热点名字,xh12345678是密码,192, 168, 5, 1是固定自定义的ip地址,允许最大四个的客户端连接,而且分配的ip是从192, 168, 5, 100到192, 168, 5, 105;


	wifi_set_opmode(SOFTAP_MODE);
	struct softap_config *config = (struct softap_config *) zalloc(
			sizeof(struct softap_config)); // 初始化

	wifi_softap_get_config(config);
	sprintf(config->ssid, "webEsp8266");
	sprintf(config->password, "xh12345678");
	config->authmode = AUTH_WPA_WPA2_PSK;
	config->ssid_len = 0;
	config->max_connection = 4;
	wifi_softap_set_config(config); // Set ESP8266 soft-AP config
	free(config);

	struct station_info * station = wifi_softap_get_station_info();
	while (station) {
		printf("bssid : MACSTR, ip : IPSTR/n", MAC2STR(station->bssid),
				IP2STR(&station->ip));
		station = STAILQ_NEXT(station, next);
	}
	wifi_softap_free_station_info(); // Free it by calling functionss
	wifi_softap_dhcps_stop(); // disable soft-AP DHCP server

	//配置dhcp,固定esp8266的ip为 192, 168, 5, 1
	struct ip_info info;
	IP4_ADDR(&info.ip, 192, 168, 5, 1);
	IP4_ADDR(&info.gw, 192, 168, 5, 1);
	IP4_ADDR(&info.netmask, 255, 255, 255, 0);
	wifi_set_ip_info(SOFTAP_IF, &info);
	struct dhcps_lease dhcp_lease;
	IP4_ADDR(&dhcp_lease.start_ip, 192, 168, 5, 100); //分配的网段ip开始
	IP4_ADDR(&dhcp_lease.end_ip, 192, 168, 5, 105); //分配的网段ip结束
	wifi_softap_set_dhcps_lease(&dhcp_lease);
	wifi_softap_dhcps_start(); // 使能 soft-AP DHCP 服务
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
4.2 创建tcp服务器!

代码比较复杂,总的来说,先初始化socket,之后bind绑定端口号,大家都知道浏览器的默认访问的端口是80,那么这里也肯定是80,然后监听这个端口,阻塞等待消息!

	int32 listenfd;
	int32 ret = 0;
	char input[1024] = { 0 };
	char output[1024] = { 0 };
	struct sockaddr_in server_addr, remote_addr;
	int stack_counter = 0;
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = INADDR_ANY;
	server_addr.sin_len = sizeof(server_addr);
	server_addr.sin_port = htons(80);

	printf("[XHLogUtils] Task_local_server init succeed!!! 
");

	/* Create socket for incoming connections */
	do {
		listenfd = socket(AF_INET, SOCK_STREAM, 0);
		printf("[XHLogUtils] Create socket for incoming connections !!! 
");
		if (listenfd == -1) {
			printf(
					"[XHLogUtils] Create socket for incoming connections -1 !!! 
");
			vTaskDelay(1000 / portTICK_RATE_MS);
		}
	} while (listenfd == -1);

	/* Bind to the local port */
	do {
		ret = bind(listenfd, (struct sockaddr * )&server_addr,
				sizeof(server_addr));
		printf("[XHLogUtils] Create socket binding !!! 
");
		if (ret != 0) {
			printf("Create socket binding = -1 
");
			vTaskDelay(1000 / portTICK_RATE_MS);
		}
	} while (ret != 0);

	do {
		// Listen to the local connection
		ret = listen(listenfd, 4);
		printf("[XHLogUtils] Create socket listening !!! 
");
		if (ret != 0) {
			printf(
					"[XHLogUtils] Create socket listening = -1 will close!!! 
");
			vTaskDelay(1000 / portTICK_RATE_MS);
		}
	} while (ret != 0);

	int32 client_sock;
	int32 len = sizeof(struct sockaddr_in);

	for (;;) {

		printf(
				"[XHLogUtils] Task_local_server block here waiting remote connect request !!! 
");

		/*block here waiting remote connect request*/
		if ((client_sock = accept(listenfd, (struct sockaddr * )&remote_addr,
				(socklen_t * )&len)) < 0) {
			printf("[XHLogUtils] acceptting < 0...
");
			continue;
		} else {
			printf("[XHLogUtils] acceptting > 0...
");
		}
	}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
4.3 对来自客户端数据的处理以及回复!

前面已经说了,我们点击开关灯时候,是post提交数据,所以我们是先判断否为post提交,然后对里面的数据进一步剖析,我们看看客户端发来了什么内容?对比下面可以看到,在body里面数据不一样,开灯时候是powerOn=1,而关灯是powerOn=0!那么我们就从body里面数据剖析就可以啦?这岂不是很简单?

  • 开灯请求得到客户端数据:
POST /setLight HTTP/1.1
Host: 192.168.5.1
Connection: keep-alive
Content-Length: 9
Cache-Control: max-age=0
Origin: http://192.168.5.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; MI 8 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,image/sharpp,image/apng,image/tpg,*/*;q=0.8
Referer: http://192.168.5.1/setLight
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.8

powerOn=1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 关灯请求得到客户端数据:
POST /setLight HTTP/1.1
Host: 192.168.5.1
Connection: keep-alive
Content-Length: 9
Cache-Control: max-age=0
Origin: http://192.168.5.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; MI 8 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,image/sharpp,image/apng,image/tpg,*/*;q=0.8
Referer: http://192.168.5.1/setLight
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.8

powerOn=0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 对body里面数据剖析,进一步得到指定的动作执行gpio!!并回复给客户端,注意之后主动要断开tcp连接!

			//确定是post请求
			if (input[0] == 'P' && input[1] == 'O' && input[2] == 'S'
					&& input[3] == 'T') {

				//显示client 端的网络地址
				char *pBody = NULL;
				//得到body
				get_http_body(input, &pBody);
				char attribute[] = { "" };
				//截取之后保存的位置,源字符串,要截取的字符串的长度
				strncpy(attribute, pBody, strlen(pBody) - 2);
				//获取value设置数值
				char *pValue = (char *) strstr(pBody, "=");
				pValue += 1;
				if (strcmp(pValue, "0") == 0) {
					GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);
				} else {
					GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0);
				}

			}

			char *pStatus;
			if (GPIO_INPUT_GET(12) == 0x00) {
				pStatus = "智能灯的当前状态:开";
			} else {
				pStatus = "智能灯的当前状态:关";
			}

			char tempHttpHead[1024], tempHttpBody[1024];
			sprintf(tempHttpHead, httpHead, strlen(tempSaveData));
			//协议头拼接到发送的变量
			sprintf(sendstr, tempHttpHead);
		    //设置结束符
			tempSaveData[594] = 0;
			//协议body拼接到发送的变量
			sprintf(tempHttpBody, tempSaveData, pStatus);
			//拼接到发送全部消息
			strcat(sendstr, tempHttpBody);
			
			write(client_sock, sendstr, strlen(sendstr));

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

五、esp8266的flash读取网页的注意要点;


  • 在我之前说到的是先通过工具把html网页烧录到flash芯片,我这里使用的是25q32,可用的空间会比较大,我这里就烧录到0x1F4000,计算之后是哪个扇区呢?大家可以算下,0x1F4000换算十进制就是‭2048000‬,一个扇区是4096 bytes,而‭2048000 / 4096 = 500 ‬ ,也就是第 500 个扇区了!于是我们代码这样读取:
    //500*4096 相当于  0x1F4000 ,也就是 0x1F4 * 4096
	spi_flash_read(500 * 4096, (uint32 *) &tempSaveData, sizeof(tempSaveData));
	printf("get Html Content:  %s 
", tempSaveData);

  • 1
  • 2
  • 3
  • 4

  • 在拿到了网页信息之后,要自己设置字符串内容的结束符,这就需要我们的Html文件有多大?注意:我们要的是显示全部内容下的时候才拿到这个Html文件大小,注意我们上面的是格式符%s,取出来的当然会小很多!
           //设置结束符
			tempSaveData[594] = 0;
  • 1
  • 2

在这里插入图片描述


六、其他注意要点;


  • 上面注意这个文件大小,再来设置结束符!如果设置不对,设置过多或过少,会影响显示效果哦!切记切记!
  • 下面是烧录固件和Html文件的烧录截图!

在这里插入图片描述

  • 下面是客户端手机浏览器截图!

在这里插入图片描述


  • 后记:在群里的小伙伴提到,博文提到的第500个扇区是非安全区域存储地址,对于4M flash安全的起始扇区是 508 即 0x1FC,计算方法就是2M以外的部分,也就是(1024+1024+4)/4096=508 ,其中 4 是指reserved 部分,详情自己阅读官方的代码块分布!*所以,大家的项目中请到此外的区域读写,当然了,本硬件博文只是示范,大家修改下即可!

  • 固件下载,非源码:https://download.csdn.net/download/xh870189248/10753770
  • 下载源码,付费的哦!不喜勿喷勿点击: http://www.demodashi.com/demo/14321.html
  • 玩转esp8266带你飞、加群付费QQ群,不喜的朋友勿喷勿加:434878850
  • esp8266源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp8266
  • esp32源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp32
注:本文转载自blog.csdn.net的半颗心脏的文章"https://blog.csdn.net/xh870189248/article/details/83543997"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top