esp8266学习
文章目录
- esp8266学习
-
- 一.环境配置
-
- [1.安装arduino IDE](#1.安装arduino IDE)
- 2.配置ESP8266开发板
- 二.程序案例
-
- 1.点灯大师
- 2.连接wifi
- 3.发布热点
- [4.AP+STA 双模(连接+发布)](#4.AP+STA 双模(连接+发布))
- 5.网页控制IO
- 6.PyQT上位机控制
一.环境配置
1.安装arduino IDE
2.配置ESP8266开发板
到下面网站下载安装包如图:

双击软件运行,等待安装完毕即可;

引脚对应表:
| 物理硬件 GPIO 编号 | Arduino IDE 中使用的数字序号 | 引脚功能说明 & 备注(重点) |
|---|---|---|
| GPIO0 | 2 | ✅ 常用 IO 口,烧录时需接地 (GND),烧录完成后接高电平 / 悬空 |
| GPIO1 | 1 | TX 串口发送脚,下载程序时占用,慎用(会和串口打印冲突) |
| GPIO2 | 4 | ✅ 常用 IO 口,上电默认高电平,可直接接 LED,不影响烧录 |
| GPIO3 | 3 | RX 串口接收脚,下载程序时占用,慎用 |
| GPIO4 | 2 | ✅ 常用 IO 口,无特殊限制,可做普通 IO/PWM |
| GPIO5 | 14 | ✅ 常用 IO 口,无特殊限制,可做普通 IO/PWM |
| GPIO9 | 3 | 极少用,部分模块为闪存引脚,不建议外接 |
| GPIO10 | 1 | 极少用,部分模块为闪存引脚,不建议外接 |
| GPIO12 | 6 | ✅ 常用 IO 口,无特殊限制,可做普通 IO/PWM |
| GPIO13 | 7 | ✅ 常用 IO 口,无特殊限制,可做普通 IO/PWM |
| GPIO14 | 5 | ✅ 常用 IO 口,无特殊限制,可做普通 IO/PWM |
| GPIO15 | 8 | ✅ 常用 IO 口,上电默认低电平,烧录时必须悬空 / 接高电平 |
| D0 / GPIO16 | 0 | ✅ 特殊常用 IO 口,仅支持输入 / 输出 ,不支持中断 / PWM |
二.程序案例
1.点灯大师
选择开发板和端口

打开例子

C++
/*
点灯程序,这里主要开发板的led灯连接的io口,默认是GPIO 0
*/
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
编译并上传

2.连接wifi
C++
// 必须引入的核心库,ESP8266的WiFi功能都依赖这个库
#include <ESP8266WiFi.h>
// ====================== 配置你的WiFi信息 ======================
const char* wifi_SSID = "realme GT Neo5"; // WiFi名称(SSID),区分大小写!
const char* wifi_Password = "b27qff39"; // WiFi密码,无密码则留空 ""
// ==============================================================
void setup() {
// 初始化串口监视器,波特率115200,用于查看连接日志
Serial.begin(115200);
// 等待串口初始化完成
delay(10);
// 断开ESP8266可能已连接的旧WiFi(防止残留连接影响)
WiFi.disconnect(true);
// 设置ESP8266为【站点模式】= 连接路由器/热点(ESP8266有2种WiFi模式)
// STA模式:连接别人的WiFi;AP模式:自己创建WiFi热点
WiFi.mode(WIFI_STA);
// 开始连接配置好的WiFi
WiFi.begin(wifi_SSID, wifi_Password);
Serial.println("\n正在连接 WiFi...");
// 循环等待WiFi连接成功,超时10秒防止卡死
int wifi_wait_time = 0;
while (WiFi.status() != WL_CONNECTED && wifi_wait_time < 20) {
delay(500);
Serial.print(".");
wifi_wait_time++;
}
// 判断WiFi连接结果
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\n✅ WiFi连接成功!");
Serial.print("📶 ESP8266的IP地址:");
Serial.println(WiFi.localIP()); // 打印ESP8266分配到的局域网IP地址
Serial.print("📡 连接的WiFi名称:");
Serial.println(WiFi.SSID()); // 打印当前连接的WiFi名称
} else {
Serial.println("\n❌ WiFi连接失败!");
Serial.println("原因:密码错误 / WiFi名称错误 / 信号差 / 超时");
}
}
void loop() {
// 主循环:连接成功后可在这里写你的业务逻辑(比如数据上传、TCP通信等)
// 如果WiFi意外断开,自动重新连接
if (WiFi.status() != WL_CONNECTED) {
Serial.println("\n⚠️ WiFi已断开,正在重新连接...");
WiFi.reconnect();
delay(1000);
}
}
效果:
注意:改成自己的wifi名称和热点,我试着连接5G wifi连接不上,用手机热点可以。

3.发布热点
代码:
C++
#include <ESP8266WiFi.h> // ESP8266无线功能核心库,必须引入
// ====================== 配置你的热点信息 ======================
const char* AP_SSID = "ESP8266_MyWiFi"; // 你要创建的WiFi热点名称,自定义
// 无密码,这里留空即可
const char* AP_Password = "";
// ==============================================================
void setup() {
// 初始化串口,波特率115200,用于查看热点信息
Serial.begin(115200);
delay(100);
// 核心配置:设置ESP8266为【纯AP模式】,只创建热点,不连接其他WiFi
WiFi.mode(WIFI_AP);
// 核心函数:启动WiFi热点,传入 热点名称+密码
WiFi.softAP(AP_SSID, AP_Password);
// 热点创建成功后,打印关键信息
Serial.println("\n✅ ESP8266 WiFi热点已开启!");
Serial.print("📡 热点名称:");
Serial.println(AP_SSID);
Serial.print("🔑 热点密码:无密码");
Serial.print("\n📶 ESP8266的AP模式IP地址:");
Serial.println(WiFi.softAPIP()); // AP模式固定默认IP: 192.168.4.1 非常重要!
}
void loop() {
// 主循环可写业务逻辑,比如TCP服务、UDP通信、网页配网等
// 打印当前连接到热点的设备数量
Serial.printf("\n当前连接设备数:%d 台\n", WiFi.softAPgetStationNum());
delay(2000);
}
效果:

4.AP+STA 双模(连接+发布)
代码:
C++
#include <ESP8266WiFi.h>
// ====================== 双模式配置信息 ======================
// ★ 配置1:要创建的ESP8266热点信息(AP模式)
const char* AP_SSID = "ESP8266_AP";
const char* AP_Password = "87654321";
// ★ 配置2:要连接的路由器WiFi信息(STA模式)
const char* STA_SSID = "realme GT Neo5";
const char* STA_Password = "b27qff39";
// ==============================================================
void setup() {
Serial.begin(115200);
delay(100);
// 核心配置:设置为【AP+STA 双模】,同时开启两种模式
WiFi.mode(WIFI_AP_STA);
// 第一步:启动自身WiFi热点
WiFi.softAP(AP_SSID, AP_Password);
// 第二步:连接外部路由器WiFi
WiFi.begin(STA_SSID, STA_Password);
Serial.println("\n正在连接路由器WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// 打印双模的所有关键信息
Serial.println("\n✅ ESP8266 AP+STA 双模已全部启动成功!");
// AP模式(热点)信息
Serial.print("📡 自身热点名称:"); Serial.println(AP_SSID);
Serial.print("🔑 热点密码:"); Serial.println(AP_Password);
Serial.print("📶 AP模式IP地址:"); Serial.println(WiFi.softAPIP());
// STA模式(连路由器)信息
Serial.print("\n📡 已连接路由器:"); Serial.println(STA_SSID);
Serial.print("📶 STA模式IP地址:"); Serial.println(WiFi.localIP());
}
void loop() {
// 打印连接到热点的设备数 + 检测路由器WiFi是否断线
Serial.printf("连接到热点的设备数:%d | 路由器连接状态:%s\n",
WiFi.softAPgetStationNum(),
WiFi.status() == WL_CONNECTED ? "已连接" : "已断开");
delay(3000);
// 断线自动重连路由器WiFi
if (WiFi.status() != WL_CONNECTED) {
WiFi.reconnect();
Serial.println("⚠️ 路由器WiFi断开,正在重连...");
}
}
效果:

5.网页控制IO
代码:
C++
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
// ====================== 【必须修改的配置项 3处】 ======================
const char* wifi_SSID = "realme GT Neo5"; // 电脑和ESP8266都连这个WiFi
const char* wifi_Password = "b27qff39"; // 你的WiFi密码,无密码则填""
const int controlPin = 2; // 要控制的GPIO引脚,默认D4(NodeMCU板载LED),可改D1/D2/D3等
// =====================================================================
// 创建Web服务器对象,端口固定为80(网页访问默认端口)
ESP8266WebServer esp8266_server(80);
// 引脚初始状态:默认低电平(关灯)
bool pinState = LOW;
// 处理根路径访问 (浏览器输入ESP8266的IP时,加载网页)
void handleRoot() {
// 更新最新的引脚状态
pinState = digitalRead(controlPin);
// 构建网页内容:HTML网页,包含开关按钮+状态显示,电脑浏览器直接渲染
String htmlPage = "<!DOCTYPE HTML><html>";
htmlPage += "<head><meta charset='UTF-8'><title>ESP8266 GPIO控制</title></head>";
htmlPage += "<body style='text-align:center;margin-top:50px;font-size:24px;'>";
htmlPage += "<h1>ESP8266 网页控制GPIO</h1>";
// 显示当前引脚状态:根据pinState显示【开/关】+ 不同颜色
htmlPage += "<h2 style='color:" + String(pinState ? "green" : "red") + ";'>";
htmlPage += "当前状态:" + String(!pinState ? "✅ 已打开 (高电平 HIGH)" : "❌ 已关闭 (低电平 LOW)");
htmlPage += "</h2><br>";
// 两个按钮:点击后发送指令到对应的路由地址 /on 和 /off
htmlPage += "<a href=\"/off\"><button style='width:150px;height:60px;font-size:20px;background:green;color:white;border:none;border-radius:8px;margin:10px;'>开灯 (HIGH)</button></a>";
htmlPage += "<a href=\"/on\"><button style='width:150px;height:60px;font-size:20px;background:red;color:white;border:none;border-radius:8px;margin:10px;'>关灯 (LOW)</button></a>";
htmlPage += "</body></html>";
// 向浏览器发送构建好的网页
esp8266_server.send(200, "text/html", htmlPage);
}
// 处理【开灯】请求:GPIO置高电平
void handleOn() {
digitalWrite(controlPin, HIGH);
pinState = HIGH;
esp8266_server.sendHeader("Location", "/"); // 跳转回根页面,刷新状态
esp8266_server.send(302);
}
// 处理【关灯】请求:GPIO置低电平
void handleOff() {
digitalWrite(controlPin, LOW);
pinState = LOW;
esp8266_server.sendHeader("Location", "/"); // 跳转回根页面,刷新状态
esp8266_server.send(302);
}
// 处理404页面:访问不存在的地址时返回
void handleNotFound() {
esp8266_server.send(404, "text/plain", "404 页面不存在");
}
void setup() {
// 初始化串口,波特率115200,用于查看日志和IP地址
Serial.begin(115200);
delay(10);
// 初始化控制引脚为【输出模式】
pinMode(controlPin, OUTPUT);
digitalWrite(controlPin, pinState); // 初始化引脚状态
// 连接WiFi
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_SSID, wifi_Password);
Serial.println("\n正在连接 WiFi: " + String(wifi_SSID));
// 等待WiFi连接成功
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// WiFi连接成功,打印关键信息
Serial.println("\n✅ WiFi连接成功!");
Serial.print("📶 ESP8266的局域网IP地址:");
Serial.println(WiFi.localIP()); // 【重中之重】这个IP就是电脑浏览器要输入的地址
Serial.println("💻 操作:电脑浏览器输入上方IP,即可控制GPIO!");
// 注册网页路由:绑定请求地址和对应的处理函数
esp8266_server.on("/", handleRoot); // 根路径 → 加载网页
esp8266_server.on("/on", handleOn); // /on → 开灯
esp8266_server.on("/off", handleOff); // /off → 关灯
esp8266_server.onNotFound(handleNotFound); // 404页面
// 启动Web服务器
esp8266_server.begin();
Serial.println("✅ ESP8266 Web服务器已启动!");
}
void loop() {
// 核心函数:监听网页客户端的请求,并处理
esp8266_server.handleClient();
}
效果:
ESP8266模块和电脑端同连接一个wifi;
复制下列的IP

在浏览器打开
这时候可以观察到,ESP8266的led灯可以通过网页端控制来开关。

6.PyQT上位机控制
代码:
ESP8266代码:
C++
#include <ESP8266WiFi.h>
// ====================== 配置区(修改成你的信息)======================
const char* wifi_name = "realme GT Neo5"; // 家里路由器的WiFi名
const char* wifi_pwd = "b27qff39"; // 家里路由器的WiFi密码
const uint16_t port = 8888; // TCP端口号,PyQt要和这个一致
#define LED_PIN 2 // ESP8266板载LED引脚(D4),可修改
// ====================================================================
WiFiServer tcpServer(port); // 创建TCP服务器
WiFiClient tcpClient; // 声明TCP客户端对象
void setup() {
pinMode(LED_PIN, OUTPUT); // 设置引脚为输出模式
digitalWrite(LED_PIN, HIGH); // ESP8266板载LED:高电平灭,低电平亮
Serial.begin(115200); // 串口波特率,用于查看日志和IP
WiFi.begin(wifi_name, wifi_pwd); // 连接路由器WiFi
// 等待WiFi连接成功
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// WiFi连接成功,打印信息
Serial.println("");
Serial.println("✅ WiFi连接成功!");
Serial.print("✅ ESP8266的局域网IP地址:");
Serial.println(WiFi.localIP()); // 重点!复制这个IP,填到PyQt里
Serial.println("✅ TCP服务器已启动,端口号:8888");
tcpServer.begin(); // 启动TCP服务器
}
void loop() {
// 检测是否有新的客户端连接(PyQt连接)
tcpClient = tcpServer.available();
if (tcpClient) {
Serial.println("✅ 检测到新客户端连接!");
// 保持连接,持续监听指令
while (tcpClient.connected()) {
if (tcpClient.available() > 0) { // 检测是否有指令发送过来
String cmd = tcpClient.readStringUntil('\n'); // 读取指令,以换行符结束
cmd.trim(); // 去除空格和换行符,避免指令识别错误
Serial.print("📥 收到指令:");
Serial.println(cmd);
// 解析指令,控制LED
if (cmd == "ON") {
digitalWrite(LED_PIN, LOW); // 点亮LED
tcpClient.println("✅ LED已点亮"); // 向PyQt返回状态
}
else if (cmd == "OFF") {
digitalWrite(LED_PIN, HIGH); // 熄灭LED
tcpClient.println("✅ LED已熄灭"); // 向PyQt返回状态
}
else{
tcpClient.println("❌ 未知指令!");
}
}
}
// 客户端断开连接
tcpClient.stop();
Serial.println("❌ 客户端已断开连接!");
}
delay(10);
}
Pyqt5的代码:
安装库 pip3 install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple
python
import sys
import socket
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QLineEdit,
QPushButton, QTextEdit, QVBoxLayout, QHBoxLayout, QMessageBox)
from PyQt5.QtCore import Qt
# ====================== 配置区 ======================
TCP_PORT = 8888 # 必须和ESP8266的端口号一致
# ====================================================
class ESP8266_LED_Control(QWidget):
def __init__(self):
super().__init__()
self.tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_client.settimeout(3) # 连接超时3秒
self.is_connected = False # 标记是否连接成功
self.esp8266_ip = "" # ESP8266的IP地址
self.init_ui() # 初始化界面
def init_ui(self):
# 设置窗口标题和大小
self.setWindowTitle('PyQt控制ESP8266 LED')
self.resize(400, 300)
# 1. IP输入区域
self.ip_label = QLabel("ESP8266局域网IP:")
self.ip_edit = QLineEdit()
self.ip_edit.setPlaceholderText("例如:192.168.96.41")
self.ip_edit.setText("192.168.96.41") # 默认IP,可修改成你的ESP8266 IP
self.connect_btn = QPushButton("连接ESP8266")
self.connect_btn.clicked.connect(self.connect_esp8266)
ip_layout = QHBoxLayout()
ip_layout.addWidget(self.ip_label)
ip_layout.addWidget(self.ip_edit)
ip_layout.addWidget(self.connect_btn)
# 2. LED控制按钮区域
self.on_btn = QPushButton("点亮LED")
self.on_btn.clicked.connect(self.send_on_cmd)
self.on_btn.setEnabled(False) # 未连接时禁用
self.off_btn = QPushButton("熄灭LED")
self.off_btn.clicked.connect(self.send_off_cmd)
self.off_btn.setEnabled(False) # 未连接时禁用
btn_layout = QHBoxLayout()
btn_layout.addWidget(self.on_btn)
btn_layout.addWidget(self.off_btn)
# 3. 状态显示区域
self.status_label = QLabel("设备状态:未连接")
self.status_text = QTextEdit()
self.status_text.setReadOnly(True) # 只读,不能编辑
self.status_text.append("📌 等待连接ESP8266...")
# 整体布局
main_layout = QVBoxLayout()
main_layout.addLayout(ip_layout)
main_layout.addLayout(btn_layout)
main_layout.addWidget(self.status_label)
main_layout.addWidget(self.status_text)
self.setLayout(main_layout)
# 连接ESP8266的TCP服务器
def connect_esp8266(self):
self.esp8266_ip = self.ip_edit.text().strip()
if not self.esp8266_ip:
QMessageBox.warning(self, "警告", "请输入ESP8266的IP地址!")
return
try:
# 连接TCP服务器
self.tcp_client.connect((self.esp8266_ip, TCP_PORT))
self.is_connected = True
self.connect_btn.setText("已连接")
self.connect_btn.setEnabled(False)
self.on_btn.setEnabled(True)
self.off_btn.setEnabled(True)
self.status_label.setText(f"设备状态:已连接 {self.esp8266_ip}")
self.status_text.append(f"✅ 成功连接到 {self.esp8266_ip}:{TCP_PORT}")
except Exception as e:
self.is_connected = False
QMessageBox.critical(self, "错误", f"连接失败!\n原因:{str(e)}")
self.status_text.append(f"❌ 连接失败:{str(e)}")
# 发送点亮指令 ON
def send_on_cmd(self):
self.send_cmd("ON")
# 发送熄灭指令 OFF
def send_off_cmd(self):
self.send_cmd("OFF")
# 通用指令发送函数
def send_cmd(self, cmd):
if not self.is_connected:
QMessageBox.warning(self, "警告", "未连接到ESP8266!")
return
try:
# 发送指令,必须加换行符 \n !和ESP8266的readStringUntil('\n')对应
self.tcp_client.send((cmd + "\n").encode("utf-8"))
self.status_text.append(f"📤 发送指令:{cmd}")
# 接收ESP8266返回的状态
recv_data = self.tcp_client.recv(1024).decode("utf-8").strip()
self.status_text.append(f"📥 设备回复:{recv_data}")
except Exception as e:
self.is_connected = False
self.connect_btn.setText("重新连接")
self.connect_btn.setEnabled(True)
self.on_btn.setEnabled(False)
self.off_btn.setEnabled(False)
self.status_label.setText("设备状态:已断开")
QMessageBox.critical(self, "错误", f"发送失败/连接断开!\n原因:{str(e)}")
self.status_text.append(f"❌ {str(e)}")
# 窗口关闭时,断开TCP连接
def closeEvent(self, event):
if self.is_connected:
self.tcp_client.close()
event.accept()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ESP8266_LED_Control()
window.show()
sys.exit(app.exec_())
效果

上位机

