Arduino 入门学习笔记(二十六):WIFI

06-01 1574阅读

Arduino 入门学习笔记(二十六):WIFI_WEBSERVER 实验

开发板:正点原子ESP32S3

没有LCD屏可以用串口打印进行测试

例程源码在文章顶部可免费下载

1. 网络基础知识和 WEBSERVER 函数介绍

1.1 互联网络和 TCP/IP 协议

在世界各地,各种各样的计算机运行着不同的操作系统为大家服务,这些计算机在表达同一种信息时使用的方法也是千差万别,就好像语言不通会为人们合作带来障碍一样,计算机使用者意识到,使用单台计算机并不能发挥太大的作用,只有把它们连接起来,才能发挥出计算机的巨大潜力。于是人们就想法设法用线路将计算机连接到一起,这就构成了互联网络,也就是常说的 Internet。

通过线路简单将计算机连接到一起是远远不够的,就好像语言不通的两个人见了面,不能完全交流信息,因此需要定义一些共同的规则以方便交流, TCP/IP 就是为此而生的。 TCP/IP 是一个协议家族的统称,除了包含了 IP 协议、 TCP 协议,及我们比较熟悉的 HTTP、 FTP、 POP3协议等。计算机有了这些协议,就好像学会了外语,就可以和其他的计算机进行信息传输和数据交流了。

TCP/IP 协议家族的协议成员是分层次的,我们称之为 TCP/IP 模式,共分为 4 层,从底向上依次是网络接口层、网络层、传输层和应用层,如下图所示:

Arduino 入门学习笔记(二十六):WIFI

1.2 IP 地址

IP 地址指互联网协议地址(Internet Protocol Address),是 IP 协议提供的一种统一地址格式,它为互联网上每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽各种不同类型计算机物理地址的差异。

举个例子,如果要写信给一个人,那就要知道他的地址,这样邮寄员才能将信件送到。 IP地址相当于计算机在网络上的“门牌号”,只有通过 IP 地址才能找到对方的计算机或服务器,如下图所示:

Arduino 入门学习笔记(二十六):WIFI

IP 地址的定义不止一个版本,目前的主流版本为 IPv4。 IPv4 地址的长度为 32 位,分为 4段,每段 8 位,用十进制数字表示,每段数字范围为 0 ~ 255,段与段之间用句点隔开,如202.102.10.1。可见, IPv4 共有 232 个,接近 43 亿个 IP 地址。在互联网发展的初期这似乎是个很大的数量,但随着互联网的发展,尤其移动互联网的发展,越来越多的服务器和终端(包括手机)连入互联网,即使只满足全球 70 亿人口的手机联网, IP 地址数量就已经不够使用了,更何况现在是物联网时代,万物互联,各种各样的传感器都会联网,此时连入互联网的终端数量将比人口数量至少高 1000 倍。为了满足这种需求,国际标准阻值又提出了 IPv6 标准, IPv6 的地址长度为 128 位,其地址数量号称“可以为全世界的每一粒沙子拥有一个 IP 地址”,足以支撑未来相当长时间的发展需要。目前, IPv4 正在向 IPv6 应用的过渡过程中。

如果你的计算机通过路由器连接到互联网,那么路由器会分配一个 IP 地址给计算机。单击快捷键“win+R”,在弹出对话框的文本框中输入 cmd 命令后回车,则可以打开 Windows 命令行界面。在提示符下,输入 ipconfig 命令可以查看当前计算机的 IP 配置,如下图所示:

Arduino 入门学习笔记(二十六):WIFI

1.3 端口号

我们知道,一台拥有 IP 地址的主机可以提供许多服务,比如网页浏览服务、文件传送服务、邮件服务等,那么,主机如何区分不同的网络服务呢?显然不能只靠 IP 地址,因为 IP 地址与网络服务的关系是一对多的关系,现实中是通过“IP 地址+端口号”来区分不同的服务。常用端口号(Port)对应的应用列表如下表所示:

Arduino 入门学习笔记(二十六):WIFI

便于理解“IP 地址+端口号”来区分不同服务,可以把一个 IP 地址看作一个医院,医院有内科、外科、牙科、皮肤科等科室。挂号时,会根据你的症状安排到不同的科室进行医治,这些科室就和端口号类似,不同的端口号就对应着不同的网络服务(Web 服务、 FTP 服务等)。

1.4 客户端-服务器模式

互联网络把计算机连起来的目的主要是向计算机提供信息服务,互联的计算机通常可分为两类:一类是信息服务的请求者(Requestor),被称为客户端(Client);另外一类是信息服务的响应者(Responsor),被称为服务器(Server)。这种主要由客户端和服务器组成的网络架构称为客户端-服务器模式(简称 C/S 模式),如下图所示:

Arduino 入门学习笔记(二十六):WIFI

在计算机的浏览器输入 www.baidu.com 访问网站,此时计算机上的浏览器就是客户端,而百度网站的计算机和数据库则是服务器。当网页浏览器向百度发送一个查询请求时,百度服务器从百度的数据库中找出该请求所对应的信息,组成一个网页,再发送回浏览器。

1.5 HTTP 协议

协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则。

HTTP 协议是 Hyper Text Transfer Protocol (超文本传输协议)的缩写,是从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。超文本是指用超链接的方法将各种不同空间的文字信息组织在一起而形成的网状文本。这里的文字信息包含文字、图片、音频、视频、文件等数据。

HTTP 协议是基于客户端/服务端(C/S)的架构模型。

HTTP 客户端一般是一个应用程序(比如 Web 浏览器),通过连接到服务器达到向服务器发送方一个或多个 HTTP 的请求的目的。

HTTP 服务器同样也是一个应用程序,通过是一个 Web 服务器程序,如微软 IIS 服务器,服务器通过接收客户端的请求并向客户端发送 HTTP 响应数据。

HTTP 的访问由客户端发起,通过一种叫统一资源定位符(URL: Uniform Resource Locator,比如 www.baidu.com/duty)的标识来找到服务器,建立连接并传输数据。

HTTP 默认端口号为 80。

1.6 ESP32-S3 Web 服务器

HTTP 服务器也称为 Web 服务器,用于接收客户端 HTTP 请求消息并回复响应消息,是一个运行在硬件服务器的软件。

HTTP 服务器也称为 Web 服务器,用于接收客户端 HTTP 请求消息并回复响应消息,是一个运行在硬件服务器的软件。

客户端与 Web 服务器通过 HTTP 协议进行交互,如下图所示:

Arduino 入门学习笔记(二十六):WIFI

1.7 URL 和域名、 IP 之间的关系

http://www.baidu.com/duty/是 URL; www.baidu.com 就是域名; 183.2.172.42 就是 IP 地址。在计算机的浏览器输入 http://www.baidu.com/duty/( URL),其中, http 为传输协议;www.baidu.com 为域名,计算机会通过域名解析系统( DNS: Domain name resolution),把www.baidu.com(域名)解析成 183.2.172.42(IP 地址),然后和 183.2.172.42 建立连接,并告诉183.2.172.42:“我要看/duty(资源路径下)网页的内容”。

之所以在 IP 地址之外还引入域名,主要是为了帮助记忆, IP 地址作为一个抽象的数字不太容易记住,而 www.baidu.com 则更容易记住多了。

1.8 ESP32-S3 WEBSERVER 介绍

本实验, 开发板为 Web 服务器。 实现 Web 服务器主要依赖 WIFISTA 和 WIFISERVER 库。

Arduino 入门学习笔记(二十六):WIFI

Arduino 入门学习笔记(二十六):WIFI

本小节介绍到的函数可在以下文件中找到:

C:\Users\ 用户名 \Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\WiFi\src\WiFiSTA.cpp

C:\Users\ 用户名 \Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\WiFi\src\WiFiServer.cpp

接下来,我们介绍一下本实验所用到的 WEBSERVER 相关函数。

第一个函数: begin 函数,该函数功能是启动 ESP32-S3 的工作模式。

Wl_status_t WiFiSTAClass::begin(char* ssid, char* passphrase, int32_t channel,const uint8_t* bssid, bool connect)

参数 ssid 为要连接的 WiFi 名称;

参数 passphrase 为要连接的 WiFi 密码;

参数 channel 为连接的 WiFi 接入点信道,属于可选参数;

参数 bssid 为连接 WiFi 接入点的 mac 地址,属于可选参数;

参数 connect 为是否连接该 WiFi,属于可选参数;

返回值: wl_status_t 类型。 WL_IDLE_STATUS(0)表示 WIFI 模块处于空闲状态,没有与任何网络连接; WL_NO_SSID_AVAIL(1)表示找不到指定的 WiFi 网络或者附近没有可用的WiFi 网络; WL_SCAN_COMPLETED(2)表示 WiFi 扫描已完成,但尚未连接到任何网络。WL_CONNECTED(3)表示 WiFi 连接成功; WL_CONNECT_FAILED(4) 表示 WiFi 连接失败, WL_CONNECTION_LOST(5)表示 WiFi 连接丢失; WL_DISCONNECTED(6)表示 WiFi未连接。

第二个函数: status 函数,该函数功能是返回联网状态。

Wl_status_t WiFiSTAClass::status()

无参数;

返回值: wl_status_t 类型。 具体返回值含义查看上一函数返回值说明。

第三个函数: localIP 函数,该函数功能是获取当前 ESP32-S3 的 IP 地址。

IPAddress WiFiSTAClass::localIP()

无参数;

返回值为 IPAddress 类型,即当前 WiFi 终端分配的 IP 地址。

第四个函数: begin 函数,该函数不同于第一个函数,本函数的功能是用于启动 ESP32-S3所建立的物联网网络服务器。

void WiFiServer::begin(uint16_t port)

参数 port 为服务器使用的端口号;

无返回值。

第五个函数: available 函数,本函数的功能是侦听是否有 Client 接入。

WiFiClient WiFiServer::available()

无参数;

返回值为接入网络的 WiFiClient 对象。

第六个函数: connected 函数,本函数的功能是判断 Client 是否成功连接服务器。

uint8_t WiFiClient::connected()

无参数;

返回值为 int 类型, 0 表示连接失败, 1 表示连接成功。

第七个函数: available 函数,本函数的功能是客户端接收缓冲区中的字节数。

int WiFiClient::available()

无参数;

返回值为 int 类型,返回缓冲区中的字节数。

第八个函数: read 函数,本函数的功能是从客户端接收缓冲区中读取数据。

int WiFiClient::read()

无参数;

返回值为缓冲区第一个字节数据。

第九个函数: stop 函数,本函数的功能是客户端断开连接。

void WiFiClient::stop()

无参数;

无返回值。

2. HTML 基础

HTML(Hyper Text Markup Language),即超文本标记语言,是用于创建网页的主要标记语言。浏览网页时,每一个网页对应一个 HTML 文档。 Web 浏览器是为了解释 HTML 文件而生的, HTML 文件中的标签告诉 Web 浏览器如何在页面上显示内容。 HTML 文档的后缀为.html或者.htm,这两种后缀都一样,没有区别。

本节将通过编写简单的 HTML 文档来了解 HTML 文档的基本结构。

HTML 文档是纯文本格式,可以使用电脑自带的记事本来编辑 HTML 文档,当然也可以使用 VScode 或者 notepad++等等。 此外,微软的 FrontPage 和 Adobe 公司的 Dreamweaver,是“所见即所得”的可视化网页制作软件,可自行选择。

2.1 HTML 文档基本结构

HTML 文档的基本结构如下图所示:

Arduino 入门学习笔记(二十六):WIFI

上图中,不同的“”及其包围的关键词称为 HTML 标记标签,简称为 HTML 标签,如、 、 、 等。需要注意:绝大多数标签成对出现。

我们手动输入的内容称为文本,文本和 HTML 标签构成了 HTML 文档。在 HTML 文件中,使用“”这个格式作为注释。

HTML 文档的基本结构总结如下:

HTML 文档由 HTML 标签以及文本内容组成。

HTML 标签是由尖括号及包围的关键词组成,比如、 等。

HTML 标签通常是成对出现的,比如

,标签对中的第一个标签是开始标签,第二个标签是结束标签。结束标签比开始标签多一个斜杠“/”。

为注释标签,用于在 HTML 插入注释。

标签标识网页的开始和结尾,网页的结构基于两者之间。

HTML 文档分为两个主要部分:头部和主体。 和标记头部, 和标记主体。头部包含有关 HTML 文档的属性数据,这些数据对最终用户不可见,但会向网页添加标题、脚本、样式甚至更多,这称为元数据。主体是包括类似文本、按钮、表格等页面内容。

基于文档的基本结构,写了一个简单的页面,代码如下:

 
 
	ATK ESP32-S3 Web Server
 
 
	

ESP32-S3 Web Server

LED State

ON

OFF

网页显示效果如下图所示:

Arduino 入门学习笔记(二十六):WIFI

2.2 HTML 标签

常用的 HTML 标签如下表所示:

Arduino 入门学习笔记(二十六):WIFI

3. 硬件设计

3.1 例程功能

程序下载完成, ESP32-S3 尝试连接程序设定的 WIFI 网络,连接上后 LCD 显示 ESP32-S3的 IP。终端浏览器(计算机、手机)也要接入一样的 WIFI 网络,在浏览器中输入 ESP32-S3 的IP 地址,访问 ESP32-S3 Web 服务器。单击 Web 网页上的按钮,以无线的方式打开或关闭 ESP32-S3 板载的 LED 灯。

3.2 硬件资源

  • LED 灯

    LED-IO1

  • USART0

    U0TXD-IO43

    U0RXD-IO44

  • XL9555

    IIC_SDA-IO41

    IIC_SCL-IO42

  • SPILCD

    CS-IO21

    SCK-IO12

    SDA-IO11

    DC-IO40(在 P5 端口,使用跳线帽将 IO_SET 和 LCD_DC 相连)

    PWR- IO1_3(XL9555)

    RST- IO1_2(XL9555)

  • ESP32-S3 内部 WiFi

    3.3 原理图

    本实验使用的 WiFi 为 ESP32-S3 的片上资源,因此并没有相应的连接原理图。

    4. 软件设计

    4.1 程序流程图

    下面看看本实验的程序流程图:

    Arduino 入门学习笔记(二十六):WIFI

    4.2 程序解析

    02_wifi_webserver.ino 代码

    在 02_wifi_webserver.ino 里面编写如下代码:

    需要连接的WIFI名称和密码需要根据自己的热点进行相应的修改

    #include "led.h"
    #include "uart.h"
    #include "xl9555.h"
    #include "spilcd.h"
    #include "WiFi.h"
    char* ssid = "ALIENTEK-YF"; /* 要连接网络名称 */
    char* password = "15902020353"; /* 要连接网络密码 */
    WiFiServer server(80); /* 定义 Web 服务器对象实例,端口默认为 80 */
    WiFiClient client; /* 定义客户端对象 */
    void webpage_display(void); /* 网页显示内容 */
    /**
    * @brief 当程序开始执行时,将调用 setup()函数,通常用来初始化变量、函数等
    * @param 无
    * @retval 无
    */
    void setup()
    {
    	uint16_t i = 0;
    	char ip_buf[20];
    	led_init(); /* LED 初始化 */
    	uart_init(0, 115200); /* 串口 0 初始化 */
    	xl9555_init(); /* IO 扩展芯片初始化 */
    	lcd_init(); /* LCD 初始化 */
    	lcd_show_string(30, 50, 200, 16, LCD_FONT_16, "ESP32-S3", RED);
    	lcd_show_string(30, 70, 200, 16, LCD_FONT_16, "WIFI WEBSERVER TEST", RED);
    	lcd_show_string(30, 90, 200, 16, LCD_FONT_16, "ATOM@ALIENTEK", RED);
    	WiFi.begin(ssid, password); /* 连接网络 */
    	lcd_show_string(30, 110, 200, 16, LCD_FONT_16, "WIFI_NAME:", RED);
    	/* 显示要连接 wifi 的名字 */
    	lcd_show_string(118, 110, 200, 16, LCD_FONT_16, ssid, BLUE);
    	while (WiFi.status() != WL_CONNECTED) /* 等待网络连接成功 */
    	{
    		delay(500);
    		lcd_show_char(30 + 8 * i, 130, '.', LCD_FONT_16, 1, BLUE);
    		i++;
    	}
    	lcd_show_string(30, 130, 200, 16, LCD_FONT_16, "WiFi connected.", RED);
    	lcd_show_string(30, 150, 200, 16, LCD_FONT_16, "IP address:", RED);
    	sprintf(ip_buf, "%s", WiFi.localIP().toString().c_str());
    	/* 显示连接 wifi 后的 ip */
    	lcd_show_string(126, 150, 200, 16, LCD_FONT_16, ip_buf, BLUE);
    	server.begin(); /* 启动 ESP32 所建立的物联网网络服务器 */
    	lcd_show_string(30, 170, 200, 16, LCD_FONT_16, "Please connect.....", RED);
    	/* 等待客户端通过 web 连接 IP */
    }
    /**
    * @brief 循环函数,通常放程序的主体或者需要不断刷新的语句
    * @param 无
    * @retval 无
    */
    void loop()
    {
    	client = server.available(); /* 检测服务器端是否有活动的客户端连接 */
    	if (client) /* 有客户端连接 */
    	{
    		String currentLine = ""; /* 创建一个字符串来保存来自客户端的传入数据 */
    		while (client.connected()) /* 检查设备是否成功连接服务器 */
    		{
    			lcd_show_string(30,170,200,16,LCD_FONT_16,"Client is connected",RED);
    			if (client.available()) /* 检查网络客户端是否有接收到服务器发来的信息 */
    			{
    				char c = client.read(); /* 读取服务器发来的信息 */
    				if (c == '\n')
    				{
    					/* 如果当前行为空,则一行中有两个换行符。这是客户端 HTTP 请求的结束,所以发送一个响应: */
    					if (currentLine.length() == 0)
    					{
    					Webpage_display();
    					break;
    				} 
    				else /* 如果有一个换行符,那么清除 currentLine */
    				{
    					currentLine = "";
    				}
    			}
    			else if (c != '\r') /* 如果没有回车符 */
    			{
    				currentLine += c; /* 将它添加到 currentLine 的末尾 */
    			}
    			/* 检查客户端请求是"GET /LED_ON"还是"GET /LED_OFF" */
    			if (currentLine.endsWith("GET /LED_ON"))
    			{
    				LED(0); /* GET /LED_ON 打开灯 */
    				lcd_show_string(30, 210, 200, 16, LCD_FONT_16, "LED ON ", RED);
    			}
    			if (currentLine.endsWith("GET /LED_OFF"))
    			{
    				LED(1); /* GET /LED_OFF 关闭灯 */
    				lcd_show_string(30, 210, 200, 16, LCD_FONT_16, "LED OFF", RED);
    			}
    		}
    	}
    	client.stop(); /* 关闭连接 */
    	}
    }
    /**
    * @brief 网页数据内容
    * @param 无
    * @retval 无
    */
    void webpage_display(void)
    {
    	/* HTTP 报头总是以响应码开头(例如 HTTP/1.1 200 OK)和一个内容类型,以便客户端知道接下来
    	是什么,然后是一个空行: */
    	client.println("HTTP/1.1 200 OK");
    	client.println("Content-type:text/html"); /* 浏览器响应数据类型为文本数据 */
    	client.println();
    	client.print("");
    	client.print("");
    	client.print("");
    	client.print("ATK ESP32-S3 Web Server");
    	client.print("");
    	client.print("");
    	client.print("

    ESP32-S3 Web Server

    "); client.print("

    LED State

    "); client.print("

    \"/LED_ON\"> ON

    "); client.print("

    \"/LED_OFF\"> OFF

    "); client.print(""); client.print(""); /* HTTP 响应以另一个空行结束 */ client.println(); }

    首先定义 WiFiServer 服务器对象实例为 server,服务器端口号为 80。继续定义 WiFiClient客户端对象实例为 client,用于保存侦听登录到 server 的客户端对象。

    在 setup 函数中,调用 led_init 函数完成 LED 初始化,调用 key_init 函数完成 KEY 初始化,调用 uart_init 函数完成串口初始化,调用 xl9555_init 函数完成 XL9555 初始化,调用 lcd_init 函数完成 LCD 屏初始化, 调用 WiFi.begin 函数连接网络,最后通过 server.begin 函数启动 web 服务器。

    在 loop 函数中, 通过 server.available 函数侦听是否有客户端连接,若有连接即浏览器登录该 Web 服务器,这就相当于客户端发送给 Web 服务器的 HTTP 请求。 HTTP 请求的内容是固定格式的多行文本并以空行结束,就是 webpage_display 函数。

    5 下载验证

    程序下载成功后,我们可以看到 LCD 显示已经连接上 WiFi, 显示当前 ESP32-S3 的 IP, 如下图所示:

    Arduino 入门学习笔记(二十六):WIFI

    将移动端设备,比如手机也连接该 WiFi,然后在浏览器中输入 ESP32-S3 的 IP“192.168.2.0”回车访问网页, 需要稍等片刻, 如下图所示:

    Arduino 入门学习笔记(二十六):WIFI

    通过该网页的 ON 和 OFF 按钮可控制开发板上的 LED 灯。当我们按下 ON 按钮时, ESP32-S3 开发板上的 LED 亮起, LCD 屏显示内容如下图所示:

    Arduino 入门学习笔记(二十六):WIFI

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码