ESP8266(esp-01s) 继电器控制灯具项目

第一步:环境准备

  1. 安装 ESP-IDF:确保你已正确安装 ESP-IDF 环境,并且已支持 ESP8266。

    • 官方安装指南:ESP-IDF 获取和安装
    • 重要:ESP8266 支持需要 IDF 版本 v4.4 或更高。安装时通常需要手动添加 ESP8266 支持:
    bash 复制代码
    cd $IDF_PATH
    ./install.sh esp8266   # 在安装时添加目标,或者使用 install.bat (Windows)
    . ./export.sh          # 激活环境 (Linux/macOS),或 export.bat (Windows)
  2. 确认环境:打开终端(或 ESP-IDF Command Prompt),运行以下命令确认 ESP8266 已就绪:

    css 复制代码
    idf.py --version
    idf.py --list-targets | grep esp8266 # 应该能看到 esp8266 在列表中

第二步:创建项目

我们将从一个简单的示例项目开始修改。

  1. 创建项目目录

    bash 复制代码
    mkdir ~/esp/esp8266_relay_control
    cd ~/esp/esp8266_relay_control
  2. 复制示例项目 (推荐从 hello_world 开始):

    bash 复制代码
    cp -r $IDF_PATH/examples/get-started/hello_world/* .
  3. 初始化项目为 ESP8266

    arduino 复制代码
    idf.py set-target esp8266

    这个命令会创建必要的配置文件,并将项目目标设置为 ESP8266。

第三步:编写代码

修改 main/hello_world_main.c 文件,将其重命名为 main/relay_control.c 并替换为以下代码:

c 复制代码
#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"

#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"

#include "driver/gpio.h"

// 项目配置(这些将在 menuconfig 中设置)
#define RELAY_GPIO CONFIG_RELAY_GPIO
#define PORT CONFIG_TCP_PORT

static const char *TAG = "relay_control";

// 继电器控制函数
static void relay_init(void) {
    gpio_config_t io_conf = {};
    io_conf.intr_type = GPIO_INTR_DISABLE;     // 禁用中断
    io_conf.mode = GPIO_MODE_OUTPUT;           // 设置为输出模式
    io_conf.pin_bit_mask = (1ULL << RELAY_GPIO); // 指定GPIO引脚
    io_conf.pull_down_en = 0;                  // 禁用下拉
    io_conf.pull_up_en = 0;                    // 禁用上拉
    gpio_config(&io_conf);
    
    // 初始状态:关闭继电器
    gpio_set_level(RELAY_GPIO, 0);
    ESP_LOGI(TAG, "Relay initialized on GPIO %d", RELAY_GPIO);
}

static void set_relay_state(int state) {
    gpio_set_level(RELAY_GPIO, state);
    ESP_LOGI(TAG, "Relay set to: %s", state ? "ON" : "OFF");
}

// TCP服务器任务
static void tcp_server_task(void *pvParameters) {
    char rx_buffer[128];
    int addr_family = AF_INET;
    int ip_protocol = IPPROTO_IP;
    
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);
    
    int sock = socket(addr_family, SOCK_STREAM, ip_protocol);
    if (sock < 0) {
        ESP_LOGE(TAG, "Unable to create socket");
        vTaskDelete(NULL);
        return;
    }
    
    // 绑定socket
    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        ESP_LOGE(TAG, "Socket bind failed");
        close(sock);
        vTaskDelete(NULL);
        return;
    }
    
    // 开始监听
    if (listen(sock, 5) < 0) {
        ESP_LOGE(TAG, "Socket listen failed");
        close(sock);
        vTaskDelete(NULL);
        return;
    }
    
    ESP_LOGI(TAG, "TCP server started on port %d", PORT);
    
    while (1) {
        struct sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        int client_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len);
        
        if (client_sock < 0) {
            ESP_LOGE(TAG, "Unable to accept connection");
            continue;
        }
        
        ESP_LOGI(TAG, "Client connected");
        
        // 向客户端发送欢迎消息
        char welcome_msg[] = "ESP8266 Relay Controller. Commands: 'ON', 'OFF'\r\n";
        send(client_sock, welcome_msg, strlen(welcome_msg), 0);
        
        while (1) {
            int len = recv(client_sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
            
            if (len < 0) {
                ESP_LOGE(TAG, "Receive failed");
                break;
            } else if (len == 0) {
                ESP_LOGI(TAG, "Connection closed");
                break;
            } else {
                rx_buffer[len] = '\0'; // 添加字符串结束符
                ESP_LOGI(TAG, "Received: %s", rx_buffer);
                
                // 处理命令
                if (strstr(rx_buffer, "ON")) {
                    set_relay_state(1);
                    send(client_sock, "Relay turned ON\r\n", 17, 0);
                } else if (strstr(rx_buffer, "OFF")) {
                    set_relay_state(0);
                    send(client_sock, "Relay turned OFF\r\n", 18, 0);
                } else {
                    send(client_sock, "Unknown command\r\n", 17, 0);
                }
            }
        }
        
        shutdown(client_sock, 0);
        close(client_sock);
    }
}

void app_main(void) {
    // 初始化NVS
    ESP_ERROR_CHECK(nvs_flash_init());
    
    // 初始化TCP/IP栈
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    
    // 连接WiFi(使用示例组件中的通用函数)
    ESP_ERROR_CHECK(example_connect());
    
    // 初始化继电器GPIO
    relay_init();
    
    // 创建TCP服务器任务
    xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL);
    
    ESP_LOGI(TAG, "Relay control application started");
}

同时,需要修改 main/CMakeLists.txt

erlang 复制代码
idf_component_register(SRCS "relay_control.c"
                    INCLUDE_DIRS "."
                    REQUIRES esp_netif lwip)

这是最关键的一步,配置项目参数。

  1. 打开配置菜单

    复制代码
    idf.py menuconfig
  2. 配置串口烧录参数

    • 导航到 Serial flasher config
    • 设置 Default serial port(你的串口设备,如 /dev/ttyUSB0COM3
    • 根据你的模块设置 Flash Size(通常为 2MB4MB
  3. 配置项目参数

    • 导航到 Example Configuration(如果不存在,需要先创建 main/Kconfig.projbuild 文件)
    • 设置 WiFi SSID(你的WiFi名称)
    • 设置 WiFi Password(你的WiFi密码)
    • 设置 Relay GPIO number(控制继电器使用的GPIO号,如 2
    • 设置 TCP port number(TCP服务器端口,如 3333
  4. 保存并退出

    • S 保存配置
    • Enter 确认文件名
    • Q 退出

创建 main/Kconfig.projbuild 文件(如果不存在):

arduino 复制代码
menu "Example Configuration"

    config ESP_WIFI_SSID
        string "WiFi SSID"
        default "myssid"
        help
            SSID (network name) to connect to.

    config ESP_WIFI_PASSWORD
        string "WiFi Password"
        default "mypassword"
        help
            WiFi password (WPA or WPA2).

    config RELAY_GPIO
        int "Relay GPIO number"
        range 0 16
        default 2
        help
            GPIO number (IOxx) to connect RELAY module.

    config TCP_PORT
        int "TCP port number"
        range 1024 65535
        default 3333
        help
            TCP port number for the server.

endmenu

第五步:编译项目

复制代码
idf.py build

编译成功后会显示类似信息:

arduino 复制代码
Project build complete. To flash, run this command:
../../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800...

第六步:烧录固件

  1. 硬件准备

    • 将 ESP8266 模块连接到电脑(通过 USB-TTL 转换器)
    • 确保 GPIO0 接地以进入下载模式
    • 给模块上电
  2. 执行烧录 (将 PORT 替换为你的实际串口):

    bash 复制代码
    idf.py -p /dev/ttyUSB0 flash      # Linux
    idf.py -p COM3 flash              # Windows
  3. 重置模块

    • 烧录完成后,断开 GPIO0 与地的连接
    • 重启模块(或重新上电)

第七步:监视运行和测试

  1. 打开串口监视器

    bash 复制代码
    idf.py -p /dev/ttyUSB0 monitor    # Linux
    idf.py -p COM3 monitor            # Windows
  2. 观察日志:你应该能看到:

    • 继电器初始化信息
    • WiFi 连接过程
    • 获取到的 IP 地址
    • TCP 服务器启动信息
  3. 测试控制

    • 使用网络调试工具(如 NetAssist、TCP/UDP 调试助手)
    • 连接到 ESP8266 的 IP 地址和配置的端口(如 192.168.1.100:3333
    • 发送 ON 打开继电器,发送 OFF 关闭继电器

一键编译烧录监视

bash 复制代码
idf.py -p /dev/ttyUSB0 flash monitor

这样就完成了整个 ESP8266 继电器控制项目的创建、配置、编译和烧录流程!

核心网络设计模式概览

模式 协议/技术 特点 适用场景 ESP 芯片
直接连接云 Wi-Fi + MQTT/HTTP 响应快,依赖网络和云服务 大家电、智能插座、摄像头 ESP32, ESP8266
局域网中心 Wi-Fi + LAN MQTT 响应极快,网络中断仍可用 本地自动化(灯光、开关) ESP32, ESP8266
混合模式 Wi-Fi + 双MQTT 兼顾本地速度与远程控制 绝大多数智能家居设备 ESP32, ESP8266
低功耗传感 Wi-Fi + ESP-NOW 低功耗,星型网络,简单 电池供电传感器 ESP32, ESP8266
Mesh 覆盖 Wi-Fi Mesh 自组网,无缝覆盖,高可靠性 大户型全屋智能 ESP32 (ESP-WIFI-MESH)
蓝牙辅助 BLE + Wi-Fi 低功耗配网,近距离控制 设备配网、传感器 ESP32

网络我暂时用 局域网中心蓝牙辅助 , 稳定后考虑混合模式低功耗传感 , 最后考虑Mesh 覆盖

相关推荐
回家路上绕了弯1 小时前
ClickHouse 深度解析:从核心特性到实战应用,解锁 OLAP 领域新势能
数据库·后端
xiaok1 小时前
本地用VScode的Live Server监听5500访问页面,ubuntu上不需要在配置5500
后端
雨绸缪1 小时前
ABAP 时间戳
后端
m0_480502641 小时前
Rust 登堂 之 函数式编程(三)
开发语言·后端·rust
艾醒2 小时前
大模型面试题剖析:大模型微调与训练硬件成本计算
人工智能·后端·算法
自由生长20242 小时前
每日知识-设计模式-状态机模式
后端
用户298698530142 小时前
如何使用 Spire.Doc 在 C# 中创建、写入和读取 Word 文档?
后端
林太白2 小时前
项目中的层级模块到底如何做接口
前端·后端·node.js
一枚小小程序员哈2 小时前
基于Android的车位预售预租APP/基于Android的车位租赁系统APP/基于Android的车位管理系统APP
android·spring boot·后端·struts·spring·java-ee·maven
二闹3 小时前
从@Transactional失效场景到传播行为原理
java·后端