WIFI模块(ESP8266)学习3

2025-12-11 09:38:17      新服速递

一、Arduino Core For ESP8266

源码:Arduino Core For ESP8266 github

资料:ESP8266 Arduino Core

概述:

二、ESP8266工作模式与ESP8266WIFI库1、ESP8266工作模式

Station模式(STA):

ESP8266模块连接WIFI网络(通过接入点(Access Point))

特点:

连接丢失,ESP8266会自动重连最近使用的接入点(会出问题,连不上);

模块重启也会这样;

ESP8266将最后使用的接入点认证信息(ssid , psw)保存到Flash(非易失性)存储器中;

若在Arduino IDE修改代码,但不更改WIFI工作模式或接入点认证信息,ESP8266使用保存在Flash上的数据重新连接。

AP模式(soft-AP):

(Access Point) ESP8266作为接入点建立WIFI网络,供Station模式下的模块连接

特点:

AP模式可用作STA模式的模块之间交换中转站(让模块处于同一WIFI网络下);

可先在AP模式下发出WIFI信号,手机连接,高速该模块家里的WIFI认证信息,模块转为STA模式,连接目标WIFI。

AP兼STA模式:

以上两种模式的整合(应该是做软路由那个意思)

2、ESP8266WIFI库概述:

相关知识:

名字里带Secure、SSL、TLS的,和安全校验有关(https);

带Client,和tcp客户端(发送端)有关;

带Server,和tcp服务端(接收端)有关;

带8266,针对ESP8266的代码封装;

带Scan,和WIFI扫描有关;

带STA,和ESP8266 Station模式有关;

带AP,和ESP8266 AP模式(AP热点)有关;

ESP8266WiFiGeneric(8266模块通用库)包括:处理程序来管理WIFI事件,如连接、断开或获得ip,WIFI模式的变化,管理模块睡眠模式的功能,以ip地址解析hostName等;

ESP8266WiFiGType.h文件,主要用来定义各种配置选项,如WIFI工作模式(WiFiMode),WiFi睡眠模式(WiFiSleep Type),wifi物理模式(WiFiPhyMode),wifi事件(WiFiEvent),wifi断开原因等;

ESP8266WiFi库不仅仅局限于ESP8266WIFi.h和ESP8266WiFi.cpp这两个文件,但他们是最核心的统一入口;

WiFiUdp库,在ESP8266WiFi功能基础上包装了UDP广播协议,适用于UDP通信,需另加头文件

引入#include一步到位

详解:

①、WIFI通用功能库(ESP8266WiFiGeneric):

②、STA库(ESP8266WiFiSTA):

配置连接:

注意:

WiFi.mode(WIFI_STA);//最好人为加上STA设置(虽然默认是STA模式)

WiFi.disconnect();//最好调用一下断连

/*如果之前处于AP模式,再调begin()可能会进入STA+softAp模式

*可检测当前模式(WiFi.getMode())

*/

切换到STA模式(begin())

源码:

/**

* 切换工作模式到STA模式,并自动连接到最近接入的wifi热点

* @param void

* @return void

* @note 调用这个方法就会切换到STA模式,并且连接到最近使用的接入点(会从flash中读取之前存储的配置信息)

* 如果没有配置信息,那么这个方法基本上没有什么用。

*/

wl_status_t begin()

应用:

WiFi.begin();

切换到STA模式(begin(ssid,psw))

应用:

WiFi.begin(AP_SSID, AP_PSW);

切换到STA模式(begin(ssid,psw,channel,bssid,connect))

/**

* 切换工作模式到STA模式,并根据connect属性来判断是否连接wifi

* @param ssid wifi热点名字

* @param password wifi热点密码

* @param channel wifi热点的通道号,用特定通信通信,可选参数

* @param bssid wifi热点的mac地址,可选参数

* @param connect boolean参数,默认等于true,当设置为false,不会去连接wifi热点,会建立module保存上面参数

* @return wl_status_t wifi状态

* @note 调用这个方法就会切换到STA模式。

* 如果connect等于true,会连接到ssid的wifi热点。

* 如果connect等于false,不会连接到ssid的wifi热点,会建立module保存上面参数。

*/

wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel =0, const uint8_t* bssid = NULL, bool connect = true

配置IP信息(config(local_ip,gateway,subnet,dns1,dns2))

源码:

/**

* 禁止DHCP client,设置station 模式下的IP配置

* @param local_ip station固定的ip地址(连接快)

* @param gateway 网关

* @param subnet 子网掩码(前3个参数都设置为0.0.0.0,则重启DHCP)

* @param dns1,dns2 可选参数定义域名服务器(dns)的ip地址,这些域名服务器

* 维护一个域名目录(如www.google.co.uk),并将它们翻译成ip地址

* @return boolean值,如果配置成功,返回true;

* 如果配置没成功(模块没处于station或者station+soft AP模式),返回false;

*/

bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000)

管理连接:

重新连接网络(reconnect())

源码:

/**

* 断开连接并且重新连接station到同一个AP

* @param void

* @return false or true

* 返回false,意味着ESP8266不处于STA模式或者说Station在此之前没有连接到一个可接入点。

* 返回true,意味着已经成功重新启动连接,但是用户仍应该去检测网络连接状态指导WL_CONNECTED。

*/

bool reconnect()

应用:

WiFi.reconnect();

while (WiFi.status() != WL_CONNECTED)

{

delay(500);

Serial.print(".");

}

断开网络连接(disconnect())

源码:

/**

* 断开wifi连接,设置当前配置SSID和pwd为null

* @param wifioff 可选参数,设置为true,那么就会关闭Station模式

* @return false or true 返回wl_status_t状态

*/

bool disconnect(bool wifioff = false);

是否连接网络(isConnected())

源码:

/**

* 判断STA模式下是否连接上AP

* @return 如果STA连接上AP,那么就返回true

*/

bool isConnected();

设置是否自动连接到最近接入点(setAutoConnect(bool autoReconnect))

源码:

/**

* 当电源启动后,设置ESP8266在STA模式下是否自动连接flash中存储的AP

* @param autoConnect bool 默认是自动连接

* @return 返回保存状态 true or false

*/

bool setAutoConnect(bool autoConnect);

判断是否自动设置自动连接(getAutoConnect())

源码:

/**

* 检测ESP8266 station模式下是否启动自动连接

* @return 返回自动连接状态 true or false

*/

bool getAutoConnect();

设置是否自动重连到最近接入点(setAutoReconnect(bool autoReconnect))

源码:

/**

* 设置当断开连接的时候是否自动重连

* 网络断开后再设置无效

* @param autoConnect bool

* @return 返回保存状态 true or false

*/

bool setAutoReconnect(bool autoReconnect);

判断网络连接状态(waitForConnectResult())

源码:

/**

* 等待直到ESP8266连接AP返回结果

* @return uint8_t 连接结果

* 1.WL_CONNECTED 成功连接

* 2.WL_NO_SSID_AVAIL 匹配SSID失败(账号错误)

* 3.WL_CONNECT_FAILED psw错误

* 4.WL_IDLE_STATUS 当wi-fi正在不同的状态中变化

* 5.WL_DISCONNECTED 这个模块没有配置STA模式

*/

uint8_t waitForConnectResult();

station信息:

获取mac地址

macAddress(macAddr)

macAddress()

源码:

/**

* 获取ESP station下的Mac地址

* @param mac uint8_t数组的指针,数组长度为Mac地址的长度,这里为6

* @return 返回uint8_t数组的指针

*/

uint8_t * macAddress(uint8_t* mac);

/**

* 获取ESP station下的Mac地址

* @return 返回String的Mac地址

*/

String macAddress();

应用:

//实例代码1 这只是部分代码 不能直接使用

if (WiFi.status() == WL_CONNECTED)

{

uint8_t macAddr[6];

WiFi.macAddress(macAddr);

Serial.printf("Connected, mac address: %02x:%02x:%02x:%02x:%02x:%02x\n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);

//Connected, mac address: 5C:CF:7F:08:11:17

}

//实例代码2 这只是部分代码 不能直接使用

if (WiFi.status() == WL_CONNECTED)

{

Serial.printf("Connected, mac address: %s\n", WiFi.macAddress().c_str());

Connected, mac address: 5C:CF:7F:08:11:17

}

获取ip地址(localIP())

源码:

/**

* 返回ESP8266 STA模式下的IP地址

* @return IP地址

*/

IPAddress localIP();

应用:

if (WiFi.status() == WL_CONNECTED)

{

Serial.print("Connected, IP address: ");

Serial.println(WiFi.localIP());

//Connected, IP address: 192.168.1.10

}

获取子网掩码(subnetMask())

源码:

/**

* 获取子网掩码的地址

* @return 返回子网掩码的IP地址

*/

IPAddress subnetMask();

应用:

Serial.print("Subnet mask: ");

Serial.println(WiFi.subnetMask());

//Subnet mask: 255.255.255.0

获取网关地址(getwayIP())

源码:

/**

* 获取网关IP地址

* @return 返回网关IP地址

*/

IPAddress gatewayIP();

应用:

//实例代码 这只是部分代码 不能直接使用

Serial.printf("Gataway IP: %s\n", WiFi.gatewayIP().toString().c_str());

//Gataway IP: 192.168.1.9

获取dns地址(dnsIP())

源码:

/**

* 获取DNS ip地址

* @param dns_no dns序列号

* @return 返回DNS服务的IP地址

*/

IPAddress dnsIP(uint8_t dns_no = 0);

应用:

Serial.print("DNS #1, #2 IP: ");

WiFi.dnsIP().printTo(Serial);

Serial.print(", ");

WiFi.dnsIP(1).printTo(Serial);

Serial.println();

//DNS #1, #2 IP: 62.179.1.60, 62.179.1.61

获取host名字(hostname())

源码:

/**

* 获取ESP8266 station DHCP的主机名

* @return 主机名

*/

String hostname();

设置host名字(hostname(hostname))(3种)

源码:

/**

* 设置ESP8266 station DHCP的主机名

* @param aHostname 最大长度:32

* @return ok

*/

bool hostname(char* aHostname);

bool hostname(const char* aHostname);

bool hostname(String aHostname);

应用:

Serial.printf("Default hostname: %s\n", WiFi.hostname().c_str());

WiFi.hostname("Station_Tester_02");

Serial.printf("New hostname: %s\n", WiFi.hostname().c_str());

//Default hostname: ESP_081117

//New hostname: Station_Tester_02

获取当前wifi连接状态(status())

源码:

/**

* 返回wifi的连接状态

* @return 返回wl_status_t中定义的其中一值,wl_status_t在 wl_definitions.h中定义

*/

wl_status_t status();

获取wifi网络名字(SSID())

源码:

/**

* 返回当前通信网络的SSID

* @return SSID

*/

String SSID() const;

应用:

//实例代码 这只是部分代码 不能直接使用

Serial.printf("SSID: %s\n", WiFi.SSID().c_str());

//SSID: sensor-net

获取wifi网络密码(psk())

源码:

/**

* 返回当前通信网络的密码

* @return psk

*/

String psk() const;

获取wifi网络macaddress(BSSID())

源码:

/**

* 返回当前通信网络的mac地址

* @return bssid uint8_t *

*/

uint8_t * BSSID();

String BSSIDstr();

应用:

Serial.printf("BSSID: %s\n", WiFi.BSSIDstr().c_str());

//BSSID: 00:1A:70E:C1:68

获取wifi网络的信号强度(RSSI())

源码:

/**

* Return the current network RSSI.返回当前通信网络的信号强度,单位是dBm

* @return RSSI value

*/

int32_t RSSI();

应用:

Serial.printf("RSSI: %d dBm\n", WiFi.RSSI());

//RSSI: -68 dBm

智能配置:

进入智能配置功能(beginSmartConfig())

查询智能配置状态(smartConfigDone())

停止智能配置功能(stopSmartConfig())

WiFi.beginWPSConfig()

bool beginWPSConfig(void);

/**

* 启动 SmartConfig

*/

bool beginSmartConfig();

/**

* 停止 SmartConfig

*/

bool stopSmartConfig();

/**

* 查找SmartConfig状态来决定是否停止配置

* @return smartConfig Done

*/

bool smartConfigDone();

③、AP库(ESP8266WIFIAP)

配置soft-AP:

启动开放式wifi网络(softAP(ssid))

启动校验式wifi网络(softAP(ssid,password,channel,hidden))

配置ap网络信息(softAPConfig(local_ip,gateway,subnet))

管理网络:

获取连接到AP上的station的数目(softAPgetStationNum())

关闭AP模式(softAPdisconnect(bool wifi off))

网络信息:

获取ap的IP地址(softAPIP())

获取ap的mac地址(softAPmacAddress())

④、WiFi扫描库(ESP8266WiFiScan):一般使用异步扫描(不影响代码运行)

扫描操作:

同步扫描周边有效wifi网络(scanNetworks()) 源码: /**

* Start scan WiFi networks available

* @param async run in async mode(是否启动异步扫描)

* @param show_hidden show hidden networks(是否扫描隐藏网络)

* @param channel scan only this channel (0 for all channels)(是否扫描特定通道)

* @param ssid* scan for only this ssid (NULL for all ssid's)(是否扫描特定的SSID)

* @return Number of discovered networks

*/

int8_t scanNetworks(bool async = false, bool show_hidden = false, uint8 channel = 0, uint8* ssid = NULL);

应用: //实例代码 这只是部分代码 不能直接使用

//同步扫描

int n = WiFi.scanNetworks();//不需要填任何参数

Serial.println("scan done");

if (n == 0) {

Serial.println("no networks found");

} else {

Serial.println(" networks found");

}

异步扫描周边有效wifi网络,包括隐藏网络(scanNetworks(bool async,bool show_hiden)) 应用: //实例代码 这只是部分代码 不能直接使用

//异步扫描

WiFi.scanNetworks(true);

// print out Wi-Fi network scan result uppon completion

int n = WiFi.scanComplete();

if(n >= 0){

Serial.printf("%d network(s) found\n", n);

for (int i = 0; i < n; i++){

Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i+1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : "");

}

//打印一次结果之后把缓存中的数据清掉

WiFi.scanDelete();

}

检测异步扫描的结果(scanComplete()) 源码: /**

* called to get the scan state in Async mode(异步扫描的结果函数)

* @return scan result or status

* -1 if scan not find

* -2 if scan not triggered

*/

int8_t scanComplete();

从内存中删除最近扫描结果(scanDelete()) 如果不删除,则会叠加上次扫描结果; /**

* delete last scan result from RAM(从内存中删除最近的扫描结果)

*/

void scanDelete();

异步扫描周边wifi网络,并回调结果(scanNetworkAsync(onComplete,show_hidden)) 源码: /**

* Starts scanning WiFi networks available in async mode

* @param onComplete the event handler executed when the scan is done

* @param show_hidden show hidden networks

*/

void scanNetworksAsync(std::function onComplete, bool show_hidden = false);

应用: //实例代码

#include "ESP8266WiFi.h"

void prinScanResult(int networksFound)

{

Serial.printf("%d network(s) found\n", networksFound);

for (int i = 0; i < networksFound; i++)

{

Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i + 1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : "");

}

}

void setup()

{

Serial.begin(115200);

Serial.println();

WiFi.mode(WIFI_STA);

WiFi.disconnect();

delay(100);

WiFi.scanNetworksAsync(prinScanResult);

}

void loop() {}

//应该会打印如下类似的显示

//5 network(s) found

//1: Tech_D005107, Ch:6 (-72dBm)

//2: HP-Print-A2-Photosmart 7520, Ch:6 (-79dBm)

//3: ESP_0B09E3, Ch:9 (-89dBm) open

//4: Hack-4-fun-net, Ch:9 (-91dBm)

//5: UPC Wi-Free, Ch:11 (-79dBm)

扫描结果:

获取wifi网络名字(SSID(int networkltem)) /**

* Return the SSID discovered during the network scan.

* @param i specify from which network item want to get the information

* @return ssid string of the specified item on the networks scanned list

*/

String SSID(uint8_t networkItem);

获取wifi网络信号强度(RSS(int networkltem)) /**

* Return the RSSI of the networks discovered during the scanNetworks(信号强度)

* @param i specify from which network item want to get the information

* @return signed value of RSSI of the specified item on the networks scanned list

*/

int32_t RSSI(uint8_t networkItem);

获取wifi网络加密方式(encryption Type(int networkltem)) /**

* Return the encryption type of the networks discovered during the scanNetworks(加密方式)

* @param i specify from which network item want to get the information

* @return encryption type (enum wl_enc_type) of the specified item on the networks scanned list

* ............ Values map to 802.11 encryption suites.....................

* AUTH_OPEN ----> ENC_TYPE_WEP = 5,

* AUTH_WEP ----> ENC_TYPE_TKIP = 2,

* AUTH_WPA_PSK ----> ENC_TYPE_CCMP = 4,

* ........... except these two, 7 and 8 are reserved in 802.11-2007.......

* AUTH_WPA2_PSK ----> ENC_TYPE_NONE = 7,

* AUTH_WPA_WPA2_PSK ----> ENC_TYPE_AUTO = 8

*/

uint8_t encryptionType(uint8_t networkItem);

获取wifi网络mac地址(BSSID(int networkltem)) /**

* return MAC / BSSID of scanned wifi (物理地址)

* @param i specify from which network item want to get the information

* @return uint8_t * MAC / BSSID of scanned wifi

*/

uint8_t * BSSID(uint8_t networkItem);

/**

* return MAC / BSSID of scanned wifi (物理地址)

* @param i specify from which network item want to get the information

* @return uint8_t * MAC / BSSID of scanned wifi

*/

String BSSIDstr(uint8_t networkItem);

获取整体网络信息,名字,信号强度等(getNetworkInfo) 入参前面多数加了&,意味着调完函数后外面获取到的详细洗信息; /**

* loads all infos from a scanned wifi in to the ptr parameters

* @param networkItem uint8_t

* @param ssid const char**

* @param encryptionType uint8_t *

* @param RSSI int32_t *

* @param BSSID uint8_t **

* @param channel int32_t *

* @param isHidden bool *

* @return (true if ok)

*/

bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden);

获取wifi网络通道号 /**

* return channel of scanned wifi(通道号)

*/

int32_t channel(uint8_t networkItem);

判断wifi网络是否是隐藏网络 /**

* return if the scanned wifi is Hidden (no SSID)(判断扫描到的wifi是否是隐藏wifi)

* @param networkItem specify from which network item want to get the information

* @return bool (true == hidden)

*/

bool isHidden(uint8_t networkItem);

⑤、TCP客户端(WiFiClient):TCP与HTTP关系:

TCP是底层通讯协议,定义的是数据传输和连接方式的规范;

HTTP是应用层协议,定义的是传输数据的内容规范;

HTTP协议中的数据是利用TCP协议传输的,所以支持HTTP就支持TCP。

连接操作:

启动tcp连接(connect(host,port))

判断client是否还在连接(connected())

停止tcp连接(stop())

发送http请求操作:

print()

println()

write()

响应操作:

判断是否有响应数据(available())

查找响应数据某个字符串(find())

读取响应数据直到某个字符串,会清除掉(readStringUntil)

读取响应数据中的一个字符,不清除(peek())

读取固定大小的响应数据,不清除(peekBytes(buf,size))

读取响应数据中的一个字符,清掉(read())

读取固定大小的响应数据,清掉(read(buf,size))

清掉缓冲区(flush())

普通设置:setNoDelay()

⑥、TCP客户端(WiFiClientSecure https):⑦、TCP服务端(WiFiServer):

管理server:

设置tcp server:

新增tcp server(WiFiServer server(port))

启动tcp server(begin())

关闭小包合并发送功能(setNoDelay(true))

停止server:

close()

stop()(内部实现直接调用close())

server状态 : server.status()

等待WiFiClient访问:

判断是否有新的client连接进来(available())

判断是否有client连接(has Client())

读取WiFiClient的请求:参考WiFiClient里面的响应方法

⑧、TCP服务端(WiFiServerSecure https)⑨、ESP8266WiFi库自带方法:

调用调试信息(printDiag(serial))

总结:(感谢博哥的图)

三、示例:1、AP模式:/**

* AP模式下,演示AP 函数方法的使用(最多连接4个)

*/

#include

#define AP_SSID "AP_Test" //这里改成你的AP名字

#define AP_PSW "12345678" //这里改成你的AP密码 8位以上

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

IPAddress local_IP(192,168,4,1);

IPAddress gateway(192,168,4,1);

IPAddress subnet(255,255,255,0);

void setup(){

//设置串口波特率,以便打印信息

DebugBegin(115200);

//延时2s 为了演示效果

delay(2000);

DebugPrint("Setting soft-AP configuration ... ");

//配置AP信息

WiFi.mode(WIFI_AP);

DebugPrintln(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");

//启动AP模式,并设置账号和密码

DebugPrint("Setting soft-AP ... ");

boolean result = WiFi.softAP(AP_SSID, AP_PSW);

if(result){

DebugPrintln("Ready");

//输出 soft-ap ip地址

DebugPrintln(String("Soft-AP IP address = ") + WiFi.softAPIP().toString());

//输出 soft-ap mac地址

DebugPrintln(String("MAC address = ") + WiFi.softAPmacAddress().c_str());

}else{

DebugPrintln("Failed!");

}

DebugPrintln("Setup End");

}

void loop() {

//不断打印当前的station个数

DebugPrintln(String("Stations connected =") + WiFi.softAPgetStationNum());

delay(3000);

}

2、STA模式

/**

* Demo1:

* statin模式下,创建一个连接到可接入点(wifi热点),并且打印IP地址

*/

#include

#define AP_SSID "XU-ChinaNet" //这里改成你的wifi名字

#define AP_PSW "15358228063"//这里改成你的wifi密码

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

void setup(){

//设置串口波特率,以便打印信息

DebugBegin(115200);

//延时2s 为了演示效果

delay(2000);

DebugPrintln("Setup start");

//启动STA模式,并连接到wifi网络

WiFi.mode(WIFI_STA);//最好人为加上STA设置(虽然默认是STA模式)

WiFi.disconnect();//最好调用一下断连

WiFi.begin(AP_SSID, AP_PSW);

DebugPrint(String("Connecting to ")+AP_SSID);

//判断网络状态是否连接上,没连接上就延时500ms,并且打出一个点,模拟连接过程

//笔者扩展:加入网络一直都连不上 是否可以做个判断,由你们自己实现

while (WiFi.status() != WL_CONNECTED){

delay(500);

DebugPrint(".");

}

DebugPrintln("");

DebugPrint("Connected, IP address: ");

//输出station IP地址,这里的IP地址由DHCP分配

DebugPrintln(WiFi.localIP());

DebugPrintln("Setup End");

}

void loop() {

}

/**

* Demo2:固定IP

* statin模式下,配置IP地址,网关地址,子网掩码,并且打印IP地址

*/

#include

#define AP_SSID "XU-ChinaNet" //这里改成你的wifi名字

#define AP_PSW "15358228063"//这里改成你的wifi密码

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

IPAddress staticIP(192,168,1,22);//固定IP地址

IPAddress gateway(192,168,1,9);//网关地址

IPAddress subnet(255,255,255,0);//子网掩码地址

void setup(){

//设置串口波特率,以便打印信息

DebugBegin(115200);

//延时2s 为了演示效果

delay(2000);

DebugPrintln("Setup start");

//启动STA模式,并连接到wifi网络

WiFi.begin(AP_SSID, AP_PSW);

DebugPrint(String("Connecting to ")+AP_SSID);

//配置网络

WiFi.config(staticIP,gateway,subnet);

//判断网络状态是否连接上,没连接上就延时500ms,并且打出一个点,模拟连接过程

//笔者扩展:加入网络一直都连不上 是否可以做个判断,由你们自己实现

while (WiFi.status() != WL_CONNECTED){

delay(500);

DebugPrint(".");

}

DebugPrintln("");

DebugPrint("Connected, IP address: ");

//输出station IP地址,这里的IP地址理论上就是上面配置的

DebugPrintln(WiFi.localIP());

DebugPrintln("Setup End");

}

void loop() {

}

/**

* Demo3:

* statin模式下,创建一个连接到可接入点(wifi热点),并且打印station信息

*/

#include

#define AP_SSID "XU-ChinaNet" //这里改成你的wifi名字

#define AP_PSW "15358228063"//这里改成你的wifi密码

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

void setup(){

//设置串口波特率,以便打印信息

DebugBegin(115200);

//延时2s 为了演示效果

delay(2000);

DebugPrintln("Setup start");

//启动STA模式,并连接到wifi网络

WiFi.begin(AP_SSID, AP_PSW);

//设置自动连接

WiFi.setAutoConnect(true);

//设置自动重连

WiFi.setAutoReconnect(true);

DebugPrint(String("Connecting to ")+AP_SSID);

//判断网络状态是否连接上,没连接上就延时500ms,并且打出一个点,模拟连接过程

//笔者扩展:加入网络一直都连不上 是否可以做个判断,由你们自己实现

while (WiFi.status() != WL_CONNECTED){

delay(500);

DebugPrint(".");

}

DebugPrintln("");

DebugPrintln("rint Network Info:");

if (WiFi.status() == WL_CONNECTED){

//输出mac地址

DebugPrintln(String("Connected, mac address: ")+WiFi.macAddress().c_str());

//输出station IP地址,这里的IP地址由DHCP分配

DebugPrintln(String("Connected, IP address: ")+WiFi.localIP().toString());

//输出子网掩码地址

DebugPrintln(String("Subnet mask: ")+WiFi.subnetMask().toString());

//输出网关 IP地址

DebugPrintln(String("Gataway IP: ")+WiFi.gatewayIP().toString());

//输出hostname

DebugPrintln(String("Default hostname: ")+WiFi.hostname());

//设置新的hostname

WiFi.hostname("Station_host_123");

DebugPrintln(String("New hostname: ")+WiFi.hostname());

//输出SSID

DebugPrintln(String("SSID: ")+WiFi.SSID());

//输出psk

DebugPrintln(String("psk: ")+WiFi.psk());

//输出BSSID

DebugPrintln(String("BSSID: ")+WiFi.BSSIDstr());

//输出RSSI

DebugPrintln(String("RSSI: ") + WiFi.RSSI() + " dBm");

}

DebugPrintln("Setup End");

}

void loop() {

}

3、扫描:

/**

* Demo:

* STA模式下,演示同步扫描Scan wifi功能

*/

#include

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

void setup() {

//设置串口波特率,以便打印信息

DebugBegin(115200);

//延时5s 为了演示效果

delay(5000);

// 我不想别人连接我,只想做个站点

WiFi.mode(WIFI_STA);

//断开连接

WiFi.disconnect();

delay(100);

DebugPrintln("Setup done");

}

void loop() {

DebugPrintln("scan start");

// 同步扫描,等待返回结果

int n = WiFi.scanNetworks();

DebugPrintln("scan done");

if (n == 0){

DebugPrintln("no networks found");

}else{

DebugPrint(n);

DebugPrintln(" networks found");

for (int i = 0; i < n; ++i){

DebugPrint(i + 1);

DebugPrint(": ");

//打印wifi账号

DebugPrint(WiFi.SSID(i));

DebugPrint(",");

DebugPrint(String("Ch:")+WiFi.channel(i));

DebugPrint(",");

DebugPrint(WiFi.isHidden(i)?"hide":"show");

DebugPrint(" (");

//打印wifi信号强度

DebugPrint(WiFi.RSSI(i));

DebugPrint("dBm");

DebugPrint(")");

//打印wifi加密方式

DebugPrintln((WiFi.encryptionType(i) == ENC_TYPE_NONE)?"open":"*");

delay(10);

}

}

DebugPrintln("");

// 延时5s之后再次扫描

delay(5000);

}

/**

* Demo:

* STA模式下,演示异步扫描Scan wifi功能

*/

#include

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

//定义一个扫描时间间隔

#define SCAN_PERIOD 5000

long lastScanMillis;

void setup() {

//设置串口波特率,以便打印信息

DebugBegin(115200);

//延时5s 为了演示效果

delay(5000);

// 我不想别人连接我,只想做个站点

WiFi.mode(WIFI_STA);

//断开连接

WiFi.disconnect();

delay(100);

DebugPrintln("Setup done");

}

void loop() {

long currentMillis = millis();

//触发扫描

if (currentMillis - lastScanMillis > SCAN_PERIOD){

WiFi.scanNetworks(true);

Serial.print("\nScan start ... ");

lastScanMillis = currentMillis;

}

// 判断是否有扫描结果

int n = WiFi.scanComplete();

if(n >= 0){

Serial.printf("%d network(s) found\n", n);

for (int i = 0; i < n; i++){

Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i+1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : "");

}

//打印完一次扫描结果之后 删除内存保存结果

WiFi.scanDelete();

}

}

/**

* Demo:

* STA模式下,演示异步扫描Scan wifi功能

*/

#include

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

/**

* 打印扫描结果

* @param networksFound 结果个数

*/

void prinScanResult(int networksFound){

Serial.printf("%d network(s) found\n", networksFound);

for (int i = 0; i < networksFound; i++)

{

Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i + 1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : "");

}

}

void setup() {

//设置串口波特率,以便打印信息

DebugBegin(115200);

//延时5s 为了演示效果

delay(5000);

// 我不想别人连接我,只想做个站点

WiFi.mode(WIFI_STA);

//断开连接

WiFi.disconnect();

delay(100);

DebugPrintln("Setup done");

Serial.print("\nScan start ... ");

WiFi.scanNetworksAsync(prinScanResult);

}

void loop() {

}

4、通用库处理事件:

官方示例:(AP模式)

/*

This sketch shows how to use WiFi event handlers.

In this example, ESP8266 works in AP mode.

Three event handlers are demonstrated:

- station connects to the ESP8266 AP

- station disconnects from the ESP8266 AP

- ESP8266 AP receives a probe request from a station

*/

#include

#include

const char* ssid = "ap-ssid";

const char* password = "ap-password";

WiFiEventHandler stationConnectedHandler;

WiFiEventHandler stationDisconnectedHandler;

WiFiEventHandler probeRequestPrintHandler;

WiFiEventHandler probeRequestBlinkHandler;

bool blinkFlag;

void setup() {

Serial.begin(115200);

pinMode(LED_BUILTIN, OUTPUT);

digitalWrite(LED_BUILTIN, HIGH);

// 不保存任何wifi配置到flash

WiFi.persistent(false);

// 建立一个AP

WiFi.mode(WIFI_AP);

WiFi.softAP(ssid, password);

// 注册事件处理器

// 回调函数会在事件发生时被调用

// onStationConnected函数会在每一次有station连接时调用

stationConnectedHandler = WiFi.onSoftAPModeStationConnected(&onStationConnected);

// onStationDisconnected函数会在每一次有station断开时调用

stationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(&onStationDisconnected);

// onProbeRequestPrint和onProbeRequestBlink函数会在每一次收到探针请求时调用

// onProbeRequestPrint会打印station的mac地址和信号强度到串口监视器

// onProbeRequestBlink会闪烁LED

probeRequestPrintHandler = WiFi.onSoftAPModeProbeRequestReceived(&onProbeRequestPrint);

probeRequestBlinkHandler = WiFi.onSoftAPModeProbeRequestReceived(&onProbeRequestBlink);

}

void onStationConnected(const WiFiEventSoftAPModeStationConnected& evt) {

Serial.print("Station connected: ");

Serial.println(macToString(evt.mac));

}

void onStationDisconnected(const WiFiEventSoftAPModeStationDisconnected& evt) {

Serial.print("Station disconnected: ");

Serial.println(macToString(evt.mac));

}

void onProbeRequestPrint(const WiFiEventSoftAPModeProbeRequestReceived& evt) {

Serial.print("Probe request from: ");

Serial.print(macToString(evt.mac));

Serial.print(" RSSI: ");

Serial.println(evt.rssi);

}

void onProbeRequestBlink(const WiFiEventSoftAPModeProbeRequestReceived&) {

// 我们不能在事件处理函数中调用延时函数或者其他阻塞函数

// 因此这里设置一个标志位

blinkFlag = true;

}

void loop() {

if (millis() > 10000 && probeRequestPrintHandler) {

// 10s之后,禁止 onProbeRequestPrint

Serial.println("Not printing probe requests any more (LED should still blink)");

probeRequestPrintHandler = WiFiEventHandler();

}

if (blinkFlag) {

blinkFlag = false;

digitalWrite(LED_BUILTIN, LOW);

delay(100);

digitalWrite(LED_BUILTIN, HIGH);

}

delay(10);

}

String macToString(const unsigned char* mac) {

char buf[20];

snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",

mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

return String(buf);

}

station模式:

#include

const char *ssid = "********";

const char *password = "********";

WiFiEventHandler STAConnected;

WiFiEventHandler STADisconnected;

WiFiEventHandler STAGotIP;

void ConnectedHandler(const WiFiEventStationModeConnected &event)

{

Serial.println(WiFi.status());

Serial.println("模块连接到网络");

}

void DisconnectedHandler(const WiFiEventStationModeDisconnected &event)

{

Serial.println(WiFi.status());

Serial.println("模块从网络断开");

}

void setup()

{

Serial.begin(115200);

Serial.println();

STAConnected = WiFi.onStationModeConnected(ConnectedHandler);

STADisconnected = WiFi.onStationModeDisconnected(DisconnectedHandler);

STAGotIP = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP &event) {

Serial.println(WiFi.status());

Serial.println("模块获得IP");

});

WiFi.mode(WIFI_STA);

WiFi.begin(ssid, password);

Serial.println(WiFi.status());

}

void loop()

{

delay(5000); //等待5秒

WiFi.disconnect(); //断开当前网络连接

}

5、TCP客户端(client)

演视WiFiClient与TCP server之间通信功能(使用TCP调试助手(TCP/UDP Socket调试工具))在TCP调试助手上建立一个TCP server, IP地址是192.168.1.102,端口号是8234。

/**

* Demo:

* STA模式下,演示WiFiClient与TCP server之间的通信功能

* 本实验需要跟TCP调试助手一起使用。

*/

#include

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

#define AP_SSID "XU-ChinaNet" //这里改成你的wifi名字

#define AP_PSW "15358228063"//这里改成你的wifi密码

const uint16_t port = 8234;

const char * host = "192.168.1.8"; // ip or dns

WiFiClient client;//创建一个tcp client连接

void setup() {

//设置串口波特率,以便打印信息

DebugBegin(115200);

//延时5s 为了演示效果

delay(5000);

// 我不想别人连接我,只想做个站点

WiFi.mode(WIFI_STA);

WiFi.begin(AP_SSID,AP_PSW);

DebugPrint("Wait for WiFi... ");

//等待wifi连接成功

while (WiFi.status() != WL_CONNECTED) {

Serial.print(".");

delay(500);

}

DebugPrintln("");

DebugPrintln("WiFi connected");

DebugPrint("IP address: ");

DebugPrintln(WiFi.localIP());

delay(500);

}

void loop() {

DebugPrint("connecting to ");

DebugPrintln(host);

if (!client.connect(host, port)) {

DebugPrintln("connection failed");

DebugPrintln("wait 5 sec...");

delay(5000);

return;

}

// 发送数据到Tcp server

DebugPrintln("Send this data to server");

client.println(String("Send this data to server"));

//读取从server返回到响应数据

String line = client.readStringUntil('\r');

DebugPrintln(line);

DebugPrintln("closing connection");

client.stop();

DebugPrintln("wait 5 sec...");

delay(5000);

}

通过TCP client包装Http请求协议去调用天气接口获取天气信息

(使用ArduinoJson库,尽量使用5.X版本)

/**

* Demo:

* 演示Http请求天气接口信息

*/

#include

#include

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

const char* ssid = "TP-LINK_5344"; // XXXXXX -- 使用时请修改为当前你的 wifi ssid

const char* password = "6206908you11011010"; // XXXXXX -- 使用时请修改为当前你的 wifi 密码

const char* host = "api.seniverse.com";

const char* APIKEY = "wcmquevztdy1jpca"; //API KEY

const char* city = "guangzhou";

const char* language = "zh-Hans";//zh-Hans 简体中文 会显示乱码

const unsigned long BAUD_RATE = 115200; // serial connection speed

const unsigned long HTTP_TIMEOUT = 5000; // max respone time from server

const size_t MAX_CONTENT_SIZE = 1000; // max size of the HTTP response

// 我们要从此网页中提取的数据的类型

struct WeatherData {

char city[16];//城市名称

char weather[32];//天气介绍(多云...)

char temp[16];//温度

char udate[32];//更新时间

};

WiFiClient client;

char response[MAX_CONTENT_SIZE];

char endOfHeaders[] = "\r\n\r\n";

void setup() {

// put your setup code here, to run once:

WiFi.mode(WIFI_STA); //设置esp8266 工作模式

DebugBegin(BAUD_RATE);

DebugPrint("Connecting to ");//写几句提示,哈哈

DebugPrintln(ssid);

WiFi.begin(ssid, password); //连接wifi

WiFi.setAutoConnect(true);

while (WiFi.status() != WL_CONNECTED) {

//这个函数是wifi连接状态,返回wifi链接状态

delay(500);

DebugPrint(".");

}

DebugPrintln("");

DebugPrintln("WiFi connected");

delay(500);

DebugPrintln("IP address: ");

DebugPrintln(WiFi.localIP());//WiFi.localIP()返回8266获得的ip地址

client.setTimeout(HTTP_TIMEOUT);

}

void loop() {

// put your main code here, to run repeatedly:

//判断tcp client是否处于连接状态,不是就建立连接

while (!client.connected()){

if (!client.connect(host, 80)){

DebugPrintln("connection....");

delay(500);

}

}

//发送http请求 并且跳过响应头 直接获取响应body

if (sendRequest(host, city, APIKEY) && skipResponseHeaders()) {

//清除缓冲

clrEsp8266ResponseBuffer();

//读取响应数据

readReponseContent(response, sizeof(response));

WeatherData weatherData;

if (parseUserData(response, &weatherData)) {

printUserData(&weatherData);

}

}

delay(5000);//每5s调用一次

}

/**

* @发送http请求指令

*/

bool sendRequest(const char* host, const char* cityid, const char* apiKey) {

// We now create a URI for the request

//心知天气 发送http请求

String GetUrl = "/v3/weather/now.json?key=";

GetUrl += apiKey;

GetUrl += "&location=";

GetUrl += city;

GetUrl += "&language=";

GetUrl += language;

// This will send the request to the server

client.print(String("GET ") + GetUrl + " HTTP/1.1\r\n" +

"Host: " + host + "\r\n" +

"Connection: close\r\n\r\n");

DebugPrintln("create a request:");

DebugPrintln(String("GET ") + GetUrl + " HTTP/1.1\r\n" +

"Host: " + host + "\r\n" +

"Connection: close\r\n");

delay(1000);

return true;

}

/**

* @Desc 跳过 HTTP 头,使我们在响应正文的开头

*/

bool skipResponseHeaders() {

// HTTP headers end with an empty line

bool ok = client.find(endOfHeaders);

if (!ok) {

DebugPrintln("No response or invalid response!");

}

return ok;

}

/**

* @Desc 从HTTP服务器响应中读取正文

*/

void readReponseContent(char* content, size_t maxSize) {

size_t length = client.readBytes(content, maxSize);

delay(100);

DebugPrintln("Get the data from Internet!");

content[length] = 0;

DebugPrintln(content);

DebugPrintln("Read data Over!");

client.flush();//清除一下缓冲

}

/**

* @Desc 解析数据 Json解析

* 数据格式如下:

* {

* "results": [

* {

* "location": {

* "id": "WX4FBXXFKE4F",

* "name": "北京",

* "country": "CN",

* "path": "北京,北京,中国",

* "timezone": "Asia/Shanghai",

* "timezone_offset": "+08:00"

* },

* "now": {

* "text": "多云",

* "code": "4",

* "temperature": "23"

* },

* "last_update": "2017-09-13T09:51:00+08:00"

* }

* ]

*}

*/

bool parseUserData(char* content, struct WeatherData* weatherData) {

// -- 根据我们需要解析的数据来计算JSON缓冲区最佳大小

// 如果你使用StaticJsonBuffer时才需要

// const size_t BUFFER_SIZE = 1024;

// 在堆栈上分配一个临时内存池

// StaticJsonBuffer jsonBuffer;

// -- 如果堆栈的内存池太大,使用 DynamicJsonBuffer jsonBuffer 代替

DynamicJsonBuffer jsonBuffer;

JsonObject& root = jsonBuffer.parseObject(content);

if (!root.success()) {

DebugPrintln("JSON parsing failed!");

return false;

}

//复制我们感兴趣的字符串

strcpy(weatherData->city, root["results"][0]["location"]["name"]);

strcpy(weatherData->weather, root["results"][0]["now"]["text"]);

strcpy(weatherData->temp, root["results"][0]["now"]["temperature"]);

strcpy(weatherData->udate, root["results"][0]["last_update"]);

// -- 这不是强制复制,你可以使用指针,因为他们是指向“内容”缓冲区内,所以你需要确保

// 当你读取字符串时它仍在内存中

return true;

}

// 打印从JSON中提取的数据

void printUserData(const struct WeatherData* weatherData) {

DebugPrintln("Print parsed data :");

DebugPrint("City : ");

DebugPrint(weatherData->city);

DebugPrint(", \t");

DebugPrint("Weather : ");

DebugPrint(weatherData->weather);

DebugPrint(",\t");

DebugPrint("Temp : ");

DebugPrint(weatherData->temp);

DebugPrint(" C");

DebugPrint(",\t");

DebugPrint("Last Updata : ");

DebugPrint(weatherData->udate);

DebugPrintln("\r\n");

}

// 关闭与HTTP服务器连接

void stopConnect() {

DebugPrintln("Disconnect");

client.stop();

}

void clrEsp8266ResponseBuffer(void){

memset(response, 0, MAX_CONTENT_SIZE); //清空

}

6、TCP服务端(server)

8266作为WiFiServer端,打开TCP调试助手,模拟TCP Client的请求;

/**

* Demo:

* 演示WiFiServer功能

* 打开TCP调试助手 模拟TCP client请求

*/

#include

//定义最多多少个client可以连接本server(一般不要超过4个)

#define MAX_SRV_CLIENTS 1

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

const char* ssid = "TP-LINK_5344";

const char* password = "6206908you11011010";

//创建server 端口号是23

WiFiServer server(23);

//管理clients

WiFiClient serverClients[MAX_SRV_CLIENTS];

void setup() {

DebugBegin(115200);

WiFi.mode(WIFI_STA);

WiFi.begin(ssid, password);

DebugPrint("\nConnecting to ");

DebugPrintln(ssid);

uint8_t i = 0;

while (WiFi.status() != WL_CONNECTED && i++ < 20) {

delay(500);

}

if (i == 21) {

DebugPrint("Could not connect to");

DebugPrintln(ssid);

while (1) {

delay(500);

}

}

//启动server

server.begin();

//关闭小包合并包功能,不会延时发送数据

server.setNoDelay(true);

DebugPrint("Ready! Use 'telnet ");

DebugPrint(WiFi.localIP());

DebugPrintln(" 23' to connect");

}

void loop() {

uint8_t i;

//检测是否有新的client请求进来

if (server.hasClient()) {

for (i = 0; i < MAX_SRV_CLIENTS; i++) {

//释放旧无效或者断开的client

if (!serverClients[i] || !serverClients[i].connected()) {

if (serverClients[i]) {

serverClients[i].stop();

}

//分配最新的client

serverClients[i] = server.available();

DebugPrint("New client: ");

DebugPrint(i);

break;

}

}

//当达到最大连接数 无法释放无效的client,需要拒绝连接

if (i == MAX_SRV_CLIENTS) {

WiFiClient serverClient = server.available();

serverClient.stop();

DebugPrintln("Connection rejected ");

}

}

//检测client发过来的数据

for (i = 0; i < MAX_SRV_CLIENTS; i++) {

if (serverClients[i] && serverClients[i].connected()) {

if (serverClients[i].available()) {

//get data from the telnet client and push it to the UART

while (serverClients[i].available()) {

//发送到串口调试器

Serial.write(serverClients[i].read());

}

}

}

}

if (Serial.available()) {

//把串口调试器发过来的数据 发送给client

size_t len = Serial.available();

uint8_t sbuf[len];

Serial.readBytes(sbuf, len);

//push UART data to all connected telnet clients

for (i = 0; i < MAX_SRV_CLIENTS; i++) {

if (serverClients[i] && serverClients[i].connected()) {

serverClients[i].write(sbuf, len);

delay(1);

}

}

}

}

8266作为web server端,打开PC浏览器输入IP网址,请求web server

/**

* Demo:

* 演示web Server功能

* 打开PC浏览器 输入IP地址。请求web server

*/

#include

const char* ssid = "TP-LINK_5344";//wifi账号 这里需要修改

const char* password = "xxxx";//wifi密码 这里需要修改

//创建 tcp server 端口号是80

WiFiServer server(80);

void setup(){

Serial.begin(115200);

Serial.println();

Serial.printf("Connecting to %s ", ssid);

WiFi.mode(WIFI_STA);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED){

delay(500);

Serial.print(".");

}

Serial.println(" connected");

//启动TCP 连接

server.begin();

//打印TCP server IP地址

Serial.printf("Web server started, open %s in a web browser\n", WiFi.localIP().toString().c_str());

}

/**

* 模拟web server 返回http web响应内容

* 这里是手动拼接HTTP响应内容

* 后面楼主会继续讲解另外两个专用于http请求的库

*/

String prepareHtmlPage(){

String htmlPage =

String("HTTP/1.1 200 OK\r\n") +

"Content-Type: text/html\r\n" +

"Connection: close\r\n" + // the connection will be closed after completion of the response

"Refresh: 5\r\n" + // refresh the page automatically every 5 sec

"\r\n" +

"" +

"" +

"Analog input: " + String(analogRead(A0)) +

"" +

"\r\n";

return htmlPage;

}

void loop(){

WiFiClient client = server.available();

// wait for a client (web browser) to connect

if (client){

Serial.println("\n[Client connected]");

while (client.connected()){

// 不断读取请求内容

if (client.available()){

String line = client.readStringUntil('\r');

Serial.print(line);

// wait for end of client's request, that is marked with an empty line

if (line.length() == 1 && line[0] == '\n'){

//返回响应内容

client.println(prepareHtmlPage());

break;

}

}

//由于我们设置了 Connection: close 当我们响应数据之后就会自动断开连接

}

delay(100); // give the web browser time to receive the data

// close the connection:

client.stop();

Serial.println("[Client disonnected]");

}

}

8266作为WiFiServer端,演示简单的web server功能,web server 会根据请求来做不同的操作

/*

* Demo:

* 演示简单web Server功能

* web server会根据请求来做不同的操作

* http://server_ip/gpio/0 打印 /gpio0

* http://server_ip/gpio/1 打印 /gpio1

* server_ip就是ESP8266的Ip地址

*/

#include

//以下三个定义为调试定义

#define DebugBegin(baud_rate) Serial.begin(baud_rate)

#define DebugPrintln(message) Serial.println(message)

#define DebugPrint(message) Serial.print(message)

const char* ssid = "TP-LINK_5344";//wifi账号 这里需要修改

const char* password = "xxxx";//wifi密码 这里需要修改

// 创建tcp server

WiFiServer server(80);

void setup() {

DebugBegin(115200);

delay(10);

// Connect to WiFi network

DebugPrintln("");

DebugPrintln(String("Connecting to ") + ssid);

//我只想做个安静的美男子 STA

WiFi.mode(WIFI_STA);

//我想连接路由wifi

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

DebugPrint(".");

}

DebugPrintln("");

DebugPrintln("WiFi connected");

// 启动server

server.begin();

DebugPrintln("Server started");

// 打印IP地址

DebugPrintln(WiFi.localIP().toString());

}

void loop() {

// 等待有效的tcp连接

WiFiClient client = server.available();

if (!client) {

return;

}

DebugPrintln("new client");

//等待client数据过来

while (!client.available()) {

delay(1);

}

// 读取请求的第一行 会包括一个url,这里只处理url

String req = client.readStringUntil('\r');

DebugPrintln(req);

//清掉缓冲区数据 据说这个方法没什么用 可以换种实现方式

client.flush();

// 开始匹配

int val;

if (req.indexOf("/gpio/0") != -1) {

DebugPrintln("/gpio0");

val = 0;

} else if (req.indexOf("/gpio/1") != -1) {

DebugPrintln("/gpio1");

val = 1;

} else {

DebugPrintln("invalid request");

//关闭这个client请求

client.stop();

return;

}

//清掉缓冲区数据

client.flush();

// 准备响应数据

String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\n\r\nGPIO is now ";

s += (val) ? "high" : "low";

s += "\n";

// 发送响应数据给client

client.print(s);

delay(1);

DebugPrintln("Client disonnected");

// The client will actually be disconnected

// when the function returns and 'client' object is detroyed

}

7、Smartconfig智能配网:收集APP端发送包含WIFI用户名和密码的UDP广播包,智能终端的WIFI芯片接收到UDP包,解密配置连接。

手机软件esptouch:

#include

void smartConfig()

{

WiFi.mode(WIFI_STA);

Serial.println("\r\nWait for Smartconfig");

delay(2000);

// 等待配网

WiFi.beginSmartConfig();

while (1)

{

Serial.print(".");

delay(500);

if (WiFi.smartConfigDone())

{

Serial.println("SmartConfig Success");

Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());

Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());

WiFi.setAutoConnect(true); // 设置自动连接

break;

}

}

Serial.println("");

Serial.println("WiFi connected");

}

void setup()

{

Serial.begin(115200);

smartConfig();

}

void loop()

{

delay(1000);

Serial.print("IP address: ");

Serial.println(WiFi.localIP());

}

《阴阳师》鬼使黑VS姑获鸟对比分析
红龙鳞片胸甲