一、Arduino Core For ESP8266
二、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<ESP8266WiFi.h>
一步到位
详解:
①、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)
- 切换到STA模式(
管理连接:
- 重新连接网络(
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
- 获取mac地址
智能配置:
- 进入智能配置功能(
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)
)
- 启动开放式wifi网络(
- 管理网络:
- 获取连接到AP上的station的数目(
softAPgetStationNum()
) - 关闭AP模式(
softAPdisconnect(bool wifi off)
)
- 获取连接到AP上的station的数目(
- 网络信息:
- 获取ap的IP地址(
softAPIP()
) - 获取ap的mac地址(
softAPmacAddress()
)
- 获取ap的IP地址(
④、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<void(int)> 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网络(
- 扫描结果:
- 获取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);
- 获取wifi网络名字(
⑤、TCP客户端(WiFiClient):
TCP与HTTP关系:
TCP是底层通讯协议,定义的是数据传输和连接方式的规范;
HTTP是应用层协议,定义的是传输数据的内容规范;
HTTP协议中的数据是利用TCP协议传输的,所以支持HTTP就支持TCP。
- 连接操作:
- 启动tcp连接(
connect(host,port)
) - 判断client是否还在连接(
connected()
) - 停止tcp连接(
stop()
)
- 启动tcp连接(
- 发送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)
)
- 新增tcp server(
- 停止server:
close()
stop()
(内部实现直接调用close())
- server状态 :
server.status()
- 设置tcp server:
- 等待WiFiClient访问:
- 判断是否有新的client连接进来(
available()
) - 判断是否有client连接(
has Client()
)
- 判断是否有新的client连接进来(
- 读取WiFiClient的请求:参考WiFiClient里面的响应方法
⑧、TCP服务端(WiFiServerSecure https)
⑨、ESP8266WiFi库自带方法:
- 调用调试信息(
printDiag(serial)
)
三、示例:
1、AP模式:
/**
* AP模式下,演示AP 函数方法的使用(最多连接4个)
*/
#include <ESP8266WiFi.h>
#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 <ESP8266WiFi.h>
#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 <ESP8266WiFi.h>
#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 <ESP8266WiFi.h>
#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 <ESP8266WiFi.h>
//以下三个定义为调试定义
#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 <ESP8266WiFi.h>
//以下三个定义为调试定义
#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 <ESP8266WiFi.h>
//以下三个定义为调试定义
#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 <ESP8266WiFi.h>
#include <stdio.h>
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 <ESP8266WiFi.h>
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 <ESP8266WiFi.h>
//以下三个定义为调试定义
#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 <ESP8266WiFi.h>
#include <ArduinoJson.h>
//以下三个定义为调试定义
#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<BUFFER_SIZE> 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 <ESP8266WiFi.h>
//定义最多多少个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 <ESP8266WiFi.h>
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" +
"<!DOCTYPE HTML>" +
"<html>" +
"Analog input: " + String(analogRead(A0)) +
"</html>" +
"\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 <ESP8266WiFi.h>
//以下三个定义为调试定义
#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<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s += (val) ? "high" : "low";
s += "</html>\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 <ESP8266WiFi.h>
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());
}