学习太极创客 — ESP8226 (二)

学习太极创客 — ESP8226 (二)_第1张图片
该板子上有两个按键,其中 RST 是用来复位开发板的,而 FLASH 则是在开发板刷固件时需要用到的。

浅蓝色的引脚为通讯引脚,包括 I2C、SPI、UART 等。

黑底白字的引脚是用来操作它内部的存储单元的。
学习太极创客 — ESP8226 (二)_第2张图片
也就是说几个引脚一般不做普通引脚使用。

学习太极创客 — ESP8226 (二)_第3张图片

4.4、通过网页文本框控制 ESP8266 开发板的 PWM 引脚

源文件(下载)链接: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/spiffs/spiffs-web-server/text-pwm-pin-control/

需要注意,在PWM控制方面,Arduino 开发板的可输入的数值与 ESP8266 的不同, Arduino 只能输入 0 - 255,而 ESP8266 则可以输入 0 - 1023。但是,此处需要重点说明的是,“在 3.0 之前的版本中,默认范围为 0 - 1023”,

参考链接: https://blog.csdn.net/qq_39209508/article/details/120844466

学习太极创客 — ESP8226 (二)_第4张图片
我这里的使用的库是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 + "

<-LED Page

"
; 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"; }

运行效果如下,

学习太极创客 — ESP8226 (二)_第5张图片
点击 “前往PWM控制页面” ,
学习太极创客 — ESP8226 (二)_第6张图片
输入 0 —— 1023 之间的数,因为 LED的正极接 3.3 V,所以当输入的值越大时, LED 灯两端的压差就越小,也就越暗。

这个设置过程与网络环境有关,网速越快,设置也就越快。
学习太极创客 — ESP8226 (二)_第7张图片
下面,再来重点来分析下这个代码。

void handleLEDControl(){
  // 从浏览器发送的信息中获取PWM控制数值(字符串格式)
  String ledPwm = esp8266_server.arg("ledPwm"); 

  // 将字符串格式的PWM控制数值转换为整数
  int ledPwmVal = ledPwm.toInt();

  // 实施引脚PWM设置
  analogWrite(LED_BUILTIN, ledPwmVal);

  // 建立基本网页信息显示当前数值以及返回链接
  String httpBody = "Led PWM: " + ledPwm + "

<-LED Page

"
; esp8266_server.send(200, "text/html", httpBody); }

arg 参数是可以通过浏览器这个地址信息中,
在这里插入图片描述
通过这个地址信息呢,看有没有和 arg 函数中的参数相匹配的信息,如果有就会把该参数后面的数字获取到。获取到之后将以返回值的形式赋值给 ledPWM 这个字符串变量。

之后,httpBody 是响应体中的信息,也就是,
学习太极创客 — ESP8226 (二)_第8张图片
其中,

<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); // 处理其它网络请求

然后,用户在登录服务器地址之后,在回车之后,向服务器请求资源,然后通过浏览器出现下面页面,

学习太极创客 — ESP8226 (二)_第9张图片

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

在这里插入图片描述
我们使用记事本文件打开这个网页文件看下,这个网页文件的内容。

学习太极创客 — ESP8226 (二)_第10张图片

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

学习太极创客 — ESP8226 (二)_第11张图片

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

学习太极创客 — ESP8226 (二)_第12张图片
该网页指出,当点击 /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 + "

<-LED Page

"
; esp8266_server.send(200, "text/html", httpBody); }

从而跳转进入
学习太极创客 — ESP8226 (二)_第13张图片
之后,点击链接 < - 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 + "
value2: "
+ value2 + "

<-LED Page

"
; 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开发板闪存文件系统

程序和网页下载链接: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/spiffs/spiffs-web-server/file-upload-server/

代码如下,

/**********************************************************************
项目名称/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";
}

运行并测试程序:
学习太极创客 — ESP8226 (二)_第14张图片
学习太极创客 — ESP8226 (二)_第15张图片
学习太极创客 — ESP8226 (二)_第16张图片
学习太极创客 — ESP8226 (二)_第17张图片
之后,通过读取文本中的内容来查看是否真的上传成功(代码在前面有介绍),这里不试了。

这里没有代码分析,可直接调用,在后面用到时再来分析代码。

你可能感兴趣的:(笔记,学习,单片机,物联网)