【ESP8266教程】零基础入门学用物联网-基础知识篇(太极创客团队)学习笔记

这篇具有很好参考价值的文章主要介绍了【ESP8266教程】零基础入门学用物联网-基础知识篇(太极创客团队)学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、ESP8266开发板详解

1.引脚图

esp8266引脚图及其功能,物联网,学习,单片机

        NodeMCU上的D2引脚引出ESP8266芯片的GPIO4引脚

        即digitalWrite(D2,HIGH);等价于digitalWrite(4,HIGH);

        D开头的是数字引脚,A开头的是模拟引脚(右下角的ADC引脚)

        3V3可以为外界提供3.3V电压,Vin为NodeMCU供电(也可以用数据线供电)

        数字引脚为3.3V,digitalWrite(D2,HIGH);即是将D2引脚置为3.3V.而digitalRead(D2);

        引脚所连电压不能超过3.3V。

        模拟引脚可读电压范围为0-1V。

        USB下载串口占用的是RX和TX(GPIO3和GPIO1)

        蓝底黑字都是通讯端口(如GPIO3、GPIO1等)

        黑底白字都是NodeMCU操作内部存储单元的引脚(如GPIO6、GPIO15等)

        注意:GPIO6-GPIO11不要使用

二、互联网基础

1.TCP/IP协议族

esp8266引脚图及其功能,物联网,学习,单片机

        1.链路层的主要作用是实现设备之间的物理链接,如WiFi

        2.网络层为网络设备提供地址——IP协议

esp8266引脚图及其功能,物联网,学习,单片机

esp8266引脚图及其功能,物联网,学习,单片机        

        IP协议分为IPV4和IPV6,IPV4由4个十进制数(0~255)组成

esp8266引脚图及其功能,物联网,学习,单片机

        默认网关即WiFi路由器的IP地址

        子网掩码用来区分IP地址的子网地址与机器本身地址

        参考:互联网知识基础-网络层(第2章 – 第3节) – 太极创客 (taichi-maker.com)

esp8266引脚图及其功能,物联网,学习,单片机

        而IPV6由8组16进制数组成,可以为更多网络设备提供独立的IP地址

        3.传输层——TCP协议

                TCP协议特点:稳

                ·可保证所有数据都能被接收端接收

                ·数据的传输顺序不会被打乱

                ·传输数据如有损坏则重发受损数据

                适用于电子邮件、文件传输等领域

        传输层——UDP协议

                UDP协议特点:快

                ·UDP比TCP速度快

                ·不保证所有数据都能被接收端接收

                ·数据一旦受损,UDP协议将抛弃受损数据

                ·传输数据如有损坏不会重发受损数据

                适用于在线语音/视频、网游等领域

        4.应用层

                最常用HTTP协议,HTTP协议由请求和响应组成,类似于一问一答,具体参考:互联网知识基础-应用层(第2章 – 第5节) – 太极创客 (taichi-maker.com)

        请求

esp8266引脚图及其功能,物联网,学习,单片机

        响应

esp8266引脚图及其功能,物联网,学习,单片机

2.ESP8266工作模式

esp8266引脚图及其功能,物联网,学习,单片机

1.AP(Access Point)模式(接入点模式)类似于手机热点

2.无线终端模式(Wireless Station)

3.混合模式

三、ESP8266接入点模式及无线终端模式

1.接入点模式代码

3-1-3 NodeMCU开发板的接入点模式 – 太极创客 (taichi-maker.com)

/*
NodeMCU接入点模式
By 太极创客(http://www.taichi-maker.com)
2019-03-11
 
此程序用于演示如何将NodeMCU以接入点模式工作。通过此程序,您可以使用
电脑或者手机连接NodeMCU所建立WiFi网络。
 
网络名: taichi-maker
密码:12345678
 
如需获得更多关于如何使用NodeMCU开发物联网的教程和资料信息
请参考太极创客网站(http://www.taichi-maker.com)
并在首页搜索栏中搜索关键字:物联网
*/
 
#include <ESP8266WiFi.h>        // 本程序使用ESP8266WiFi库
 
const char *ssid = "taichi-maker"; // 这里定义将要建立的WiFi名称。此处以"taichi-maker"为示例
                                   // 您可以将自己想要建立的WiFi名称填写入此处的双引号中
 
const char *password = "12345678";  // 这里定义将要建立的WiFi密码。此处以12345678为示例
                                    // 您可以将自己想要使用的WiFi密码放入引号内
                                    // 如果建立的WiFi不要密码,则在双引号内不要填入任何信息
 
void setup() {
  Serial.begin(9600);              // 启动串口通讯
 
  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地址
}
 
void loop() { 
}

2.无线终端模式代码

3-1-4 NodeMCU开发板的无线终端模式 – 太极创客 (taichi-maker.com)

/*
NodeMCU无线终端模式连接WiFi
By 太极创客(http://www.taichi-maker.com)
2019-03-11
 
本示例程序用于演示如何使用NodeMCU无线终端模式连接WiFi
 
如需获得更多关于如何使用NodeMCU开发物联网的教程和资料信息
请参考太极创客网站(http://www.taichi-maker.com)
并在首页搜索栏中搜索关键字:物联网
*/
 
#include <ESP8266WiFi.h>        // 本程序使用ESP8266WiFi库
 
const char* ssid     = "taichi-maker";      // 连接WiFi名(此处使用taichi-maker为示例)
                                            // 请将您需要连接的WiFi名填入引号中
const char* password = "12345678";          // 连接WiFi密码(此处使用12345678为示例)
                                            // 请将您需要连接的WiFi密码填入引号中
                                            
void setup() {
  Serial.begin(9600);         // 启动串口通讯
  
  WiFi.begin(ssid, password);                  // 启动网络连接
  Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
  
  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
    delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
    Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
  }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                               // 这个读秒是通过变量i每隔一秒自加1来实现的。
                                               
  Serial.println("");                          // WiFi连接成功后
  Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
  Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
  Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。
}
 
void loop() {                                   
}

四、 建立基本网络服务器

1.建立基本网络服务器

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : 3_2_1_First_Web_Server
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20191107
程序目的/Purpose          : 使用NodeMCU建立基本服务器。用户可通过浏览器使用8266的IP地址
                           访问8266所建立的基本网页(Hello from ESP8266)
-----------------------------------------------------------------------
修订历史/Revision History  
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
 
***********************************************************************/
#include <ESP8266WiFi.h>        // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h>   //  ESP8266WiFiMulti库
#include <ESP8266WebServer.h>   //  ESP8266WebServer库
 
ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
 
ESP8266WebServer esp8266_server(80);// 建立ESP8266WebServer对象,对象名称为esp8266_server
                                    // 括号中的数字是网路服务器响应http请求的端口号
                                    // 网络服务器标准http端口号为80,因此这里使用80为端口号
 
void setup(void){
  Serial.begin(9600);          // 启动串口通讯
 
  //通过addAp函数存储  WiFi名称       WiFi密码
  wifiMulti.addAP("RFID", "rfid&iot0243"); 
  wifiMulti.addAP("taichi-maker", "12345678");  // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
  wifiMulti.addAP("taichi-maker2", "87654321"); // 这3个WiFi网络名称分别是taichi-maker, taichi-maker2, taichi-maker3。
  wifiMulti.addAP("taichi-maker3", "13572468"); // 这3个网络的密码分别是123456789,87654321,13572468。
                                                // 此处WiFi信息只是示例,请在使用时将需要连接的WiFi信息填入相应位置。
                                                // 另外这里只存储了3个WiFi信息,您可以存储更多的WiFi信息在此处。
 
  int i = 0;                                 
  while (wifiMulti.run() != WL_CONNECTED) {  // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
    delay(1000);                             // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
    Serial.print(i++); Serial.print(' ');    // 将会连接信号最强的那一个WiFi信号。
  }                                          // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                                             // 此处while循环判断是否跳出循环的条件。
 
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println('\n');                     // WiFi连接成功后
  Serial.print("Connected to ");            // NodeMCU将通过串口监视器输出。
  Serial.println(WiFi.SSID());              // 连接的WiFI名称
  Serial.print("IP address:\t");            // 以及
  Serial.println(WiFi.localIP());           // NodeMCU的IP地址
  
//--------"启动网络服务功能"程序部分开始-------- //  此部分为程序为本示例程序重点1
  esp8266_server.begin();                   //  详细讲解请参见太极创客网站《零基础入门学用物联网》
  esp8266_server.on("/", handleRoot);       //  第3章-第2节 ESP8266-NodeMCU网络服务器-1
  esp8266_server.onNotFound(handleNotFound);        
//--------"启动网络服务功能"程序部分结束--------
  Serial.println("HTTP esp8266_server started");//  告知用户ESP8266网络服务功能已经启动
}
 
/* 以下函数语句为本示例程序重点3
详细讲解请参见太极创客网站《零基础入门学用物联网》
第3章-第2节 3_2_1_First_Web_Server 的说明讲解*/  
void loop(void){
  esp8266_server.handleClient();     // 处理http服务器访问(检查是否有浏览器请求网页信息)
}
 
/* 以下两个函数为本示例程序重点2
详细讲解请参见太极创客网站《零基础入门学用物联网》
第3章-第2节 3_2_1_First_Web_Server 的说明讲解*/                                                                            
void handleRoot() {   //处理网站根目录“/”的访问请求 
  esp8266_server.send(200, "text/plain", "臭婆娘~ o(* ̄▽ ̄*)o这招你会不会捏");   // NodeMCU将调用此函数。
}
 
// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){                                        // 当浏览器请求的网络资源无法在服务器找到时,
  esp8266_server.send(404, "text/plain", "404: Not found");   // NodeMCU将调用此函数。
}

2.通过网络服务实现NodeMCU开发板基本控制

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : 3_2_2_Turning_on_and_off_an_LED
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20191108
程序目的/Purpose          : 使用NodeMCU建立基本服务器。用户可通过浏览器使用8266的IP地址
                           访问8266所建立的基本网页并通过该页面点亮/熄灭NodeMCU的内置LED
-----------------------------------------------------------------------
修订历史/Revision History  
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
 
***********************************************************************/
#include <ESP8266WiFi.h>        // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h>   //  ESP8266WiFiMulti库
#include <ESP8266WebServer.h>   //  ESP8266WebServer库
 
ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
 
ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
 
void setup(void){
  Serial.begin(9600);   // 启动串口通讯
 
  pinMode(LED_BUILTIN, OUTPUT); //设置内置LED引脚为输出模式以便控制LED
  wifiMulti.addAP("RFID", "rfid&iot0243"); 
  wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); // 将需要连接的一系列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) {  // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
    delay(1000);                             // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
    Serial.print(i++); Serial.print(' ');    // 将会连接信号最强的那一个WiFi信号。
  }                                          // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                                             // 此处while循环判断是否跳出循环的条件。
  
  // 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
 
  esp8266_server.begin();                           // 启动网站服务
  esp8266_server.on("/", HTTP_GET, handleRoot);     // 设置服务器根目录即'/'的函数'handleRoot'
  /*当有浏览器请求首页"/"并且方法是HTTP_GET时,才调用handleRoot*/
  esp8266_server.on("/LED", HTTP_POST, handleLED);  // 设置处理LED控制请求的函数'handleLED'
  /*当有浏览器请求页面"/LED"并且方法是HTTP_POST时,才调用handleLED*/
  esp8266_server.onNotFound(handleNotFound);        // 设置处理404情况的函数'handleNotFound'
 
  Serial.println("HTTP esp8266_server started");//  告知用户ESP8266网络服务功能已经启动
}
 
void loop(void){
  esp8266_server.handleClient();                     // 检查http服务器访问
}
 
/*设置服务器根目录即'/'的函数'handleRoot'
  该函数的作用是每当有客户端访问NodeMCU服务器根目录时,
  NodeMCU都会向访问设备发送 HTTP 状态 200 (Ok) 这是send函数的第一个参数。
  同时NodeMCU还会向浏览器发送HTML代码,以下示例中send函数中第三个参数,
  也就是双引号中的内容就是NodeMCU发送的HTML代码。该代码可在网页中产生LED控制按钮。 
  当用户按下按钮时,浏览器将会向NodeMCU的/LED页面发送HTTP请求,请求方式为POST。
  NodeMCU接收到此请求后将会执行handleLED函数内容*/
void handleRoot() {       
  esp8266_server.send(200, "text/html", "<form action=\"/LED\" method=\"POST\"><input type=\"submit\" value=\"Toggle LED\"></form>");
}
/*html——超文本标记语言

<form action=\"/LED\" method=\"POST\">
    <input type=\"submit\" value=\"Toggle LED\">
</form>

form为表单格式,其中划出一个名为Toggle LED的按键,按下后,会以POST方式跳转到/LED页面
*/

//处理LED控制请求的函数'handleLED'
void handleLED() {                          
  digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// 改变LED的点亮或者熄灭状态,翻转IO口
  esp8266_server.sendHeader("Location","/");          // 跳转回页面根目录(首页)
  esp8266_server.send(303);                           // 发送Http相应代码303 跳转  
}
 
// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){
  esp8266_server.send(404, "text/plain", "404: Not found"); // 发送 HTTP 状态 404 (未找到页面) 并向浏览器发送文字 "404: Not found"
}

3.通过网络服务将开发板引脚状态显示在网页中

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : 3_2_4_Pin_State_Display_Auto_Refresh
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200128
程序目的/Purpose          : 使用NodeMCU建立基本服务器。该网页将显示引脚D3状态。同时状态会
                           每隔5秒钟更新一次。
-----------------------------------------------------------------------
修订历史/Revision History  
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
 
***********************************************************************/
 
#include <ESP8266WiFi.h>        // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h>   //  ESP8266WiFiMulti库
#include <ESP8266WebServer.h>   //  ESP8266WebServer库
 
#define buttonPin 0           // 按钮引脚D3(GPIO0)因为它已经与开发板上的FLASH按键开关连接好了。
 
ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
 
ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
 
bool pinState;                      // 存储引脚状态用变量
 
void setup(){
  Serial.begin(9600);          // 启动串口通讯
  delay(10);
  Serial.println("");
 
  pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式

  wifiMulti.addAP("RFID", "rfid&iot0243"); 
  wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); // 将需要连接的一系列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 ...");                            // 则尝试使用此处存储的密码进行连接。
                                                               // 另外这里只存储了3个WiFi信息,您可以存储更多
                                                               // 的WiFi信息在此处。
  int i = 0;                                 
  while (wifiMulti.run() != WL_CONNECTED) {  // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
    delay(1000);                             // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
    Serial.print(i++); Serial.print(' ');    // 将会连接信号最强的那一个WiFi信号。
  }                                          // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                                             // 此处while循环判断是否跳出循环的条件。
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println('\n');                     // WiFi连接成功后
  Serial.print("Connected to ");            // NodeMCU将通过串口监视器输出。
  Serial.println(WiFi.SSID());              // 连接的WiFI名称
  Serial.print("IP address:\t");            // 以及
  Serial.println(WiFi.localIP());           // NodeMCU的IP地址
  
  esp8266_server.begin();                  
  esp8266_server.on("/", handleRoot);      
  esp8266_server.onNotFound(handleNotFound);        
 
  Serial.println("HTTP esp8266_server started");//  告知用户ESP8266网络服务功能已经启动
}
 
void loop(){
  esp8266_server.handleClient();     // 处理http服务器访问
  pinState = digitalRead(buttonPin); // 获取引脚状态
}                                                                   
 
/* 以下函数处理网站首页的访问请求。此函数为本示例程序重点1
详细讲解请参见太极创客网站《零基础入门学用物联网》
第3章-第2节“通过网络服务将开发板引脚状态显示在网页中”的说明讲解。*/    
void handleRoot() {   //处理网站目录“/”的访问请求 
  esp8266_server.send(200, "text/html", sendHTML(pinState));  
}
 
/*
建立用于发送给客户端浏览器的HTML代码。此代码将会每隔5秒刷新页面。
通过页面刷新,引脚的最新状态也会显示于页面中
*/
String sendHTML(bool buttonState){
  
  String htmlCode = "<!DOCTYPE html> <html>\n";
  htmlCode +="<head><meta http-equiv='refresh' content='5'/>\n";//每隔5s自动刷新一次
  htmlCode +="<title>ESP8266 Butoon State</title>\n";
  htmlCode +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  htmlCode +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  htmlCode +="</style>\n";
  htmlCode +="</head>\n";
  htmlCode +="<body>\n";
  htmlCode +="<h1>ESP8266 BUTTON STATE</h1>\n";
  
  if(buttonState)
    {htmlCode +="<p>Button Status: HIGH</p>\n";}
  else
    {htmlCode +="<p>Button Status: LOW</p>\n";}
    
  htmlCode +="</body>\n";
  htmlCode +="</html>\n";
  
  return htmlCode;
}
 
// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){                                        // 当浏览器请求的网络资源无法在服务器找到时,
  esp8266_server.send(404, "text/plain", "404: Not found");   // NodeMCU将调用此函数。
}

五、ESP8266闪存文件系统

ESP8266闪存文件系统基本操作

1.ESP8266闪存文件系统大小

        大小一般为4MB,具体以生产商为准,可以从Arduino IDE中读取

esp8266引脚图及其功能,物联网,学习,单片机

esp8266引脚图及其功能,物联网,学习,单片机

        若程序使用了Flash,需配置一下Flash Size

esp8266引脚图及其功能,物联网,学习,单片机

2.通过程序向闪存文件系统写入信息

/**********************************************************************
项目名称/Project           : 零基础入门学用物联网
程序名称/Program name      : esp8266-flash-write
团队/Team                 : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author               : CYNO 朔 
日期/Date(YYYYMMDD)      : 20191109
程序目的/Purpose           : 此程序用于演示如何向NodeMCU的SPIFFS中建立名为
                            notes.txt的文件,程序还将向该文件写入信息。
-----------------------------------------------------------------------
函数说明:
SPIFFS.open(file_name, "w"); 
以上函数有两个参数:
第一个参数是被操作的文件名称,本示例中该文件为/notes.txt
第二个参数"w" 代表写入文件信息。(如需了解如何读取信息,请参阅示例程序esp8266-flash-read)
***********************************************************************/


#include <FS.h>//包含闪存的一些函数
 
String file_name = "/taichi-maker/notes.txt"; //被读取的文件位置和名称
 
void setup() {
  Serial.begin(9600);
  Serial.println("");
  
  Serial.println("SPIFFS format start");
  SPIFFS.format();    // 格式化SPIFFS(Serial Peripheral Interface Flash File System)闪存文件系统
  Serial.println("SPIFFS format finish");
  
  if(SPIFFS.begin()){ // 启动SPIFFS
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
  
  File dataFile = SPIFFS.open(file_name, "w");// 建立File对象用于向SPIFFS中的file对象(即/notes.txt)写入信息
  dataFile.println("Hello IOT World.");       // 向dataFile写入字符串信息
  dataFile.close();                           // 完成文件写入后关闭文件
  Serial.println("Finished Writing data to SPIFFS");
}
 
void loop() {
}

3. 通过程序从闪存文件系统读取信息

/**********************************************************************
项目名称/Project           : 零基础入门学用物联网
程序名称/Program name      : esp8266-flash-read
团队/Team                 : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author               : CYNO 朔
日期/Date(YYYYMMDD)      : 20191109
程序目的/Purpose           : 此程序用于演示如何从NodeMCU的内置SPIFFS中存储的文件notes.txt读取数据。
                           notes.txt 文件内容将会通过串口监视器显示出来供用户确认。
                           注意在使用本程序以前需要先将notes.txt 文件上传到NodeMCU开发板的SPIFFS中
-----------------------------------------------------------------------
修订历史/Revision History
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
-----------------------------------------------------------------------
函数说明:
SPIFFS.open(file_name, "r"); 
以上SPIFFS函数有两个参数:
第一个参数是被操作的文件名称,本示例中该文件为/notes.txt
第二个参数"r" 代表读取文件信息。(如需了解如何写入信息,请参阅示例程序esp8266-flash-write)
***********************************************************************/
 
#include <FS.h>
 
String file_name = "/taichi-maker/notes.txt";              //被读取的文件位置和名称
 
void setup() {
  Serial.begin(9600);
  Serial.println("");
  
  if(SPIFFS.begin()){ // 启动闪存文件系统
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
 
  //确认闪存中是否有file_name文件
  if (SPIFFS.exists(file_name)){
    Serial.print(file_name);
    Serial.println(" FOUND.");
  } else {
    Serial.print(file_name);
    Serial.print(" NOT FOUND.");
  }
 
  //建立File对象用于从SPIFFS中读取文件
  File dataFile = SPIFFS.open(file_name, "r");
 
  //读取文件内容并且通过串口监视器输出文件信息
  for(int i=0; i<dataFile.size(); i++){
    Serial.print((char)dataFile.read());       
  }
 
  //完成文件读取后关闭文件
  dataFile.close();                           
}
 
void loop() {
}

4. 通过程序向闪存文件系统文件添加信息

        使用"a"会从文件尾部开始写,而"w"操作将会在文件系统中建立该文件。如果文件系统有该文件,则程序将会重新建立该文件,即原有文件信息将会被覆盖。

/**********************************************************************
项目名称/Project           : 零基础入门学用物联网
程序名称/Program name      : esp8266-flash-append
团队/Team                 : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author               : CYNO 朔 
日期/Date(YYYYMMDD)      : 20191109
程序目的/Purpose           : 此程序用于演示如何向NodeMCU的内置SPIFFS中存储的文件
                            notes.txt添加数据。                      
-----------------------------------------------------------------------  
函数说明:
SPIFFS.open(file_name, "a"); 
以上SPIFFS函数有两个参数:
第一个参数是被操作的文件名称,本示例中该文件为/notes.txt
第二个参数"a" 代表添加文件信息。(如需了解如何读取信息,请参阅示例程序esp8266-flash-read)
此示例程序所演示的是向SPIFFS中的文件里添加信息。这一操作写入信息有所区别。
添加信息是不会删除文件内原有信息,而是在原有信息后面添加新的信息。
但写入操作(示例 esp8266-flash-write.ino)是将文件内容完全清除,重新写入新信息。    
***********************************************************************/
 
#include <FS.h>
 
String file_name = "/taichi-maker/notes.txt";              //被读取的文件位置和名称
 
void setup() {
  Serial.begin(9600);
  Serial.println("");
  
  if(SPIFFS.begin()){ // 启动闪存文件系统
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
 
  //确认闪存中是否有file_name文件
  if (SPIFFS.exists(file_name)){
    
    Serial.print(file_name);
    Serial.println(" FOUND.");
 
    File dataFile = SPIFFS.open(file_name, "a");// 建立File对象用于向SPIFFS中的file对象(即/notes.txt)写入信息 "a"即Append
    dataFile.println("This is Appended Info."); // 向dataFile添加字符串信息
    dataFile.close();                           // 完成文件操作后关闭文件   
    Serial.println("Finished Appending data to SPIFFS");
    
  } else {
    Serial.print(file_name);
    Serial.print(" NOT FOUND.");
  }
                        
}
 
void loop() {
}

5. 通过程序读取目录内容(读取文件夹中所包含文件)

/**********************************************************************
项目名称/Project           : 零基础入门学用物联网
程序名称/Program name      : esp8266-flash-folder-read
团队/Team                 : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author               : CYNO 朔
日期/Date(YYYYMMDD)      : 20191109
程序目的/Purpose           : 此程序用于演示如何从NodeMCU的内置SPIFFS中文件夹里读取文件信息
                           文件夹内容将会通过串口监视器显示出来。
                           
-----------------------------------------------------------------------
修订历史/Revision History
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
-----------------------------------------------------------------------
函数说明:
SPIFFS.openDir(folder_name);
以上函数打开指定目录并返回一个目录对象实例。
***********************************************************************/
 
 
#include <FS.h>
 
String file_name = "/taichi-maker/myFile.txt"; //被读取的文件位置和名称
String folder_name = "/taichi-maker";         //被读取的文件夹
 
void setup() {
  Serial.begin(9600);
  Serial.println("");
  
  if(SPIFFS.begin()){ // 启动闪存文件系统
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
 
  File dataFile = SPIFFS.open(file_name, "w");// 建立File对象用于向SPIFFS中的file对象(即myFile.txt)写入信息
  dataFile.println("Hello Taichi-Maker.");    // 向dataFile写入字符串信息
  dataFile.close();                           // 完成文件写入后关闭文件
  Serial.println(F("Finished Writing data to SPIFFS"));
  /*添加 F() 相当于为字符串常量定义了PROGMEM属性,常量字符串仍然存储在FLASH中,
    但是程序运行时不会再将常量字符串从FLASH中copy到SRAM中,
  而是直接读取FLASH中的字符串,这样一来就节约了SRAM,但是代码运行速度就下降了。*/
 
  // 显示目录中文件内容以及文件大小
  Dir dir = SPIFFS.openDir(folder_name);  // 建立“目录”对象 dir=folder_name="/taichi-maker"
  
  while (dir.next()) {  // dir.next()用于检查目录中是否还有“下一个文件”
    Serial.println(dir.fileName()); // 输出文件名
  }
}
 
void loop() {
}

6. 从闪存文件系统中删除文件

/**********************************************************************
项目名称/Project           : 零基础入门学用物联网
程序名称/Program name      : esp8266-flash-remove
团队/Team                 : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author               : CYNO 朔 
日期/Date(YYYYMMDD)      : 20191109
程序目的/Purpose           : 此程序用于演示如何删除SPIFFS中存储的文件                        
***********************************************************************/
 
#include <FS.h>
 
String file_name = "/taichi-maker/notes.txt";              //被读取的文件位置和名称
 
void setup() {
  Serial.begin(9600);
  Serial.println("");
  
  if(SPIFFS.begin()){ // 启动闪存文件系统
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
  
  //从闪存中删除file_name文件
  if (SPIFFS.remove(file_name)){
    
    Serial.print(file_name);
    Serial.println(" remove sucess");
    
  } else {
    Serial.print(file_name);
    Serial.println(" remove fail");
  }                       
}
 
void loop() {
}

7. 显示闪存文件系统信息

/**********************************************************************
项目名称/Project           : 零基础入门学用物联网
程序名称/Program name      : esp8266-flash-info
团队/Team                 : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author               : CYNO 朔
日期/Date(YYYYMMDD)      : 20200204
程序目的/Purpose           : 此程序用于演示如何使用FSInfo对象来显示闪存文件系统状态
-----------------------------------------------------------------------
修订历史/Revision History
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
***********************************************************************/
 
 
#include <FS.h>
 
FSInfo fs_info;
 
void setup() {
  Serial.begin(9600);
 
  SPIFFS.begin();       //启动SPIFFS
  Serial.println("");
  Serial.println("SPIFFS Started.");
 
  // 闪存文件系统信息
  SPIFFS.info(fs_info);
 
  // 可用空间总和(单位:字节)
  Serial.print("totalBytes: ");     
  Serial.print(fs_info.totalBytes); 
  Serial.println(" Bytes"); 
 
  // 已用空间(单位:字节)
  Serial.print("usedBytes: "); 
  Serial.print(fs_info.usedBytes);
  Serial.println(" Bytes"); 
 
  // 最大文件名字符限制(含路径和'\0')
  Serial.print("maxPathLength: "); 
  Serial.println(fs_info.maxPathLength);
 
  // 最多允许打开文件数量
  Serial.print("maxOpenFiles: "); 
  Serial.println(fs_info.maxOpenFiles);
 
  // 存储块大小
  Serial.print("blockSize: "); 
  Serial.println(fs_info.blockSize);
 
  // 存储页大小
  Serial.print("pageSize: ");
  Serial.println(fs_info.pageSize);
}
 
void loop() {
}

8.通过Arduino IDE向闪存文件系统上传文件

        将需要上传的文件保存在程序路径下的data文件夹中

esp8266引脚图及其功能,物联网,学习,单片机

        根据所要上传的文件大小调整Flash Size大小 

esp8266引脚图及其功能,物联网,学习,单片机

六、使用闪存文件系统建立功能更加丰富的网络服务器

  • 在网页中加载闪存文件系统中的图片、CSS和JavaScript
  • 通过网页控制ESP8266开发板的引脚
  • 通过网页文本框控制ESP8266开发板的PWM引脚
  • (Ajax)控制LED引脚并将A0引脚读数实时显示于网页中
  • (JavaScript)通过网页图形界面控制ESP8266的PWM引脚
  • (JavaScript)使用指针表显示模拟输入引脚数值
  • 通过网页将文件上传到ESP8266开发板闪存文件系统

七、ESP8266帮助文档

1.

ESP8266-Arduino库 开发参考资料 – 太极创客 (taichi-maker.com)

esp8266引脚图及其功能,物联网,学习,单片机

esp8266引脚图及其功能,物联网,学习,单片机

注意书写格式,如GET / HTTP中间的空格 

 在http请求时,我们一般会在request header 或 response header 中看到”Connection:Keep-Alive”或 “Connection:close”,这里具体的含义是有关http 请求的是否保持长连接,即链接是否复用,每次请求是复用已建立好的请求,还是重新建立一个新的请求。

esp8266引脚图及其功能,物联网,学习,单片机

响应体即www.example.com的网页信息

2.

客户端向服务器发送数据信息

esp8266引脚图及其功能,物联网,学习,单片机

esp8266引脚图及其功能,物联网,学习,单片机

esp8266引脚图及其功能,物联网,学习,单片机

GET即可以用来发送信息也可以用来请求信息 

3.

客户端向服务器请求数据信息

七、JSON

esp8266引脚图及其功能,物联网,学习,单片机

size_t  相当于  unsigned long

esp8266引脚图及其功能,物联网,学习,单片机

 esp8266引脚图及其功能,物联网,学习,单片机

esp8266引脚图及其功能,物联网,学习,单片机

 效果如下esp8266引脚图及其功能,物联网,学习,单片机

 esp8266引脚图及其功能,物联网,学习,单片机

这样也打印的是123

  String jsonCode = "{\"info\": {\"name\": \"taichimaker\",\"url\": \"www.taichi-maker.com\",\"email\": \"taichimaker@163.com\"},\"digital_pin\": {\"d1\": \"";
  jsonCode += String(digitalRead(D1));  
  jsonCode += "\",\"d2\": \""; 
  jsonCode += String(digitalRead(D2));  
  jsonCode += "\",\"d3\": \""; 
  jsonCode += String(digitalRead(D3));  
  jsonCode += "\"},\"analog_pin\": {\"a0\": \"";
  jsonCode += String(analogRead(A0));
  jsonCode += "\"}}";  


合成后如下
{
  "info": {
    "name": "taichimaker",
    "url": "www.taichi-maker.com",
    "email": "taichimaker@163.com"
  },
  "digital_pin": {
    "d1": "1",
    "d2": "0",
    "d3": "1"
  },
  "analog_pin": {
    "a0": "500"
  }
}

Json建立过程 

{
  "info": {
    "name": "taichimaker",
    "url": "www.taichi-maker.com",
    "email": "taichimaker@163.com"
  },
  "digital_pin": {
    "d1": "1",
    "d2": "0",
    "d3": "1"
  },
  "analog_pin": {
    "a0": "500"
  }
}


该段Json代码有两种建立方式
1.手动建立

String rootJson(){

  String jsonCode = "{\"info\": {\"name\": \"taichimaker\",\"url\": \"www.taichi-maker.com\",\"email\": \"taichimaker@163.com\"},\"digital_pin\": {\"d1\": \"";
  jsonCode += String(digitalRead(D1));  
  jsonCode += "\",\"d2\": \""; 
  jsonCode += String(digitalRead(D2));  
  jsonCode += "\",\"d3\": \""; 
  jsonCode += String(digitalRead(D3));  
  jsonCode += "\"},\"analog_pin\": {\"a0\": \"";
  jsonCode += String(analogRead(A0));
  jsonCode += "\"}}";  
  
  Serial.print("jsonCode: ");Serial.println(jsonCode);
  
  return jsonCode;
}

2.使用官方工具建立(详细步骤如下图)
https://arduinojson.org/v5/assistant/

String rootJson(){
  const size_t capacity = JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(3)+140;//
  DynamicJsonDocument doc(capacity);
  
  JsonObject info = doc.createNestedObject("info");
  info["name"] = "taichimaker";
  info["url"] = "www.taichi-maker.com";
  info["email"] = "taichimaker@163.com";
  
  JsonObject digital_pin = doc.createNestedObject("digital_pin");
  digital_pin["d1"] = String(digitalRead(D1));
  digital_pin["d2"] = String(digitalRead(D2));
  digital_pin["d3"] = String(digitalRead(D3));
  
  JsonObject analog_pin = doc.createNestedObject("analog_pin");
  analog_pin["a0"] = String(analogRead(A0));
  // 结束assistant的serialize代码
 
  String jsonCode;  
  serializeJson(doc, jsonCode);
  Serial.print("Root Json Code: ");Serial.println(jsonCode); 
   
  return jsonCode;
}

使用官方工具建立步骤

esp8266引脚图及其功能,物联网,学习,单片机

 首先复制Serializing program中的代码,将1,0,1,500改为识别对应引脚的状态,capcity修改为Parsing program同样大小,这样运行更加稳定,然后修改串口打印方式

单独请求一段Json

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : cgj_server_1_serialize
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 2020517
程序目的/Purpose          : 
本实例用于演示esp8266的JSON数据通讯。
操作测试本程序需要使用两台8266开发板。其中一台为服务器端,一台为客户端。
本程序为服务器程序,功能如下:

1. 实时读取A0、 D1、D2以及D3引脚的读数。
2. 当有客户端请求信息时,将会通过http响应将引脚读数等信息发送给客户端。
   信息发送格式为JSON格式。
3. 使用ArduinoJson库的Serialize方式建立响应JSON信息
-----------------------------------------------------------------------
修订历史/Revision History  
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
***********************************************************************/
#include <ESP8266WiFi.h>        // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h>   //  ESP8266WiFiMulti库
#include <ESP8266WebServer.h>   //  ESP8266WebServer库
#include <ArduinoJson.h>        //  ArduinoJson库

#define buttonPin D3            // 按钮引脚D3

ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
 
ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)

IPAddress local_IP(192, 168, 3, 12); // 设置ESP8266-NodeMCU联网后的IP
IPAddress gateway(192, 168, 3, 1);    // 设置网关IP(通常网关IP是WiFI路由IP)
IPAddress subnet(255, 255, 255, 0);   // 设置子网掩码
IPAddress dns(192,168,3,1);           // 设置局域网DNS的IP(通常局域网DNS的IP是WiFI路由IP)
         
void setup(){
  Serial.begin(9600);          // 启动串口通讯
  Serial.println("");

  // 将引脚设置为输入上拉模式
  pinMode(D1, INPUT_PULLUP);
  pinMode(D2, INPUT_PULLUP);
  pinMode(buttonPin, INPUT_PULLUP);   // NodeMCU开发板按键连接在D3引脚上
   
  // 设置开发板网络环境
  if (!WiFi.config(local_IP, gateway, subnet)) {
    Serial.println("Failed to Config ESP8266 IP"); 
  } 

  //通过addAp函数存储  WiFi名称       WiFi密码
  wifiMulti.addAP("RFID", "rfid&iot0243"); // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
  wifiMulti.addAP("taichi-maker2", "87654321"); // 这3个WiFi网络名称分别是taichi-maker, taichi-maker2, taichi-maker3。
  wifiMulti.addAP("taichi-maker3", "13572468"); // 这3个网络的密码分别是123456789,87654321,13572468。
                                                // 此处WiFi信息只是示例,请在使用时将需要连接的WiFi信息填入相应位置。
                                                // 另外这里只存储了3个WiFi信息,您可以存储更多的WiFi信息在此处。

  int i = 0;                                 
  while (wifiMulti.run() != WL_CONNECTED) {  // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
    delay(1000);                             // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
    Serial.print(i++); Serial.print(' ');    // 将会连接信号最强的那一个WiFi信号。
  }                                          // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                                             // 此处while循环判断是否跳出循环的条件。
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println('\n');                     // WiFi连接成功后
  Serial.print("Connected to ");            // NodeMCU将通过串口监视器输出。
  Serial.println(WiFi.SSID());              // 连接的WiFI名称
  Serial.print("IP address:\t");            // 以及
  Serial.println(WiFi.localIP());           // NodeMCU的IP地址
  
  esp8266_server.begin();                  
  esp8266_server.on("/", handleRoot);    
  esp8266_server.on("/info", handleInfo); 
  esp8266_server.on("/digital_pin", handleDigitalPin);       

  Serial.println("HTTP esp8266_server started");//  告知用户ESP8266网络服务功能已经启动
}

void loop(){
  // 处理http服务器访问
  esp8266_server.handleClient(); 
}                                                                   

void handleRoot() {   //处理网站目录“/”的访问请求 
  esp8266_server.send(200, "application/json", rootJson());  
}

void handleInfo(){
  esp8266_server.send(200, "application/json", infoJson());  
}

void handleDigitalPin(){
  esp8266_server.send(200, "application/json", digitalpinJson());  
}

// 实时获取ESP8266开发板引脚信息并且建立JSON信息
// 以便ESP8266服务器通过响应信息发送给客户端
String rootJson(){
  // 开始ArduinoJson Assistant的serialize代码 
  const size_t capacity = JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(3)+140;
  DynamicJsonDocument doc(capacity);
  
  JsonObject info = doc.createNestedObject("info");
  info["name"] = "taichimaker";
  info["url"] = "www.taichi-maker.com";
  info["email"] = "taichimaker@163.com";
  
  JsonObject digital_pin = doc.createNestedObject("digital_pin");
  digital_pin["d1"] = String(digitalRead(D1));
  digital_pin["d2"] = String(digitalRead(D2));
  digital_pin["d3"] = String(digitalRead(D3));
  
  JsonObject analog_pin = doc.createNestedObject("analog_pin");
  analog_pin["a0"] = String(analogRead(A0));
  // 结束assistant的serialize代码
 
  String jsonCode;  
  serializeJson(doc, jsonCode);
  Serial.print("Root Json Code: ");Serial.println(jsonCode); 
   
  return jsonCode;
}

//V6版本
String infoJson(){
  StaticJsonDocument<128> doc;

  JsonObject info = doc.createNestedObject("info");
  info["name"] = "taichimaker";
  info["url"] = "www.taichi-maker.com";
  info["email"] = "taichimaker@163.com";
  String jsonCode;
  serializeJson(doc, jsonCode);
  return jsonCode;
}


String digitalpinJson(){
  StaticJsonDocument<96> doc;

  JsonObject digital_pin = doc.createNestedObject("digital_pin");
  digital_pin["d1"] = String(digitalRead(D1));
  digital_pin["d2"] = String(digitalRead(D2));
  digital_pin["d3"] = String(digitalRead(D3));
  String jsonCode;
  serializeJson(doc, jsonCode);
  return jsonCode;
}

//V5版本
/*
String infoJson(){
  const size_t capacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(3)+90;
  DynamicJsonBuffer jsonBuffer(capacity);

  JsonObject& root = jsonBuffer.createObject();

  JsonObject& info = root.createNestedObject("info");
  info["name"] = "taichimaker";
  info["url"] = "www.taichi-maker.com";
  info["email"] = "taichimaker@163.com";

  String jsonCode;
  root.printTo(jsonCode);

  return jsonCode;
}
*/

/*
String digitalpinJson(){
  const size_t capacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(3)+30;
  DynamicJsonBuffer jsonBuffer(capacity);

  JsonObject& root = jsonBuffer.createObject();

  JsonObject& digital_pin = root.createNestedObject("digital_pin");
  digital_pin["d1"] = String(digitalRead(D1));
  digital_pin["d2"] = String(digitalRead(D2));
  digital_pin["d3"] = String(digitalRead(D3));

  String jsonCode;
  root.printTo(jsonCode);

  return jsonCode;
}
*/

ESP8266客户端发送多种JSON数据信ddd息

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : client_send_multi_json
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : Dapenson
日期/Date(YYYYMMDD)     : 20200425
程序目的/Purpose          : 
本实例用于演示esp8266的json数据通讯。
操作测试本程序需要使用两台8266开发板。其中一台为服务器端,一台为客户端

本程序为客户端程序,功能如下:
1. 实时读取A0、 D1、D2以及D3引脚的读数。
2. 向服务器发送多种Json信息。
3. 在有些发送的信息中包含有D3引脚状态从而控制服务器开发板上
   的LED点亮或熄灭
-----------------------------------------------------------------------
修订历史/Revision History  
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
20200521      CYNO朔           001        调整以使程序与csj_client一致
-----------------------------------------------------------------------
本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ArduinoJson.h>

ESP8266WiFiMulti wifiMulti;           // 建立ESP8266WiFiMulti对象
 
const char* host = "192.168.3.12"; // 网络服务器地址
const int httpPort = 80;            // http端口80

void setup(){
  Serial.begin(9600);          
  Serial.println("");
  
   //通过addAp函数存储  WiFi名称       WiFi密码
  wifiMulti.addAP("RFID", "rfid&iot0243"); // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
  wifiMulti.addAP("taichi-maker2", "87654321"); // 这3个WiFi网络名称分别是taichi-maker, taichi-maker2, taichi-maker3。
  wifiMulti.addAP("taichi-maker3", "13572468"); // 这3个网络的密码分别是123456789,87654321,13572468。
                                                // 此处WiFi信息只是示例,请在使用时将需要连接的WiFi信息填入相应位置。
                                                // 另外这里只存储了3个WiFi信息,您可以存储更多的WiFi信息在此处。
  int i = 0;                                 
  while (wifiMulti.run() != WL_CONNECTED) {  // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
    delay(1000);                             // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
    Serial.print(i++); Serial.print(' ');    // 将会连接信号最强的那一个WiFi信号。
  }                                          // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                                             // 此处while循环判断是否跳出循环的条件。
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println('\n');                     // WiFi连接成功后
  Serial.print("Connected to ");            // NodeMCU将通过串口监视器输出。
  Serial.println(WiFi.SSID());              // 连接的WiFI名称
  Serial.print("IP address:\t");            // 以及
  Serial.println(WiFi.localIP());           // NodeMCU的IP地址
}
 
void loop(){
  // 发送HTTP请求,使用参数控制函数发送不同类型JSON
  httpRequest(1);    
  delay(2000);
  httpRequest(2); 
  delay(2000); 
  httpRequest(3); 
  delay(2000);   
  Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
 
// 向服务器发送HTTP请求,请求信息中包含json信息
void httpRequest(int jsonType){
  // 建立WiFi客户端对象,对象名称client
  WiFiClient client;    

  // 根据jsonType参数建立不同类型JSON
  String payloadJson = buildJson(jsonType); 
 
  // 建立字符串,用于HTTP请求
  String httpRequest =  String("GET /") + " HTTP/1.1\r\n" +
                        "Host: " + host + "\r\n" +
                        "Connection: close\r\n\r\n" + payloadJson;
  
  // 通过串口输出连接服务器名称以便查阅连接服务器的网址                      
  Serial.print("Connecting to "); 
  Serial.print(host); 

  if (client.connect(host, httpPort)){ 
    Serial.println(" Success!");            // 连接成功后串口输出“Success”信息
    
    client.print(httpRequest);              // 向服务器发送请求
    Serial.println("Sending request: ");    // 通过串口输出HTTP请求信息内容以便查阅
    Serial.println(httpRequest);     
    
    Serial.println("Web Server Response:"); // 通过串口监视输出服务器响应信息        
    while (client.connected() || client.available()){ 
      if (client.available()){
        String line = client.readStringUntil('\n');
        Serial.println(line);
      }
    } 
  } else{    // 如果连接不成功则通过串口输出“连接失败”信息
    Serial.println(" failed!");
  } 
  
  client.stop();                      // 断开与服务器的连接
  Serial.print("Disconnected from "); // 并且通过串口输出断开连接信息
  Serial.println(host);   
  Serial.println("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); 
}

//建立json信息v6
String buildJson(int type){

  StaticJsonDocument<256> doc;
  
  if (type == 1){
    JsonObject info = doc.createNestedObject("info");
    info["name"] = "taichimaker";
    info["url"] = "www.taichi-maker.com";
    info["email"] = "taichimaker@163.com";
  }

  if (type == 2){
    JsonObject digital_pin = doc.createNestedObject("digital_pin");
    digital_pin["d1"] = String(digitalRead(D1));
    digital_pin["d2"] = String(digitalRead(D2));
    digital_pin["d3"] = String(digitalRead(D3));
  }

  if (type == 3){
    doc["analog_pin"]["a0"] = String(analogRead(A0));
    //JsonObject analog_pin = doc.createNestedObject("analog_pin");
    //analog_pin["a0"] = String(analogRead(A0));
  }

  String jsonCode;  
  serializeJson(doc, jsonCode);
  Serial.print("type="); 
  Serial.println(type); 
  Serial.print("json Code: ");Serial.println(jsonCode); 
  return jsonCode;
}

/*
//建立json信息v5
String buildJson(int type){

  Serial.println("开始建立Json信息"); 
  // 开始ArduinoJson Assistant的serialize代码 
  const size_t capacity = JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(3)+140;
  DynamicJsonDocument doc(capacity);
  
  if (type == 1){
    JsonObject info = doc.createNestedObject("info");
    info["name"] = "taichimaker";
    info["url"] = "www.taichi-maker.com";
    info["email"] = "taichimaker@163.com";
  }

  if (type == 2){
    JsonObject digital_pin = doc.createNestedObject("digital_pin");
    digital_pin["d1"] = String(digitalRead(D1));
    digital_pin["d2"] = String(digitalRead(D2));
    digital_pin["d3"] = String(digitalRead(D3));
  }

  if (type == 3){
    JsonObject analog_pin = doc.createNestedObject("analog_pin");
    analog_pin["a0"] = String(analogRead(A0));
  }
  // 结束assistant的serialize代码

  String jsonCode;  
  serializeJson(doc, jsonCode);
  Serial.print("type="); 
  Serial.println(type); 
  Serial.print("json Code: ");Serial.println(jsonCode); 
  return jsonCode;
}
*/

六、MQTT的connect与publish在各情景下的区别

esp8266引脚图及其功能,物联网,学习,单片机

订阅主题-基础

void connectMQTTServer(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "esp8266-" + WiFi.macAddress();

  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address: ");
    Serial.println(mqttServer);
    Serial.println("ClientId:");
    Serial.println(clientId);
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }   
}

订阅主题-Qos

const int subQoS = 1;     // 客户端订阅主题时使用的QoS级别(截止2020-10-07,仅支持QoS = 1,不支持QoS = 2)

const char* willTopic = "willTopic"; // 遗嘱主题名称
const int willQos = 0;               // 遗嘱QoS
const int willRetain = false;        // 遗嘱保留
const char* willMsg = "willMsg";     // 遗嘱主题信息
const bool cleanSession = false; // 清除会话(如QoS>0必须要设为false)

// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "client-" + WiFi.macAddress();

  /* 连接MQTT服务器
  boolean connect(const char* id, const char* user, 
                  const char* pass, const char* willTopic, 
                  uint8_t willQos, boolean willRetain, 
                  const char* willMessage, boolean cleanSession); 
  若让设备在离线时仍然能够让qos1工作,则connect时的cleanSession需要设置为false                
                  */
  if (mqttClient.connect(clientId.c_str(), NULL, NULL, willTopic, willQos, willRetain, willMsg, cleanSession)) { 
    Serial.print("MQTT Server Connected. ClientId: ");
    Serial.println(clientId);
    subscribeTopic(); // 订阅指定主题
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }   
}

// 订阅指定主题
void subscribeTopic(){
  String topicString = "Qos-test";
  char subTopic[topicString.length() + 1];  
  strcpy(subTopic, topicString.c_str());
  
  // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  // 请注意subscribe函数第二个参数数字为QoS级别。这里为QoS = 1
  if(mqttClient.subscribe(subTopic, subQoS)){
    Serial.print("Subscribed Topic: ");
    Serial.println(subTopic);
  } else {
    Serial.print("Subscribe Fail...");
  }  
}

订阅主题-遗嘱

// 遗嘱设置
const char* willMsg = "CLIENT-OFFLINE"; // 遗嘱消息内容
const int willQoS = 0;                   // 遗嘱QoS
const bool willRetain = false;           // 遗嘱保留

// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
  
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "esp8266-" + WiFi.macAddress();

  // 建立遗嘱主题。主题名称以Taichi-Maker-为前缀,后面添加设备的MAC地址,最后
  // 以“-Will”结尾,这是为确保不同ESP8266客户端的遗嘱主题名称各不相同。
  String willString = "Taichi-Maker-" + WiFi.macAddress() + "-Will";
  char willTopic[willString.length() + 1];  
  strcpy(willTopic, willString.c_str());

  // 连接MQTT服务器,在连接过程中提供以下参数:
  // 客户端ID,遗嘱主题,遗嘱QoS,遗嘱保留,遗嘱信息
  if (mqttClient.connect(clientId.c_str(), willTopic, willQoS, willRetain, willMsg)){ 
    Serial.println("MQTT Server Connected.");
    Serial.print("Server Address: ");Serial.println(mqttServer);
    Serial.print("ClientId: ");Serial.println(clientId);
    Serial.print("Will Topic: ");Serial.println(willTopic);    
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }   
}

订阅主题-用户密码认证

// MQTT服务端连接用户名密码
const char* mqttUserName = "test-user";
const char* mqttPassword = "ranye-iot";

void connectMQTTServer(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "esp8266-" + WiFi.macAddress();
 
  // 连接MQTT服务器。此处使用了程序首部定义的用户名和密码来实现MQTT服务端认证
  if (mqttClient.connect(clientId.c_str(), mqttUserName, mqttPassword)) { 
    Serial.println("MQTT Server Connected.");
    Serial.print("Server Address: ");
    Serial.println(mqttServer);
    Serial.print("ClientId: ");
    Serial.println(clientId);
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }   
}

// 发布信息
void pubMQTTmsg(){
  static int value;
 
  // 建立发布主题。使用然也物联免费端口时,主题名称必须以test-user/为前缀。
  String topicString = "test-user/" + WiFi.macAddress();
  char publishTopic[topicString.length() + 1];  
  strcpy(publishTopic, topicString.c_str());
 
  // 建立发布信息。信息内容以Hello World为起始,后面添加发布次数。
  String messageString = "Hello World " + String(value++); 
  char publishMsg[messageString.length() + 1];   
  strcpy(publishMsg, messageString.c_str());
 
  // 实现ESP8266向主题发布信息
  if(mqttClient.publish(publishTopic, publishMsg)){
    Serial.println("Publish Topic:");Serial.println(publishTopic);
    Serial.println("Publish message:");Serial.println(publishMsg);      
  } else {
    Serial.println("Message Publish Failed."); 
  }
}

发布消息

void pubMQTTmsg(){
  static int value; // 客户端发布信息用数字

  // 建立发布主题。主题名称以Taichi-Maker-为前缀,后面添加设备的MAC地址。
  // 这么做是为确保不同用户进行MQTT信息发布时,ESP8266客户端名称各不相同,
  String topicString = "Taichi-Maker-Pub-" + WiFi.macAddress();
  char publishTopic[topicString.length() + 1];  
  strcpy(publishTopic, topicString.c_str());

  // 建立发布信息。信息内容以Hello World为起始,后面添加发布次数。
  String messageString = "Hello World " + String(value++); 
  char publishMsg[messageString.length() + 1];   
  strcpy(publishMsg, messageString.c_str());
  
  // 实现ESP8266向主题发布信息
  if(mqttClient.publish(publishTopic, publishMsg)){
    Serial.println("Publish Topic:");Serial.println(publishTopic);
    Serial.println("Publish message:");Serial.println(publishMsg);    
  } else {
    Serial.println("Message Publish Failed."); 
  }
}

收到信息后的回调函数

// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message Received [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println("");
  Serial.print("Message Length(Bytes) ");
  Serial.println(length);
 
  if ((char)payload[0] == '1') {     // 如果收到的信息以“1”为开始
    digitalWrite(LED_BUILTIN, LOW);  // 则点亮LED。
  } else {                           
    digitalWrite(LED_BUILTIN, HIGH); // 否则熄灭LED。
  }
}

MQTT汇总文章来源地址https://www.toymoban.com/news/detail-861474.html

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "RFID";
const char* password = "12345678";
const char* mqttServer = "test.ranye-iot.net";

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

const int subQoS = 1;     // 客户端订阅主题时使用的QoS级别(截止2020-10-07,仅支持QoS = 1,不支持QoS = 2)
const bool cleanSession = false; // 清除会话(如QoS>0必须要设为false)

const char* willTopic = "willTopic";    // 遗嘱主题名称
const char* willMsg = "willMsg";        // 遗嘱主题信息
const int willQos = 0;                  // 遗嘱QoS
const int willRetain = false;           // 遗嘱保留
const char* mqttUserName = "test-user"; // 服务端连接用户名
const char* mqttPassword = "ranye-iot"; // 服务端连接密码
//然也物联免费端口只提供这一个用户名密码
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // 设置板上LED引脚为输出模式
  digitalWrite(LED_BUILTIN, HIGH);  // 启动后关闭板上LED
  Serial.begin(9600);               // 启动串口通讯
  
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
  
  // 连接WiFi
  connectWifi();
  
  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
  mqttClient.setCallback(receiveCallback);

  // 连接MQTT服务器
  connectMQTTserver();
}

void loop() {
  // 如果开发板未能成功连接服务器,则尝试连接服务器
  if (!mqttClient.connected()) {
    connectMQTTserver();
  }
   // 处理信息以及心跳
   mqttClient.loop();
}

// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "client-" + WiFi.macAddress();

  /* 连接MQTT服务器
  boolean connect(const char* id, const char* user, 
                  const char* pass, const char* willTopic, 
                  uint8_t willQos, boolean willRetain, 
                  const char* willMessage, boolean cleanSession); 
  若让设备在离线时仍然能够让qos1工作,则connect时的cleanSession需要设置为false                
                  */
  if (mqttClient.connect(clientId.c_str(), mqttUserName, 
                         mqttPassword, willTopic, 
                         willQos, willRetain, willMsg, cleanSession)) { 
    Serial.print("MQTT Server Connected. ClientId: ");
    Serial.println(clientId);
    Serial.print("MQTT Server: ");
    Serial.println(mqttServer);    
    
    subscribeTopic(); // 订阅指定主题
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }   
}

// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message Received [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println("");
  Serial.print("Message Length(Bytes) ");
  Serial.println(length);

  if ((char)payload[0] == '1') {     // 如果收到的信息以“1”为开始
    digitalWrite(BUILTIN_LED, LOW);  // 则点亮LED。
  } else {                           
    digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
  }
}

// 订阅指定主题
void subscribeTopic(){
  // 建立订阅主题。使用然也物联的免费端口进行用户名密码连接时只能以"test-user/"开头
  // 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
  String topicString = "test-user/" + WiFi.macAddress();
  char subTopic[topicString.length() + 1];  
  strcpy(subTopic, topicString.c_str());
  
  // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  // 请注意subscribe函数第二个参数数字为QoS级别。这里为QoS = 1
  if(mqttClient.subscribe(subTopic, subQoS)){
    Serial.print("Subscribed Topic: ");
    Serial.println(subTopic);
  } else {
    Serial.print("Subscribe Fail...");
  }  
}

// ESP8266连接wifi
void connectWifi(){

  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println(""); 
}

到了这里,关于【ESP8266教程】零基础入门学用物联网-基础知识篇(太极创客团队)学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#,入门教程(15)——类(class)的基础知识

    上一篇: C#,入门教程(14)——字符串与其他数据类型的转换 https://blog.csdn.net/beijinghorn/article/details/124004562 物以类聚,凡物必类。 类的使用,须遵循几个简单的原则: (1)能类则类,留有余地。 (2)凡数据体及其集合,必写为类; (3)凡类,必独立文件; 类class实际上可

    2024年01月20日
    浏览(42)
  • C#,入门教程(20)——列表(List)的基础知识

    上一篇: C#,入门教程(19)——循环语句(for,while,foreach)的基础知识 https://blog.csdn.net/beijinghorn/article/details/124060844 List顾名思义就是数据列表,区别于数据数组(array)。 List比数组提供强大得多!多!多!多!的功能,能存储更多!多!多!类型的数据(泛型)! List是更

    2024年01月16日
    浏览(50)
  • C#,入门教程(24)——类索引器(this)的基础知识

    上一篇:   C#,入门教程(23)——数据类型转换的一点基础知识 https://blog.csdn.net/beijinghorn/article/details/124187182 工业软件首先要求高可靠性、高可维护性。 作为工业软件的开发者,我们对语言重载的需求是:“ 不可或缺 ”。 没有重载几乎就无法开展大规模的工业软件编程项目

    2024年01月22日
    浏览(43)
  • 【流光溢彩】物联网入门 - ESP8266 + WS2812B 制作流光溢彩灯带

    ESP8266 模块 x1 WS2812B 灯带(60/米,根据显示器四周长度买即可) x1 杜邦线 若干 DC 电源 x1 1. ESP8266 串口驱动 一般购买详情页都会有写,没有就找商家要一个。 一般是 CH340 或者 CP2102,我买的是 CP2102 2. WLED 固件 固件开源地址:https://github.com/Aircoookie/WLED/releases 下载 ESP8266.bin 结

    2024年02月09日
    浏览(36)
  • LaTeX详细安装教程|LaTeX 基础知识|LaTeX 常用语法|LaTeX 快速入门

    LaTeX 是一种专业的排版系统,主要用于科技文献、学术论文、书籍等的排版。与传统的文字处理软件相比,LaTeX 可以更好地管理大型文字项目,并提供了丰富的数学公式和符号支持。本篇博客将介绍 LaTeX 的基础知识、常用语法以及安装教程。 LaTeX 具有如下特点: 专业的排版

    2024年02月05日
    浏览(89)
  • ESP8266入门教程12:自动配网

    下载第三方库WiFiManager到lib文件夹  ​git clone https://github.com/tzapu/WiFiManager.git 第2行:包含WiFiManager库的头文件 第12行:创建WiFiManager对象 第14行:配置自动配网热点名称 1、编译并上传固件,然后使用手机连接名称叫做“ESP8266-Auto”的WIFI热点 2、点击【Configure WiFi】开始配网,

    2024年02月12日
    浏览(49)
  • STC8H系列单片机入门教程之ADC基础知识(四)

    目录 一、A/D转换过程 二、ADC转换流程图 三、采样定理 四、ADC基本参数 4.1、分辨率 4.2、采样速率 4.3、转换时间 4.4、量程  4.5、最低有效位 五、静态参数 5.1、微分非线性 5.2、积分非线性 六、逐次逼近型模数转换器 七、ADC常用分压电路 八、示例代码 ADC即模数转换器,用来

    2024年04月11日
    浏览(57)
  • C#,入门教程(28)——文件夹(目录)、文件读(Read)与写(Write)的基础知识

    上一篇:   C#,入门教程(27)——应用程序(Application)的基础知识 https://blog.csdn.net/beijinghorn/article/details/125094837 C#知识比你的预期简单的多,但也远远超乎你的想象! 与 文件 相关的知识,不算多。 作为初学者,先学习 文本文件 的读写,就足够应付好几年了。 文件 自然是

    2024年01月23日
    浏览(56)
  • ESP8266入门教程03:点亮LED灯

    ESP8266默认是高电平工作,所以想要点亮LED只需要给相应的引脚设置低电平即可。  第11行:使用pinMode(pin, mode)来设置GPIO口工作模式,pin取值范围0 ~ 16,数字引脚0-15可设置为INPUT、OUTPUT、INPUT_PULLUP模式(输入、输出、上拉输入);数字引脚16可设置为INPUT、OUTPUT、INPUT_PULLDOWN_16模式

    2024年02月14日
    浏览(52)
  • Python入门教程:掌握for循环、while循环、字符串操作、文件读写与异常处理等基础知识

    在 Python 中,for 循环用于遍历序列(list、tuple、range 对象等)或其他可迭代对象。for 循环的基本语法如下: 其中, 变量 表示每次循环中取出的一个元素, 可迭代对象 表示被遍历的对象。下面是一个 for 循环的例子: 输出结果为: 代码中, fruits 是一个列表, fruit 是当前循

    2024年02月10日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包