当前位置:网站首页>学习太极创客 — ESP8226 (二)
学习太极创客 — ESP8226 (二)
2022-06-11 01:48:00 【xuechanba】

该板子上有两个按键,其中 RST 是用来复位开发板的,而 FLASH 则是在开发板刷固件时需要用到的。
浅蓝色的引脚为通讯引脚,包括 I2C、SPI、UART 等。
黑底白字的引脚是用来操作它内部的存储单元的。
也就是说几个引脚一般不做普通引脚使用。

4.4、通过网页文本框控制 ESP8266 开发板的 PWM 引脚
需要注意,在PWM控制方面,Arduino 开发板的可输入的数值与 ESP8266 的不同, Arduino 只能输入 0 - 255,而 ESP8266 则可以输入 0 - 1023。但是,此处需要重点说明的是,“在 3.0 之前的版本中,默认范围为 0 - 1023”,
参考链接: https://blog.csdn.net/qq_39209508/article/details/120844466

我这里的使用的库是3.0.2版本,所以默认范围就是 0 — 255。
而要想变成 0 - 1023,也很简单,只需要在 setup 函数中添加一句代码 analogWriteRange(1023); 即可。
void setup(void){
...
...
analogWriteRange(1023);
...
}
4.4.1 通过一个网页文本框输入 PWM 数值来控制 PWM 波形
完整代码如下,
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : 3_4_3_SPIFFS_Text_PWM_Server 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20190305 程序目的/Purpose : 使用ESP8266-NodeMCU建立一个有多个页面的网站。通过LED页面 的文本输入可以控制板上LED的亮度。 ----------------------------------------------------------------------- 修订历史/Revision History 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description 20200211 CYNO朔 0.01 一致性调整 ----------------------------------------------------------------------- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/ ***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象
ESP8266WebServer esp8266_server(80);// 建立ESP8266WebServer对象,该对象用于响应HTTP请求。监听端口(80)
void setup(void){
Serial.begin(9600);
Serial.println("");
pinMode(LED_BUILTIN, OUTPUT); // 初始化NodeMCU控制板载LED引脚为OUTPUT
analogWriteRange(1023);
wifiMulti.addAP("FAST_153C80", "123456798"); // 将需要连接的一系列WiFi ID和密码输入这里
wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) {
// 尝试进行wifi连接。
delay(1000);
Serial.print(i++); Serial.print(' ');
}
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
if(SPIFFS.begin()){
// 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
//初始化网络服务器
esp8266_server.on("/LED-Control", handleLEDControl); // 告知系统如何处理/LED-Control请求
esp8266_server.onNotFound(handleUserRequest); // 处理其它网络请求
// 启动网站服务
esp8266_server.begin();
Serial.println("HTTP server started");
}
void loop(void){
esp8266_server.handleClient(); //处理网络请求
}
void handleLEDControl(){
// 从浏览器发送的信息中获取PWM控制数值(字符串格式)
String ledPwm = esp8266_server.arg("ledPwm");
// 将字符串格式的PWM控制数值转换为整数
int ledPwmVal = ledPwm.toInt();
// 实施引脚PWM设置
analogWrite(LED_BUILTIN, ledPwmVal);
// 建立基本网页信息显示当前数值以及返回链接
String httpBody = "Led PWM: " + ledPwm + "<p><a href=\"/LED.html\"><-LED Page</a></p>";
esp8266_server.send(200, "text/html", httpBody);
}
// 处理用户浏览器的HTTP访问
void handleUserRequest() {
// 获取用户请求资源(Request Resource)
String reqResource = esp8266_server.uri();
Serial.print("reqResource: ");
Serial.println(reqResource);
// 通过handleFileRead函数处处理用户请求资源
bool fileReadOK = handleFileRead(reqResource);
// 如果在SPIFFS无法找到用户访问的资源,则回复404 (Not Found)
if (!fileReadOK){
esp8266_server.send(404, "text/plain", "404 Not Found");
}
}
bool handleFileRead(String resource) {
//处理浏览器HTTP访问
if (resource.endsWith("/")) {
// 如果访问地址以"/"为结尾
resource = "/index.html"; // 则将访问地址修改为/index.html便于SPIFFS访问
}
String contentType = getContentType(resource); // 获取文件类型
if (SPIFFS.exists(resource)) {
// 如果访问的文件可以在SPIFFS中找到
File file = SPIFFS.open(resource, "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";
}
运行效果如下,

点击 “前往PWM控制页面” ,
输入 0 —— 1023 之间的数,因为 LED的正极接 3.3 V,所以当输入的值越大时, LED 灯两端的压差就越小,也就越暗。
这个设置过程与网络环境有关,网速越快,设置也就越快。
下面,再来重点来分析下这个代码。
void handleLEDControl(){
// 从浏览器发送的信息中获取PWM控制数值(字符串格式)
String ledPwm = esp8266_server.arg("ledPwm");
// 将字符串格式的PWM控制数值转换为整数
int ledPwmVal = ledPwm.toInt();
// 实施引脚PWM设置
analogWrite(LED_BUILTIN, ledPwmVal);
// 建立基本网页信息显示当前数值以及返回链接
String httpBody = "Led PWM: " + ledPwm + "<p><a href=\"/LED.html\"><-LED Page</a></p>";
esp8266_server.send(200, "text/html", httpBody);
}
arg 参数是可以通过浏览器这个地址信息中,
通过这个地址信息呢,看有没有和 arg 函数中的参数相匹配的信息,如果有就会把该参数后面的数字获取到。获取到之后将以返回值的形式赋值给 ledPWM 这个字符串变量。
之后,httpBody 是响应体中的信息,也就是,
其中,
<p><a href=\"/LED.html\"><-LED Page</a></p>
代表的含义是一个链接,可以链接到 LED.html 这个页面。
最后,再通过
esp8266_server.send(200, "text/html", httpBody);
把这个响应体通过服务器响应给浏览器,从而浏览器就可以显示出页面的信息了。
下面再把整个流程给理一理。
起初, 网络服务器启动之后,通过串口监视器输出连接成功信息 。
然后,初始化网络服务器,告知系统如何处理/LED-Control请求 和 处理其它网络请求。
//初始化网络服务器
esp8266_server.on("/LED-Control", handleLEDControl); // 告知系统如何处理/LED-Control请求
esp8266_server.onNotFound(handleUserRequest); // 处理其它网络请求
然后,用户在登录服务器地址之后,在回车之后,向服务器请求资源,然后通过浏览器出现下面页面,

这个页面也就是 index.html 这个网页文件中的内容。

我们使用记事本文件打开这个网页文件看下,这个网页文件的内容。

该网页文件指出,当用户点击“前往PWM控制页面”这个链接之后,就会跳转到 /LED.html 这个网页。从而也就出现下面这个网页内容。

我们再来看下,这个网页文件中是怎么写的。

该网页指出,当点击 /img/taichi-maker.jpg 这个图片时,会跳转到太极创客的官网 http://www.taichi-maker.com,
还有核心的部分:
当用户在这个页面输入设定的数值,然后点击 OK 后,就会执行对应程序中的 handleLEDControl() 的处理内容。
void handleLEDControl(){
// 从浏览器发送的信息中获取PWM控制数值(字符串格式)
String ledPwm = esp8266_server.arg("ledPwm");
// 将字符串格式的PWM控制数值转换为整数
int ledPwmVal = ledPwm.toInt();
// 实施引脚PWM设置
analogWrite(LED_BUILTIN, ledPwmVal);
// 建立基本网页信息显示当前数值以及返回链接
String httpBody = "Led PWM: " + ledPwm + "<p><a href=\"/LED.html\"><-LED Page</a></p>";
esp8266_server.send(200, "text/html", httpBody);
}
从而跳转进入
之后,点击链接 < - LED Page 就会回到 /LED.html 这个目录下,需要说明下,“text/html” 是文件类型。
4.4.2 通过多个网页文本框输入 PWM 数值来控制 PWM 波形
void handleLEDControl(){
// 从浏览器发送的信息中获取控制数值(字符串格式)
String value1 = esp8266_server.arg("value1");
String value2 = esp8266_server.arg("value2");
// 将用户输入的信息通过串口监视器显示出来
Serial.print("value1 = ");Serial.println(value1);
Serial.print("value2 = ");Serial.println(value2);
// 建立基本网页信息显示当前数值以及返回链接
String httpBody = "value1: " + value1 + "<br> value2: " + value2 + "<p><a href=\"/LED.html\"><-LED Page</a></p>";
esp8266_server.send(200, "text/html", httpBody);
}
其他地方,没什么变化。流程也一致。不重点说了,用到时再来看。
4.5 (Ajax)控制LED引脚并将A0引脚读数实时显示于网页中
(现在还不懂 Ajax 技术,但已了解其功能。)
在 index.html 中从< script >…< / script >之间的内容就是使用 Ajax 技术实现的内容了。
这段 Ajax 代码的作用就是部分更新网页中的内容,之前的试例程序是网页全部内容重新刷新。
4.6 (JavaScript)通过网页图形界面控制ESP8266的PWM引脚
(现在还不懂 JavaScript 技术,但了解其功能。)
4.7 (JavaScript)使用指针表显示模拟输入引脚数值
(现在还不懂 JavaScript 技术,但了解其功能。)
4.8 通过网页将文件上传到ESP8266开发板闪存文件系统
代码如下,
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : 3_4_8_SPIFFS_File_Upload_Server 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200211 程序目的/Purpose : 建立网络服务器,允许用户通过网页将文件上传到SPIFFS ----------------------------------------------------------------------- 修订历史/Revision History 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description 20200218 CYNO朔 0.01 一致性调整 ----------------------------------------------------------------------- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/ ***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
ESP8266WebServer esp8266_server(80); // 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
File fsUploadFile; // 建立文件对象用于闪存文件上传
void setup() {
Serial.begin(9600);
Serial.println("");
wifiMulti.addAP("FAST_153C80", "123456798"); // 将需要连接的一系列WiFi ID和密码输入这里
wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) {
// 尝试进行wifi连接。
delay(1000);
Serial.print(i++); Serial.print('.');
}
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
if(SPIFFS.begin()){
// 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
esp8266_server.on("/upload.html", // 如果客户端通过upload页面
HTTP_POST, // 向服务器发送文件(请求方法POST)
respondOK, // 则回复状态码 200 给客户端
handleFileUpload);// 并且运行处理文件上传函数
esp8266_server.onNotFound(handleUserRequest);
esp8266_server.begin(); // 启动网站服务
Serial.println("HTTP server started");
}
void loop() {
esp8266_server.handleClient();
}
// 处理上传文件函数
void handleFileUpload(){
HTTPUpload& upload = esp8266_server.upload();
if(upload.status == UPLOAD_FILE_START){
// 如果上传状态为UPLOAD_FILE_START
String filename = upload.filename; // 建立字符串变量用于存放上传文件名
if(!filename.startsWith("/")) filename = "/" + filename; // 为上传文件名前加上"/"
Serial.println("File Name: " + filename); // 通过串口监视器输出上传文件的名称
fsUploadFile = SPIFFS.open(filename, "w"); // 在SPIFFS中建立文件用于写入用户上传的文件数据
} else if(upload.status == UPLOAD_FILE_WRITE){
// 如果上传状态为UPLOAD_FILE_WRITE
if(fsUploadFile)
fsUploadFile.write(upload.buf, upload.currentSize); // 向SPIFFS文件写入浏览器发来的文件数据
} else if(upload.status == UPLOAD_FILE_END){
// 如果上传状态为UPLOAD_FILE_END
if(fsUploadFile) {
// 如果文件成功建立
fsUploadFile.close(); // 将文件关闭
Serial.println(" Size: "+ upload.totalSize); // 通过串口监视器输出文件大小
esp8266_server.sendHeader("Location","/success.html"); // 将浏览器跳转到/success.html(成功上传页面)
esp8266_server.send(303); // 发送相应代码303(重定向到新页面)
} else {
// 如果文件未能成功建立
Serial.println("File upload failed"); // 通过串口监视器输出报错信息
esp8266_server.send(500, "text/plain", "500: couldn't create file"); // 向浏览器发送相应代码500(服务器错误)
}
}
}
//回复状态码 200 给客户端
void respondOK(){
esp8266_server.send(200);
}
// 处理用户浏览器的HTTP访问
void handleUserRequest(){
// 获取用户请求网址信息
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";
}
运行并测试程序:



之后,通过读取文本中的内容来查看是否真的上传成功(代码在前面有介绍),这里不试了。
这里没有代码分析,可直接调用,在后面用到时再来分析代码。
边栏推荐
- Knowledge competition of safety production month -- how much do you know about new safety law
- 2022 safety officer-a certificate special operation certificate examination question bank and simulation examination
- Epoll 原理及应用 && ET模式与LT模式
- 421. maximum XOR value of two numbers in the array
- PHP starts OpenSSL and reports OpenSSL support=> disabled (install ext/openssl)
- Unity3d model skin changing technology
- 软件测试是否需要掌握编程能力
- GCC C内联汇编
- 年金保險理財產品可以複利嗎?利率是多少?
- When a logical deletion encounters a unique index, what are the problems and solutions?
猜你喜欢

Ortele has obtained three rounds of financing nine months after its establishment, and hard discount stores have found new ways to grow?

How to guarantee the data quality of data warehouse?

如何3步精读《PMBOK指南》(经验+资料分享)

Project load failed

MySQL备份与恢复

Colab报错:ImportError: cannot import name ‘_check_savefig_extra_args‘ from ‘matplotlib.backend_bases‘

Metal organic framework MOF Al (Diba), MOF Zr (Diba), MOF Fe (Diba) loaded with curcumin / carboxybenzylpenicillin /mtx methotrexate / paclitaxel ptx/ DOX / cisplatin cddp/cpt camptothecin and other d

What can the enterprise exhibition hall design bring to the enterprise?

Tests logiciels vocabulaire commun anglais

Jetpack Compose Box控件
随机推荐
Find - (sequential search)
当逻辑删除遇上唯一索引,遇到的问题和解决方案?
MySQL备份与恢复
SQL | 外连接
如何保障数仓数据质量?
可扩/减容线程池C语言原理讲解及代码实现
889. 根据前序和后序遍历构造二叉树
[3.delphi common components] 6 scroll bar
Unity3d detects that the object is not within the range of the camera
When a logical deletion encounters a unique index, what are the problems and solutions?
【AI周报】AI与冷冻电镜揭示「原子级」NPC结构;清华、商汤提出「SIM」方法兼顾语义对齐与空间分辨能力
Les produits financiers de l'assurance - rente peuvent - ils être composés? Quel est le taux d'intérêt?
Unity3d model skin changing technology
JS summary of math functions in math objects
贵金属白银和现货白银之间是什么关系
Common vocabulary of software testing English
Why can some programmers get good offers with average ability?
Find - (half find / half find)
What is the relationship between precious metal silver and spot Silver
Web watermark