ESP8266(mini D1)实现网络服务器Server 用到的硬件概念分析扩展 API调用总结
0x00 项目指北
要实现网络Server要利用好8266的两个功能SPIFFS合webServer,实现效果如下
一.SPIFFS闪存系统
1.什么叫SPIFFS? SPIFFS可以拆开成两部分来理解,一是SPI 二是FFS(文件系统)。 SPI 是 Serial Peripheral Interface 鉴于你是个爱学英语的小可爱,我告诉你第二个单词这么读 [pəˈrɪf(ə)rəl] “福瑞福若”,是外部设备的意思。所以SPI就是串行外设接口。
百度百科:
“SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,越来越多的芯片集成了这种通信协议,比如AT91RM9200。”
挺好奇的,查了一下啊,啥叫全双工,就是像柏油马路一样,双向同行就是全双工,单行道就是单工。
Github跟进
不够深入,我在github上查了一下,它是github上一位叫pellepl的工程师在2013年编写的一个文件系统
Introduction是这么写的:
Spiffs is a file system intended for SPI NOR flash devices on embedded targets. Spiffs is designed with following characteristics in mind:
Small (embedded) targets, sparse RAM without heap
Only big areas of data (blocks) can be erased
An erase will reset all bits in block to ones
Writing pulls one to zeroes
Zeroes can only be pulled to ones by erase
Wear leveling
意思是:
Spiffs是一个专门为基于SPI Nor flash储存架构的嵌入式设备开发的文件系统。
SPIFFS被设计用于以下几种特点:
1.用于小型嵌入式设备,不需要堆(heap)
2.只有大范围的数据块才能被擦除
3.擦除数据将把block位全部置1
4.写的操作会把1变成0
5.0只能被擦除成
6.损耗均衡
同时他也介绍了Features特性:
FEATURES
What spiffs does:
Specifically designed for low ram usage
Uses statically sized ram buffers, independent of number of files
Posix-like api: open, close, read, write, seek, stat, etc
It can run on any NOR flash, not only SPI flash - theoretically also on embedded flash of a microprocessor
Multiple spiffs configurations can run on same target - and even on same SPI flash device
Implements static wear leveling
Built in file system consistency checks
Highly configurable
What spiffs does not:
Presently, spiffs does not support directories. It produces a flat structure. Creating a file with path tmp/myfile.txt will create a file called tmp/myfile.txt instead of a myfile.txt under directory tmp.
It is not a realtime stack. One write operation might last much longer than another.
Poor scalability. Spiffs is intended for small memory devices - the normal sizes for SPI flashes. Going beyond ~128Mbyte is probably a bad idea. This is a side effect of the design goal to use as little ram as possible.
Presently, it does not detect or handle bad blocks.
One configuration, one binary. There's no generic spiffs binary that handles all types of configurations.
意思是:
spiffs能干什么?
1.专门为小ram(小运存)使用而设计
2.使用静态大小的ram缓冲区,与文件大小无关
3.POSIX(Portable Operating System Interface,统一UNIX-like 的OS对外的接口)提供操作系统接口,如打开,关闭,读,写,查找,统计,等。
4.可以在任何NOR闪存运行,不仅仅是SPI flash理论上也可以在微处理器上运行
5.多个SPIFFS配置可以在相同目标上运行,甚至可以在相同SPI flash闪存设备上运行
6.flash寿命维护
7.内置文件系统一致性检查
8.高度可配置
SPIFFS不能做什么:
1、目前,spiffs不支持目录。它产生一个平面结构。使用路径tmp/myfile.txt创建文件将创建一个名为tmp/myfile.txt的文件,而不是在tmp目录下创建一个名为myfile.txt的文件。
2、它不是一个实时堆栈。一个写操作的持续时间可能比另一个长得多。
3、可怜的可伸缩性。Spiffs适用于小型内存设备——SPI flash的正常大小。超过~128Mbyte就不推荐了。由于设计目标是用尽可能少的ram,所以这是设计目标的一个副作用。
4、目前,它不能检测或处理坏块。
5、一个配置,一个二进制。没有通用的spiffs二进制可以处理所有类型的配置。
关于SPI Nor flash架构:由存储单元,行列控制单元,接口转换单元组成
总结:
所以,简单来说,这是一个简易的文件系统,可以面向任何闪存。最初考虑到大部分处理器的RAM资源有限,于是使用少量RAM设计了这样一个文件系统。同时,由于用的RAM比较少,导致它不能处理大于128MB的flash。
扁平化结构,不支持目录。举例,在电脑中,假设我在C盘某路径有一个文件:C:\flexIm\hello.txt,而使用SPIFFS的话,只能创建一个名字为C:\flexIm\hello的txt格式的文件。它还有一个优点,就是考虑到了flash的寿命问题,因此做了算法均匀使用flash中的每一个block。
二.WebServer
webServer就是ESP8266WebServer库及相关功能组成的
0x01 SPIFFS API
<FS.h> 文件操作很重要,对于web来说,访问资源调用SPIFFS是必须的!
基本操作(含文件)
SPIFFS.format() |
格式化SPIFFS |
|
Bool |
SPIFFS.begin() |
启动SPIFFS |
File |
SPIFFS.open(file_name,"w") |
打开文件并执行第二个参数(这里是写入) |
dataFile.println("") |
向被打开的dataFile写入信息 |
|
dataFile.close() |
文件操作结束后必须执行 |
|
SPIFFS.info((FSInfo)fs_info) |
向fs_info写入info,仍需print出具体要看哪类info,api不展示了就 |
目录操作
Bool | SPIFFS.exists(file_name) | 检查文件系统中有无此文件,有则返回True |
---|---|---|
num | dataFile.size() | 返回当前打开的文件大小 |
Dir | SPIFFS.openDIR(folder_name) | 创建目录 |
Bool | dir.next() | 检查是否有下一个文件 dir指向下一个文件,函数返回True |
Bool | SPIFFS.remove(file_name) | 删除文件 |
0x02 通过Arduino IDE向SPIFFS系统上传文件
请确保已经完成了以下准备工作qwq:
将NodeMCU开发板与电脑通过USB数据线连接好
NodeMCU开发板驱动已经安装完毕
设置Arduino IDE以使其支持NodeMCU开发板
一.下载Arduino-ESP8266闪存文件插件程序
通过这个链接进行下载 https://github.com/esp8266/arduino-esp8266fs-plugin/releases
二.确定项目文件夹位置并粘贴文件
通过 ArduinoIDE ---> 文件 ---> 首选项 --->项目文件夹位置 在项目位置建立新文件夹"tools"然后把下载好的文件解压,直接丢过去 然后重新启动ArduinoIDE 如何确定安装成功了呢? 在工具 ---> 若有ESP8266 Sketch Data upload 则安装完毕了 上传 然后在项目文件夹下创建data文件夹,将文件直接拖进去就好
0x03 Connection API
<ESP8266WiFiMulti.h>
AP Mode:
AP麻,就是 Access Point 由自身成为WiFi,使别的设备可以连接
WiFi.softAP(ssid,password) | 启动ap模式,ssid是wifi名字 |
---|---|
WiFi.softAPIP() | 获得NodeMCU的内网地址 |
Station Mode:
即无线终端模式,纯粹的wifi收发
WiFi.status() | 获取当前wifi连接状态 |
---|---|
WL_CONNECTED |
Auto Multi Connection:
机智的你会发现,一次只能链接一个wifi有点不太符合我们的日常使用逻辑,所以我们希望能够在一个库中保存许多wifi,然后自动选取信号最强的或者可以建立有效链接的进行connect,于是我们用到了ESP8266WiFiMutil.h这个库。 所以,这个库只适用于AP mode哦!
对象 |
ESP8266WiFiMulti wifiMulti |
建立ESP8266WiFiMulti对象 然后可以使用对象的众多方法来实现功能 |
wifiMulti.addAP("ssid"."passwd") |
给链接库里面添加wifi |
|
bool |
wifiMulti.run() |
搜索当前链接库信号最强的wifi 连接成功则返回WL_CONNECTED |
while (wifiMulti.run() != WL_CONNECTED) { // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前注意哦!!!为了实现在连接前持续搜索的效果,我们需要持续循环判断wifi是否链接,比如可以这样子写
delay(1000); // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCUSerial.print('.'); // 将会连接信号最强的那一个WiFi信号。}
others:
<ESP8266WiFi.h>
WiFi.mode(mode) | 调整ESP8266工作模式为无线终端模式(如WIFI_STA) |
---|---|
WiFi.begin(ssid,password) | 开始链接wifi |
WiFi.SSID() | AP mode下查看当前连接的wifi名称 |
WiFi.localIP() | 查看NodeMCU当前的IP地址 |
0x04 Server API
<ESP8266WebServer>
对象 |
ESP8266WebServer esp8266_server(port) |
建立webServer对象 参数为打开的端口 根据协议标准,一般打开80端口 |
esp8266_server.begin(); |
让ESP8266-NodeMCU来启动网络服务功能 |
|
esp8266_server.on("pos",func); |
指挥NodeMCU来如何处理浏览器的http请求,pos是访问位置('/'代表首页),func是访问对应页面执行函数 |
|
esp8266_server.onNotFound(func) |
若无此页面则调用func处理404访问 |
|
esp8266_server.handleClient(); |
检查有没有设备通过网络向NodeMCU发送请求 (因此我们需要把它放在loop函数中,从而确保它能经常被调用。假如我们的loop函数里有类似delay一类的函数延迟程序运行,那么这时候就一定要注意了,如果handleClient函数长时间得不到调用,NodeMCU的网络服务会变得很不稳定。因此在使用NodeMCU执行网络服务功能的时候,一定要确保handleClient函数经常得以调用。我在这里反复强调这一点是因为这一点非常关键,请务必注意!) |
|
esp8266_server.send(index,"type","text") |
生成并且发送http响应信息,param1:状态码,param2:说明http响应体信息类型,parma3:具体内容(最好放在具体esp8266_Server.on对应执行函数里面,来实现“响应头”的效果) |
|
esp8266_server.sendHeader(headerName, headerValue, first); |
用于向响应头信息中添加自定义键值对。 parma1:自定义响应头的名称,可以使用字符串类型 parma2:自定义响应头的值,可使用字符串类型 parma3:设置该响应头是否需要放在第一行,缺省则为false(参数为bool) |
|
esp8266_server.send(index) |
向浏览器发送状态码 |
content-type要注意哦!!! 1.实现持续处理Client的访问响应,需要将handleClient放在loop函数中运行 而begin和on等配置型函数,在setup中使用。 2.!!!!.send函数很重要,尤其是TYPE!!!因为不同type代表了告诉client怎么处理网络字节流
常见格式如下:
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
application开头的媒体类型:
application/xhtml+xml :XHTML格式
application/xml: XML数据格式
application/atom+xml :Atom XML聚合格式
application/json: JSON数据格式
application/pdf:pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType="">中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
更多API如下:
0x05 Client API
其实这个项目是不需要用到Client API哒!刚好学到这里了,就大概见一下吧! 如果不想了解可以直接跳过 你可能会疑惑,我8266是Server为啥要Client API呢,因为我8266不光可以作为Server,还可以作为Client,类似浏览器干的事情,主动去访问一个别的Server,并解析他的响应。
ESP8266HTTPClient库
特征:简单易用,但是不灵活,封装好了底层内容,不够自由
HTTPClient httpClient |
要声明HTTPClient类型对象才能操作哦!!! |
|
httpClient.begin(URL,[port]); |
begin函数来配置请求地址,param2为默认80 |
|
int |
httpClient.GET() |
通过get函数启动链接并发送http请求 返回状态码 |
int |
httpClient.POST(payload,[size]) |
此函数用于ESP8266使用HTTP协议通过Server向服务器发送请求 parma1:通过post请求发送的数据信息,可使用字符串 parma2:通过post请求发送字节数(size_t) |
Sting |
httpClient.getString() |
getString函数获得服务器响应体内容 |
httpClient.end() |
关闭esp8266与服务器的链接 此函数来清除ESP8266的接收缓存以便设备再次接收服务器发来的响应信息。 |
void httpClientRequest(){}注意!!!! 发送HTTP请求并将服务器响应通过串口输出最好用一个函数来写,且函数必须写在loop里面,然后再setup函数启用时调用!!!
WiFiClient库
bool | client.connect(host, httpport) | 与Server连接,host是网址httpport是端口号 Success则True | |
---|---|---|---|
bool | client.connected() | 检查当前服务器的连接情况 Connected则True | |
bool | client.available() | 检查Server是否发来信息 有则True | 注意,最好写两层abaliable函数,服务器响应有延迟 |
String | client.readStringUntil('\n') | 将服务器响应信息逐行分解为字符串 | |
client.print(request) | 向Server发送封装好的请求,request是String串 |
同上一个库发送HTTP请求并将服务器响应通过串口输出最好用一个函数来写,且函数必须写在loop里面,然后再setup函数启用时调用!!!void httpClientRequest(){}
readStringUntil函数的实现利用了Stream 数据流概念,下面我们一起探索一下Stream
Stream & Stream API
直白来讲,就是一列有先后顺序的数据
bool | Serial.avilable() | 判断开发板是否收到数据 | 一般在loop函数下写相关功能的实现!! |
---|---|---|---|
Serial.println() | 将Stream串口数据输出在串口监视器中 |
还有很多api,暂不赘述啦!
0x06 最后几步
相信到这里,你已经利用插件在SPIFFS上传好了html文件,最后我们要做的就是将SPIFFS文件读取与webServer.on函数练习起来,我们都知道,每一个url都是一个资源,当我们在web标签调用图片之类的资源,也相当于发了一次request和response,所以我们需要给每一个url设置.on函数......确实有点麻烦。那么上代码吧。
#include <ESP8266WiFi.h> // 本程序使用ESP8266WiFi库
#include <ESP8266WebServer.h> // ESP8266WebServer库
#include <FS.h>
ESP8266WebServer Server(80);
const char *ssid = "LiuJiahuan Test Web Server"; // 这里定义将要建立的WiFi名称。此处以""为示例// 您可以将自己想要建立的WiFi名称填写入此处的双引号中const char *password = "12345678"; // 这里定义将要建立的WiFi密码。此处以12345678为示例// 您可以将自己想要使用的WiFi密码放入引号内// 如果建立的WiFi不要密码,则在双引号内不要填入任何信息void setup() {Serial.begin(9600); // 启动串口通讯if(SPIFFS.begin()){ // 启动闪存文件系统Serial.println("SPIFFS Started.");} else {Serial.println("SPIFFS Failed to Start.");}WiFi.softAP(ssid, password); // 此语句是重点。WiFi.softAP用于启动NodeMCU的AP模式。// 括号中有两个参数,ssid是WiFi名。password是WiFi密码。// 这两个参数具体内容在setup函数之前的位置进行定义。Serial.print("Access Point: "); // 通过串口监视器输出信息Serial.println(ssid); // 告知用户NodeMCU所建立的WiFi名Serial.print("IP address: "); // 以及NodeMCU的IP地址Serial.println(WiFi.softAPIP()); // 通过调用WiFi.softAPIP()可以得到NodeMCU的IP地址Server.begin();Server.on("/",handleRoot);Server.on("/test.jpeg", handlePhoto);
}void loop() { Server.handleClient();
}
void handleRoot() { //处理网站根目录“/”的访问请求 File dataFile = SPIFFS.open("/index.html", "r"); String rp;for(int i = 0; i < dataFile.size(); i++){rp += (char)dataFile.read(); }Server.send(200, "text/html", rp); dataFile.close();
}
void handlePhoto(){File dataFile = SPIFFS.open("/test.jpeg", "r");String pt;for(int i = 0; i < dataFile.size(); i++){pt += (char)dataFile.read(); }Server.send(200, "image/jpeg", pt); dataFile.close();
}
我给SPIFFS放了个index.html和test.jpeg 非常easy的小demo!!!给你们宿舍也做个小网站吧hhhhhh!!!做内网穿透以后更好玩了
ESP8266(mini D1)实现网络服务器Server 用到的硬件概念分析扩展 API调用总结相关推荐
- 树莓派4b+esp8266 mini D1 制作AWTRIX网红个性时钟~
BOM表: | 名称 |型号 |–|–|–| | 树莓派 | Raspberry Pi 4B | ESP-12F| mini D1 | ws2812灯| 8x32像素屏 | 电源模块| 3.3V 5V ...
- ESP8266连接STM32创建网络服务器
如果您考虑未来的技术,那么您脑海中立即出现的两个名称是人工智能(AI)和物联网(IoT). AI仍处于初始阶段,还有很多东西需要开发.但物联网正处于成长阶段,许多基于物联网的产品 已经在市场上销售.此 ...
- 网络服务器性能常见问题,服务器在使用过程中常见的误区有哪些?
服务器是企业的必需资源,但是如何确保所购置或租赁的服务器能够持续高效.稳定地工作和运行,是企业最关心的问题之一.在日常操作中,对服务器配置不当,以及一些常见的使用误区,都有可能导致服务器没有工作在最佳 ...
- micropython做中继_MicroPython网络服务器使用ESP32/ESP8266远程控制家用交流电器
背景知识视频教程 将继电器与ESP32或ESP8266配合使用是一种远程控制AC家用电器的好方法.本教程介绍了如何使用MicroPython固件通过ESP32或ESP8266控制继电器模块. 我们将研 ...
- ESP8266 网络服务器仪表显示传感器读数
了解如何使用 ESP8266 NodeMCU 构建网络服务器以在仪表中显示传感器读数. 例如,我们将以两种不同的仪表显示来自 BME280 传感器的温度和湿度:线性和径向. 概述 该项目将使用 ESP ...
- ESP8266 NodeMCU:ESP-NOW Web 服务器传感器仪表板(ESP-NOW + Wi-Fi)
在本项目中,您将学习如何使用 ESP8266 NodeMCU 板托管 Web 服务器并同时使用 ESP-NOW 通信协议.您可以让多个 ESP8266 板通过 ESP-NOW 将传感器读数发送到一个 ...
- STM32+ESP8266连接电脑Qt网络上位机——QT篇
本文简单介绍下手写网络调试器并连接ESP8266模块 上篇: STM32+ESP8266连接电脑Qt网络上位机--准备工作 目录 一.部分Qt代码及实现过程 二.实现过程--使用ESP8266连接上 ...
- ESP8266--Arduino开发(搭建HTTP网络服务器)
文章目录 一.前言 二.搭建HTTP网络服务器 三.添加一个简单网页进行交互 四.ESP8266WebServer库 4.1.WebServer管理方法 1.创建Web Server 2.启动Web ...
- Linux下各类TCP网络服务器的实现源代码
http://www.linuxeden.com/forum/t146870.html 大家都知道各类网络服务器程序的编写步骤,并且都知道网络服务器就两大类:循环服务和并发服务.这里附上源代码来个小结 ...
最新文章
- 神经网络基础知识总结
- ASP.NET (C#开发环境)Request对象 之 ServerVariables集合
- python以运行效率高著称吗_提升Python程序运行效率的6个方法
- Python的Pexpect库
- SublimeText3 初探(工欲善其事,必先利其器)
- java 网络编程学习笔记
- linux下的进程间通信-管道及共享内存
- curry化 js_前端发动机从 bind 聊到 curry (柯里化)
- 织梦linux php版本,Linux下安装DedeCMS及安全设置
- 小数乘分数怎么算过程_教资分数怎么算?多少分合格?
- Linux基础命令---显示文本grep
- 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第2节 TCP协议_2_TCP通信的概述(下)...
- Python+Appium自动化搭建新手教程
- [SCU 4507] 奶牛情书 (AC自动机)
- 用pe修改计算机ip地址,解决win7电脑禁止更改ip地址的具体步骤
- Excel如何导出高清图片
- 一文搞定基因型数据清洗
- 高薪职业,英年早秃?关于程序员,多的是你不知道的事……
- 心理正常与异常的区分_判断心理正常异常三原则
- 个人支付方案(免签约)-支付宝当面付
热门文章
- 掀开高级游戏黑客的面纱,教你打造游戏修改器
- PTAJava实验六
- java 不要使用魔法值_可别在代码中写那么多魔法值了,脑壳疼!
- 【iOS开发-动画】iOS开发动画实现合集
- XFX讯景GTX295(GX-295N-HHFF)
- 分布式图计算系统与算法简单文献综述
- 4.1 拦截电话号码
- xp/win7 win32k kernel 0day
- docker修炼手册
- javaweb项目,配置servlet后报错:java.lang.ClassCastException: cannot be cast to class javax.servlet.Servlet