esp8266学习(一)

esp8266学习

文章目录

一.环境配置

1.安装arduino IDE

arduino.cc/en/software

2.配置ESP8266开发板

到下面网站下载安装包如图:

软件下载 - Arduino中文社区

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

引脚对应表:

物理硬件 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_())

效果

上位机

相关推荐
weixin_462446239 天前
从零开始:基于 Python PyQt5 打造多功能音乐播放器 | 支持播放、暂停、进度控制与歌词同步
python·音乐播放器·pyqt5
安生生申16 天前
STM32 ESP8266连接ONENET
c语言·stm32·单片机·嵌入式硬件·esp8266
懷淰メ1 个月前
python3GUI--基于YOLOv8深度学习的车牌识别系统(详细图文介绍)
深度学习·opencv·yolo·pyqt·图像识别·车牌识别·pyqt5
゛凌乱的记忆づ1 个月前
esp8266实现mqtt(二)
物联网·esp8266
EleganceJiaBao2 个月前
【ESP8266】使用 ESP8266 + CoolTerm + Packet Sender 构建 TCP 通信的完整调试流程
网络协议·tcp/ip·wi-fi·esp8266·coolterm·packet sender
懷淰メ2 个月前
【AI加持】基于PyQt5+YOLOv8+DeepSeek的太阳能电池板缺陷检测系统(详细介绍)
yolo·目标检测·计算机视觉·pyqt5·检测系统·deepseek·太阳能电池
2401_853448232 个月前
FreeRTOS项目---WiFi模块(2)
stm32·单片机·freertos·esp8266·通信协议
文sir.2 个月前
温湿度采集系统(stm32+mqtt+Onenet云平台+esp8266)
stm32·单片机·嵌入式硬件·mqtt·onenet·云平台·esp8266
2401_853448232 个月前
ESP8266蓝牙模块
stm32·蓝牙模块·esp8266