2025 年最新树莓派 Pico 连接 ESP8266 模块实现 WiFi 通信、搭建 TCP 服务器实现数据交互详细教程

AT 指令基本结构概述

AT 指令最初由 Hayes 公司为其调制解调器(modem)开发,目的是提供一种标准化的方式来控制通信设备。最早的 Hayes Smartmodem 300 调制解调器(1981年)引入了这一指令集,因此 AT 指令也被称为 “Hayes 命令集”。“AT” 是 “Attention” 的缩写,用于唤醒设备并表示后续字符串是一个命令。

随着通信技术的发展,AT 指令被广泛应用于 GSM、GPRS、3G、4G 模块、蓝牙模块、Wi-Fi 模块等领域,成为许多设备的标准通信协议。现代 AT 指令集已由 3GPP(第三代合作伙伴计划)等组织标准化,尤其在移动通信领域。

基本结构

AT<命令>[参数][回车符]

ESP8266 概述

Wi-Fi 模块概述

主要功能:Wi-Fi模块主要用于设备之间的无线通信和连接。它可以使设备能够通过Wi-Fi网络进行数据传输、接入互联网以及与其他Wi-Fi设备进行通信。Wi-Fi模块通常配备有无线接收器和发送器,可以接收来自其他设备或无线路由器的无线信号,并发送数据到目标设备或路由器。

技术标准:Wi-Fi模块遵循IEEE 802.11无线通信标准。不同的Wi-Fi模块可能支持不同的Wi-Fi标准,如802.11a/b/g/n/ac/ax等。这些标准定义了无线信号的频率、传输速率、安全性和其他通信参数,以确保Wi-Fi设备之间的互操作性。

硬件组成:Wi-Fi模块通常由无线芯片、天线、射频前端、处理器和存储器等组成。无线芯片是Wi-Fi模块的核心部件,负责处理无线信号的接收和发送。天线用于接收和发送无线信号。射频前端负责信号的放大和调理。处理器和存储器用于执行无线通信协议、管理数据传输和存储相关配置信息。

软件支持:Wi-Fi模块通常配备有嵌入式软件,用于实现Wi-Fi通信协议栈,处理数据传输和管理网络连接。这些软件通常由供应商提供,并且可以根据需求进行配置和定制。

供电和接口:Wi-Fi模块通常通过供电引脚与外部电源连接,并通过UART、SPI、I2C等接口与主控制器或其他设备进行通信。这些接口使得Wi-Fi模块能够与各种不同类型的设备集成。

应用领域:Wi-Fi模块广泛应用于各种物联网(IoT)设备、智能家居、工业自动化、医疗设备、消费电子产品等领域。它们可以使这些设备实现无线连接、远程控制和互联网接入功能。

ESP8266 概述

在这里插入图片描述

ESP8266 是一款低成本、高性能的 Wi-Fi 模块,由 Espressif Systems 开发。它集成了 Wi-Fi 功能和TCP/IP协议栈,并可通过串口与主控制器进行通信。

ESP 通常指 Espressif Systems 的微控制器系列,包括 ESP8266 和 ESP32。由中国公司Espressif Systems(乐鑫信息科技)开发,成立于2008年,总部位于上海。生产低成本、高性能的 Wi-Fi 和蓝牙 SoC(系统级芯片),广泛用于物联网(IoT)设备。

ESP8266 基础 AT 指令

ESP8266 基础 AT 指令集,用于通过串口控制模块。涵盖了基本配置、Wi-Fi 连接、TCP/IP 通信等操作。配合 115200 波特率 串口工具使用(例如:Arduino IDE 串口监视器、PuTTY 等)。

基本功能

指令功能示例响应
AT测试模块是否正常ATOK
AT+RST重启模块AT+RSTOK + 重启信息
AT+GMR查看固件版本AT+GMR<版本号>\r\nOK
ATE0/ATE1关闭/开启回显ATE0OK

Wi-Fi 模式设置

指令功能示例响应
AT+CWMODE=<mode>设置 Wi-Fi 模式AT+CWMODE=1OK
AT+CWMODE?查询当前模式AT+CWMODE?+CWMODE:<mode>\r\nOK
1:Station 模式(客户端,连接路由器)
2:AP 模式(热点,其他设备可连接)
3:Station+AP 混合模式

在这里插入图片描述

连接 Wi-Fi(Station 模式)

指令功能示例响应
AT+CWLAP扫描附近 APAT+CWLAP返回附近热点列表
AT+CWJAP="SSID","PWD"连接 Wi-FiAT+CWJAP="home","123456"OK(成功时)
AT+CWQAP断开当前 Wi-FiAT+CWQAPOK
AT+CIFSR查询本地 IPAT+CIFSR返回 IP 地址

AP 模式配置(热点)

指令功能示例响应
AT+CWSAP="SSID","PWD",ch,ecn设置 AP 参数AT+CWSAP="ESP","pass",5,3OK
AT+CWLIF查看连接的设备AT+CWLIF返回客户端 IP
ch:信道(1~13)
ecn:加密方式(0-OPEN, 2-WPA_PSK, 3-WPA2_PSK, 4-WPA_WPA2_PSK)

TCP/IP 通信

指令功能示例响应
AT+CIPSTATUS查询连接状态AT+CIPSTATUS返回当前连接信息
AT+CIPSTART="TYPE","IP",port建立 TCP/UDP 连接AT+CIPSTART="TCP","192.168.1.100",80OKERROR
AT+CIPSEND=<length>发送数据AT+CIPSEND=4 > ABCDSEND OK
AT+CIPCLOSE关闭连接AT+CIPCLOSEOK
AT+CIPMUX=<mode>设置连接模式AT+CIPMUX=1OK
0:单连接
1:多连接(需配合 `AT+CIPSERVER` 使用)

HTTP 请求示例

AT+CIPSTART="TCP","www.example.com",80
AT+CIPSEND=48
> GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n
# 返回网页数据后关闭连接
AT+CIPCLOSE

RXD / TXD

TXD(Transmit Data)和 RXD(Receive Data)是串口通信(UART,Universal Asynchronous Receiver / Transmitter)中的两个关键引脚,分别用于数据的发送和接收。TXD 和 RXD 共同实现串口通信的双向数据交换,TXD负责输出,RXD负责输入,是串口通信的基础组件。

TXD(发送数据)

作用:用于设备发送数据到外部设备。
工作原理:当一个设备(例如微控制器或GSM模块)需要向另一设备发送数据时,数据通过TXD引脚以串行形式输出。
示例:微控制器通过TXD发送AT指令到调制解调器。

RXD(接收数据)

作用:用于设备接收来自外部设备的数据。
工作原理:当外部设备通过其TXD引脚发送数据时,目标设备的RXD引脚接收这些数据。
示例:调制解调器通过RXD返回AT指令的响应给微控制器。

一对一通信:TXD 和 RXD 通常以交叉方式连接,即设备 A 的 TXD 连接到设备 B 的 RXD,设备 B 的 TXD 连接到设备 A 的 RXD。

ESP8266 模块工作模式

STA 模式

在此模式下,模块可连接其他设备提供的无线网络,例如通过 WIFI 连接至路由器,从而可以访问互联网,进而实现手机或电脑通过互联网实现对设备的远程控制。

简单来说,此模式下,该模块相当于一个用户,需要链接外部的 WIFI(或自己的热点),通过链接的 WIFI 进行与其他设备的通信。

AP 模式

AP 模式为默认的模式,在此模式下,模块将作为热点供其他设备连接, 从而让手机或电脑直接与模块进行通讯,实现局域网的无线控制。

简单来说,此模式下,该模块相当于提供一个热点,创建一个小范围的局域网,凡是连接上的设备就能与其进行通信。

STA + AP 模式

该模式为 STA 模式与 AP 模式共存的一种模式,模块既能连接至其他 设备提供的无线网络,又能作为热点,供其他设备连接,以实现广域网与局域网的无缝切换, 方便操作使用。

WiFi ESP8266 搭建服务器

pico 端连接 WiFi 启动服务器

import machine
import time

# Initialize UART with larger buffer
uart = machine.UART(0, baudrate=115200, tx=0, rx=1, timeout=100, rxbuf=2048)  # Adjust pins, increase buffer

# Send AT command
def send_cmd(cmd, wait=1000):
    uart.write(cmd + "\r\n")
    time.sleep_ms(wait)
    response = ""
    timeout = time.ticks_ms() + wait
    while time.ticks_ms() < timeout:
        if uart.any():
            data = uart.read()
            if data:  # Check if data is not None
                try:
                    response += data.decode('utf-8')
                except UnicodeError:
                    response += str(data)  # Fallback for non-UTF-8 data
        time.sleep_ms(10)  # Avoid CPU overload
    return response

# Initialize ESP8266
def init_esp8266():
    print("Initializing ESP8266...")
    response = send_cmd("AT", 500)  # Test communication
    if "OK" in response:
        print("AT OK")
    else:
        print("AT failed:", response)
        return False
    send_cmd("AT+CWMODE=1", 500)  # Set to Station mode
    send_cmd("AT+CIPRECVTYPE=0", 500)  # Set to normal data receive mode
    return True

# Connect to WiFi
def connect_wifi(ssid, password):
    print("Connecting to WiFi...")
    response = send_cmd(f'AT+CWJAP="{ssid}","{password}"', 10000)  # Connect to WiFi
    if "OK" in response:
        print("WiFi connected")
        ip_response = send_cmd("AT+CIFSR", 1000)  # Get IP address
        print("IP info:", ip_response)
        return True
    else:
        print("WiFi connection failed:", response)
        return False

# Start TCP server
def start_tcp_server(port=12345):
    print("Starting TCP server...")
    send_cmd("AT+CIPMUX=1", 500)  # Enable multiple connections
    response = send_cmd(f'AT+CIPSERVER=1,{port}', 1000)  # Start server on port
    if "OK" in response:
        print(f"TCP server started on port {port}")
        return True
    else:
        print("Failed to start TCP server:", response)
        return False

# Receive and respond to messages
def handle_tcp_communication():
    print("Listening for messages...")
    buffer = ""  # Buffer to accumulate UART data
    while True:
        if uart.any():
            data = uart.read(uart.any())  # Read exact number of available bytes
            if data:
                try:
                    buffer += data.decode('utf-8')
                except UnicodeError:
                    buffer += str(data)
                    print("Non-UTF-8 data received:", data)

                # Debug: Print raw buffer content
                # print("Raw buffer:", repr(buffer))

                # Clean up CONNECT/CLOSED messages
                buffer = buffer.replace(",CONNECT\r\n", "")
                buffer = buffer.replace(",CLOSED\r\n", "")

                # Process complete +IPD messages
                while "+IPD" in buffer:
                    ipd_start = buffer.find("+IPD")
                    colon_pos = buffer.find(":", ipd_start)
                    if colon_pos == -1:
                        break  # Incomplete +IPD, wait for more data

                    # Extract conn_id and data_len
                    header = buffer[ipd_start:colon_pos]
                    parts = header.split(",")
                    if len(parts) < 3:
                        break  # Invalid +IPD format
                    try:
                        conn_id = parts[1]
                        data_len = int(parts[2].split(":")[0])
                    except (IndexError, ValueError):
                        break  # Malformed header

                    # Check if enough data is available
                    data_start = colon_pos + 1
                    if len(buffer[data_start:]) < data_len:
                        break  # Incomplete data, wait for more

                    # Extract client data
                    client_data = buffer[data_start:data_start + data_len]
                    print(f"Received from conn {conn_id}: {client_data}")

                    # Send response
                    response = f"Echo: {client_data}"
                    send_cmd(f'AT+CIPSEND={conn_id},{len(response)}', 1000)
                    time.sleep_ms(100)  # Ensure ESP8266 processes send command
                    send_cmd(response, 1000)
                    send_cmd(f'AT+CIPCLOSE={conn_id}', 500)  # Close connection
                    print(f"Sent to conn {conn_id}: {response}")

                    # Remove processed data from buffer
                    buffer = buffer[data_start + data_len:]

        time.sleep_ms(10)  # Faster polling for UART data

# Main program
try:
    if init_esp8266():
        # Replace with your WiFi credentials
        if connect_wifi("CMCC-308", "165123308"):
            if start_tcp_server():
                handle_tcp_communication()
except Exception as e:
    print("Error:", e)

PC 测试请求

import socket
import time

# ESP8266 IP and port
ESP8266_IP = "192.168.1.12"  # Update with actual IP from AT+CIFSR
PORT = 12345

def tcp_client():
    # Create socket
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.settimeout(10.0)  # Increase timeout to 10 seconds
    try:
        # Connect to ESP8266
        client.connect((ESP8266_IP, PORT))
        print(f"Connected to {ESP8266_IP}:{PORT}")

        # Send test message
        timestamp = int(time.time())
        message = f"msg:{timestamp} hello world."
        client.send(message.encode('utf-8'))
        print("Sent:", message)

        # Receive response
        data = client.recv(1024)
        print("Received:", data.decode('utf-8'))

    except Exception as e:
        print("Error:", e)
    finally:
        client.close()
        print("Connection closed")

if __name__ == "__main__":
    tcp_client()

运行结果

python .\pc_client.py
Connected to 192.168.1.12:12345
Sent: msg:1746379223 hello world.
Received: Echo: msg:1746379223 hello world.
Connection closed
Initializing ESP8266...
AT OK
Connecting to WiFi...
WiFi connected
IP info: AT+CIFSR
+CIFSR:STAIP,"192.168.1.12"
+CIFSR:STAMAC,"40:91:51:4b:b6:55"

OK

Starting TCP server...
TCP server started on port 12345
Listening for messages...
Received from conn 0: msg:1746379223 hello world.
Sent to conn 0: Echo: msg:1746379223 hello world.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唤醒手腕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值