ESP8266
一:環境搭建
使用Ardino框架,在官網下載,下載離線的支持包
二:實現簡單的項目
1. 點燈
{
pinMode(LED_PIN, OUTPUT); // 設置引腳為輸出模式
digitalWrite(LED_PIN, HIGH); // 點亮 LED
}
I/O引腳的三種模式分別為:INPUT —— 輸入模式; OUTPUT —— 輸出模式;INPUT _PULLUP —— 輸入上拉模式;
2. 按鍵控制LED
{
#define KEY_PIN D1 // 定義 KEY 引腳#define LED_PIN D2 // 定義 LED 引腳void setup() {Serial.begin(115200); //初始化波特率pinMode(LED_PIN, OUTPUT); // 設置引腳為輸出模式pinMode(KEY_PIN, INPUT_PULLUP);// 輸入上拉模式Serial.println("按鍵LED已啟動");//串口打印}void loop() {int keystate=digitalRead(KEY_PIN);//讀取key電平if(keystate==LOW){digitalWrite(LED_PIN, LOW); // 點亮 LEDSerial.println("按鍵按下,LED燈亮");}else?{digitalWrite(LED_PIN, HIGH); //熄滅}delay(50);}
}
Serial.println();
串口打印行
3. 讀取DHT11的數據
{
#include <DHT.h>// 定義DHT11傳感器連接的引腳#define DHTPIN D2? ? ?#define DHTTYPE DHT11? // 使用的是DHT11傳感器// 初始化DHT傳感器DHT dht(DHTPIN,DHTTYPE);void setup() {Serial.begin(115200);? // 初始化串口通信,波特率9600dht.begin();? ? ? ? ?// 初始化DHT傳感器Serial.println("DHT11溫濕度傳感器測試");Serial.println("正在讀取數據...");}void loop() {// 等待2秒再讀取一次數據,DHT傳感器需要時間穩定delay(2000);// 讀取濕度數據float humi = dht.readHumidity();// 讀取溫度數據float temp= dht.readTemperature();// 檢查是否讀取失敗if (isnan(humi) || isnan(temp)) {Serial.println("讀取傳感器數據失敗!");return;}// 通過串口輸出溫濕度數據Serial.print("濕度: ");Serial.print(humi);Serial.print("%? ");Serial.print("溫度: ");Serial.print(temp);Serial.println("°C");}
}
采用Arduino IDE自帶的DHT11庫
DHT dht(DHTPIN,DHTTYPE);
將傳感器的引腳和型號信息傳遞給 DHT 類
Isnan
主要功能是檢查一個浮點型(float 或 double)變量是否包含有效的數值。如果變量的值是 NaN(表示無效或未定義的數值),isnan() 會返回 true;如果是有效的數字,則返回 false。
三:網絡連接與通信
1. 連接wifi
{
#include <ESP8266WiFi.h>const char* ssid="ESP8266"; //WIFI賬號const char* password="123456789";//密碼void setup() {// put your setup code here, to run once:Serial.begin(115200); //初始化串口delay(10);Serial.println();Serial.print("正在連接到:");Serial.println(ssid);WiFi.begin(ssid,password); //啟動wifi連接int timeout=60; //判斷超時while(WiFi.status()!=WL_CONNECTED && timeout>0){delay(500);timeout--;Serial.print(".");}if(timeout!=0) //不為0就是成功{Serial.println("");Serial.println("WiFi連接成功!");Serial.print("IP地址:");Serial.print(WiFi.localIP());}else{ //為0就是失敗Serial.println("");Serial.println("WiFi連接超時!");}}void loop() {// put your main code here, to run repeatedly:if(WiFi.status()!=WL_CONNECTED)//不是成功就是斷開{Serial.println("WiFi斷開,嘗試重新連接");WiFi.reconnect(); //重連delay(5000);}delay(10000);}
}
2. 創建TCP客戶端和服務端
TCP客戶端
{
這段代碼實現了一個基于ESP8266的TCP客戶端,它能夠:
- 連接到指定的WiFi網絡
- 連接到指定的TCP服務器(IP和端口)
- 向服務器發送消息
- 等待并接收服務器的響應
- 處理超時情況
- 定期重復上述過程
/*TCP客戶端*/#include <ESP8266WiFi.h>const char* ssid="ESP8266";const char* password="123456789";//服務器配置const char* host="192.168.60.14";const int port=8000;void setup() {// put your setup code here, to run once:Serial.begin(115200);delay(10);Serial.println();Serial.print("正在連接到:");Serial.println(ssid);WiFi.begin(ssid,password);int timeout=60;while(WiFi.status()!=WL_CONNECTED && timeout>0){delay(500);timeout--;Serial.print(".");}if(timeout!=0){Serial.println("");Serial.println("WiFi連接成功!");Serial.print("IP地址:");Serial.print(WiFi.localIP());}else{Serial.println("");Serial.println("WiFi連接超時!");}}void loop() {// put your main code here, to run repeatedly:if(WiFi.status()!=WL_CONNECTED){Serial.println("WiFi斷開,嘗試重新連接");WiFi.reconnect();delay(5000);}Serial.print("連接到服務器!");Serial.print(host);Serial.print(":");Serial.println(port);//使用WiFiClient創建TCP連接WiFiClient client;if(!client.connect(host,port)){Serial.println("連接失敗!");delay(500);return;}Serial.println("連接成功!");//發送一條消息String message="Hello from ESP8266 - "+String(millis());client.println(message);Serial.println("發送:"+message);//等待服務器的恢復unsigned long timeout=millis();while(client.available()==0){if(millis()-timeout>5000){Serial.println("超時:服務器無響應!");client.stop();delay(5000);return;}}//讀取所有來自服務器的回復Serial.println("收到回復:");while(client.available()){String line=client.readStringUntil('\r');Serial.print(line);}//關閉連接client.stop();Serial.println();Serial.println("連接關閉");delay(10000); // 短暫延遲}
print():僅打印內容,不自動換行。
println():打印內容 + 自動換行(添加 \n)
millis()
獲得啟動時間millis() 是獲取設備啟動時間的 “標準工具”
WiFiClient client?- 創建TCP客戶端對象
client.connect(host, port)?- 連接到服務器
client.println(message)?- 向服務器發送數據
client.available()?- 檢查是否有數據可讀
client.readStringUntil('\r')?- 讀取數據直到回車符
客戶端啟動后,會每10秒執行一次以下操作:
- 嘗試連接到服務器
- 發送一條包含時間戳的消息
- 等待服務器響應(最多5秒)
- 讀取并打印服務器響應
- 關閉連接
流程圖:
}
TCP服務器
{
這段代碼實現了一個基于ESP8266的TCP服務器,它能夠:
- 連接到指定的WiFi網絡
- 在端口8000上啟動TCP服務器
- 監聽并接受客戶端的連接
- 與客戶端進行雙向通信
- 處理客戶端發送的命令
#include <ESP8266WiFi.h>const char* ssid="ESP8266";const char* password="123456789";//在端口8000上創建TCP服務器WiFiServer server(8000);void setup() {// put your setup code here, to run once:Serial.begin(115200);delay(10);Serial.println();Serial.print("正在連接到:");Serial.println(ssid);WiFi.begin(ssid,password);int timeout=60;while(WiFi.status()!=WL_CONNECTED && timeout>0){delay(500);timeout--;Serial.print(".");}if(timeout!=0){Serial.println("");Serial.println("WiFi連接成功!");Serial.print("IP地址:");Serial.print(WiFi.localIP());//啟動TCP服務器server.begin();Serial.println("TCP服務器已啟動!");Serial.print("監聽端口:");Serial.println(8000);}else{Serial.println("");Serial.println("WiFi連接超時!");}}void loop() {// put your main code here, to run repeatedly:if(WiFi.status()!=WL_CONNECTED){Serial.println("WiFi斷開,嘗試重新連接");WiFi.reconnect();delay(5000);}//檢查是否有客戶端連接WiFiClient client=server.available();if (client) {Serial.println("新的客戶端連接");// 客戶端連接時的時間String currentTime = String(millis());// 向客戶端發送歡迎消息client.println("歡迎連接到ESP8266 TCP服務器!");client.println("當前時間(毫秒): " + currentTime); // 發送連接時間client.println("輸入'bye'斷開連接");// 處理客戶端數據while (client.connected()) {if (client.available()) {// 讀取客戶端發送的數據,直到遇到回車符('\r')String line = client.readStringUntil('\r');line.trim();? ? ?// 去除字符串前后的空格和換行符Serial.print("收到數據: ");Serial.println(line);if (line == "bye") {client.println("再見!");break;} else if (line.length() > 0) {// 回顯接收到的數據client.println("回聲: " + line);}}}// 關閉連接client.stop();Serial.println("客戶端斷開連接");}delay(100); // 短暫延遲}
WiFiServer server(8000)?- 創建在端口8000上監聽的TCP服務器
server.begin()?- 啟動TCP服務器
server.available()?- 檢查是否有客戶端連接
WiFiClient client?- 表示連接到服務器的客戶端
服務器啟動后,會持續監聽客戶端連接。當客戶端連接時,服務器會:
- 發送歡迎消息
- 進入循環等待客戶端輸入
- 讀取并回顯客戶端發送的數據
- 如果客戶端發送"bye",則關閉連接
流程圖:
}
3. 創建UDP客戶端和服務端
UDP客戶端
{
/*UDP客戶端*/#include <ESP8266WiFi.h>#include <WiFiUdp.h>const char* ssid="ESP8266";const char* password="123456789";//upd配置WiFiUDP udp;unsigned int localPort=8000;//本地監聽端口unsigned int remotePort=9999;//遠程端口const char*? remoteHost="192.168.60.14";//本地主機地址void setup() {// put your setup code here, to run once:Serial.begin(115200);delay(10);Serial.println();Serial.print("正在連接到:");Serial.println(ssid);WiFi.begin(ssid,password);int timeout=60;while(WiFi.status()!=WL_CONNECTED && timeout>0){delay(500);timeout--;Serial.print(".");}if(timeout!=0){Serial.println("");Serial.println("WiFi連接成功!");Serial.print("IP地址:");Serial.print(WiFi.localIP());// 啟動UDPudp.begin(localPort);Serial.print("UDP客戶端已啟動,監聽端口: ");Serial.println(localPort);}else{Serial.println("");Serial.println("WiFi連接超時!");}}void loop() {// put your main code here, to run repeatedly:if(WiFi.status()!=WL_CONNECTED){Serial.println("WiFi斷開,嘗試重新連接");WiFi.reconnect();delay(5000);}//發送UPD數據包Serial.println("發送UDP數據包...");udp.beginPacket(remoteHost,remotePort);udp.println("Hello from ESP8266 UDP Client - " + String(millis()));udp.endPacket();Serial.println("數據包已發送");//檢查是否有收到數據包int packetSize=udp.parsePacket();//獲取包的大小if(packetSize){Serial.print("接收來自");Serial.print(udp.remoteIP());Serial.print(":");Serial.print(udp.remotePort());? // 打印發送方端口Serial.print(" 的數據,大小:");Serial.println(packetSize);//讀取數據包的內容// char packetBuffer[255];// int len=upd.read(packetBuffer,255);//從 UDP 連接中讀取數據并存儲到緩沖區// if(len>0)// {//? ?packetBuffer[len]=0;//在接收到的數據末尾添加空字符 \0// }// Serial.print("內容: ");// Serial.println(packetBuffer);String reply = udp.readStringUntil('\n');? // 讀取到換行符為止Serial.print("收到回復:");Serial.println(reply);}delay(5000); // 短暫延遲}
}
UDP服務器
{
/*ESP8266 UDP服務器功能:監聽8000端口,接收客戶端數據并回復,支持WiFi重連*/#include <ESP8266WiFi.h>#include <WiFiUdp.h>const char* ssid="ESP8266";const char* password="123456789";//UDP配置WiFiUDP udpServer;unsigned int udpPort=8000; //UDP服務器監聽端口IPAddress serverIP;? ? ? ? // 存儲服務器IPvoid setup() {// put your setup code here, to run once:Serial.begin(115200);delay(10);Serial.println();Serial.print("正在連接到:");Serial.println(ssid);WiFi.begin(ssid,password);int timeout=60;while(WiFi.status()!=WL_CONNECTED && timeout>0){delay(500);timeout--;Serial.print(".");}if(timeout!=0){Serial.println("");Serial.println("WiFi連接成功!");Serial.print("IP地址:");Serial.print(WiFi.localIP());serverIP = WiFi.localIP();//啟動UDP服務器if (udpServer.begin(udpPort)) {? // 綁定端口并啟動Serial.println("UDP服務器已啟動!");Serial.print("監聽端口:");Serial.println(udpPort);} else {Serial.println("UDP服務器啟動失敗!");}}else{Serial.println("");Serial.println("WiFi連接超時!");}}void loop() {// put your main code here, to run repeatedly://檢查是否有客戶端發送UDP數據包int packetSize=udpServer.parsePacket();//獲取數據包的大小if(packetSize>0)//有數據{//讀取客戶端數據IPAddress clientIP=udpServer.remoteIP();//客戶端IPunsigned int clientPort=udpServer.remotePort();//客戶端的端口號Serial.println("\n【收到新數據】");Serial.print("客戶端IP:");Serial.println(clientIP);Serial.print("客戶端端口:");Serial.println(clientPort);Serial.print("數據大小:");Serial.print(packetSize);Serial.println(" 字節");char dataBuffer[255];//緩沖區int dataLen=udpServer.read(dataBuffer,sizeof(dataBuffer)-1);if(dataLen>0){dataBuffer[dataLen]='\0';//添加結束字符Serial.print("數據內容:");Serial.println(dataBuffer);}// 回復內容:包含服務器信息和客戶端發送的內容String replyMsg = "ESP8266服務器已收到:" + String(dataBuffer)?+ "服務器IP:" + serverIP.toString();// 向客戶端發送回復(需指定客戶端的IP和端口)udpServer.beginPacket(clientIP, clientPort); // 開始構建回復數據包udpServer.print(replyMsg);? ? ? ? ? ? ? ? ? // 寫入回復內容udpServer.endPacket();? ? ? ? ? ? ? ? ? ? ? // 發送回復(UDP無連接,無需建立連接)Serial.print("已回復客戶端:");Serial.println(replyMsg);}delay(100); // 短暫延遲}
}