案例:ESP32-C3 芯片 WiFi 收发故障排查
标签: 硬件故障排查案例
芯片型号: ESP32-C3
固件版本: MicroPython v1.28.0
串口: COM23
日期: 2026-09-15
一、故障现象
ESP32-C3 模块(COM23)在使用过程中发现 WiFi 功能异常,具体表现为:
- WiFi 扫描正常 --- 能扫描到周围 10+ 个 WiFi 网络,信号强度合理
- 所有网络连接失败 --- 尝试连接 JZFD、GW1500、ts 等多个已知密码的 WiFi 均超时失败
- 扫描结果中信号强度合理 --- 最近的网络 RSSI 可达 -23 ~ -59 dBm
初步判断: 扫描正常说明 RX(接收)通路工作正常;连接失败可能是 TX(发射)通路问题,也可能是软件/固件配置问题。需要逐步排除。
二、排查思路
采用从易到难、从软件到硬件的四步排除法:
| 步骤 | 测试内容 | 目的 | 判定标准 |
|---|---|---|---|
| 1 | 重刷固件 | 排除固件损坏、配置残留问题 | 刷完后故障依旧 → 排除软件 |
| 2 | 多网络连接测试 | 排除单个路由器兼容、密码错误问题 | 多个网络均失败 → 非路由器问题 |
| 3 | AP 模式热点测试 | 绕过连接握手,直接验证 WiFi TX 发射能力 | 手机搜不到热点 → WiFi TX 故障 |
| 4 | 蓝牙 BLE 对比测试 | 验证 2.4G 共用射频前端是否正常,缩小故障范围 | 蓝牙正常 → 仅 WiFi 通路故障 |
三、排查过程
步骤 1:重刷 MicroPython 固件 --- 故障依旧
重刷最新版 MicroPython v1.28.0 固件,彻底清除旧固件和 NVS 配置。刷完后重新运行 WiFi 测试:
- 扫描功能:✅ 正常,发现 2 个网络(JZFD、GW1500)
- 连接 JZFD:❌ 失败,30 秒超时
结论: 排除固件损坏和软件配置问题,故障可能在硬件层面。
步骤 2:多网络连接测试 --- 全部失败
为排除单个路由器兼容性或密码错误,依次尝试连接多个已知密码的 WiFi 网络:
2.1 连接 JZFD(-62 ~ -74 dBm)
python
wlan.connect('JZFD', 'csgl123456')
# 等待 30 秒 -> 连接失败 (超时)
2.2 连接 GW1500(-23 ~ -51 dBm,信号最强)
python
wlan.connect('GW1500', 'csgl123456')
# 等待 15 秒 -> 连接失败 (超时)
2.3 连接 ts(-59 dBm,Windows 已保存密码验证)
python
wlan.connect('ts', 'ts19800309')
# 等待 30 秒 -> 连接失败 (超时)
关键发现: 3 个不同路由器、不同信号强度(-23 ~ -74 dBm)的网络均连接失败,
且
ts的密码通过 Windows 已保存配置验证正确。可以排除密码错误和路由器兼容问题。
步骤 3:AP 模式热点测试 --- TX 故障确认
STA 模式连接失败可能涉及握手协议问题,改为 AP 模式(让 ESP32 自己发热点)可以直接验证 TX 发射通路:
python
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(ssid='ESP32C3_TEST', key='12345678', channel=6)
# AP 状态: active=True
# MAC: 90:da:72:89:84:25
# IP: 192.168.4.1
# 等待 30 秒,设备数始终为 0
用手机和电脑同时搜索 WiFi 列表:
- 手机(iOS/Android)搜不到
ESP32C3_TEST - Windows 电脑也搜不到
ESP32C3_TEST - 同一位置其他 WiFi 网络均正常显示
最终判定: AP 模式下外部设备完全搜不到热点信号,而 ESP32 自身扫描能收到周围网络 --- 说明 RX 接收正常,TX 发射无输出。
结论:WiFi TX 发射通路硬件故障。
步骤 4:蓝牙 BLE 测试 --- 完全正常
ESP32-C3 的 WiFi 和蓝牙共用 2.4GHz 射频前端(天线、匹配电路、部分 PA)。
测试蓝牙可以判断故障是仅 WiFi 通路 还是整个 2.4G 射频。
4.1 BLE 广播与连接测试
python
ble = bluetooth.BLE()
ble.active(True)
# 广播设备名: ESP32C3_BT,间隔 100ms
# 手机可搜索到并稳定连接
- 手机能搜到
ESP32C3_BT广播:✅ 是 - 手机能成功建立连接:✅ 是
- 连接稳定保持 5 分钟以上:✅ 是
4.2 BLE UART 双向收发测试(Nordic UART Service)
使用 NUS(Nordic UART Service)验证 BLE 双向数据收发,确认蓝牙 TX 和 RX 通路完全正常。
测试步骤:
- ESP32-C3 运行
test_ble_uart.py,启动 BLE 广播(设备名:ESP32C3_BT) - 手机安装 nRF Connect APP,扫描并连接
ESP32C3_BT - 找到 Nordic UART Service (UUID 以
6e400001开头) - 点击 TX Characteristic (UUID
6e400003)右侧的 Notify 图标 ⬇️,开启通知接收 - 点击 RX Characteristic (UUID
6e400002)右侧的 Write 图标 ↑,发送测试数据 - 观察 TX Characteristic 是否收到 ESP32 回传的
OK:前缀数据
测试代码(ESP32 端):
python
# NUS 服务 UUID
UART_SERVICE_UUID = bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')
UART_RX_UUID = bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E') # 手机→ESP32
UART_TX_UUID = bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E') # ESP32→手机
# 收到数据后自动回包(加 OK: 前缀)
def _irq(self, event, data):
if event == 3: # WRITE
data_bytes = self.ble.gatts_read(self.rx_handle)
print('[BLE] 收到数据:', data_bytes)
reply = b'OK:' + data_bytes
self._send(reply)
print('[BLE] 已回包:', reply)
测试结果:
| 方向 | 发送内容 | 接收内容 | 结果 |
|---|---|---|---|
| 手机 → ESP32(BLE RX) | tttt |
b'tttt' |
✅ 正常 |
| ESP32 → 手机(BLE TX) | OK:tttt |
OK:tttt |
✅ 正常 |
| 手机 → ESP32(BLE RX) | hello esp32 |
b'hello esp32' |
✅ 正常 |
| ESP32 → 手机(BLE TX) | OK:hello esp32 |
OK:hello esp32 |
✅ 正常 |
![]() |
截图证据:
nRF Connect 截图:RX 发送 "hello esp32",TX 收到 "OK:hello esp32",验证 BLE 双向收发正常
关键结论: 蓝牙 BLE 广播、连接、双向数据收发均正常 → 说明 2.4G 射频前端(天线、匹配、共用 PA)和 BLE 基带完全工作正常 ,故障范围精确锁定在 WiFi 专用发射通路内部。
四、故障定位
4.1 功能矩阵
| 功能 | 状态 | 说明 |
|---|---|---|
| WiFi 扫描(RX) | ✅ 正常 | 能扫描到 10+ 个网络,信号强度合理 |
| WiFi STA 连接(TX+RX) | ❌ 失败 | JZFD / GW1500 / ts 均超时失败 |
| WiFi AP 热点(TX) | ❌ 失败 | 手机、电脑均搜不到 ESP32C3_TEST 热点 |
| BLE 广播(TX) | ✅ 正常 | 手机 nRF Connect 可搜到 ESP32C3_BT |
| BLE 连接(TX+RX) | ✅ 正常 | 连接稳定,可持续 5 分钟以上 |
| BLE 双向数据收发 | ✅ 正常 | NUS 服务收发均正常,手机发"hello esp32"回"OK:hello esp32" |
| MAC 地址 | ✅ 正常 | WiFi: 90:da:72:89:84:24 / BLE: 90:da:72:89:84:26 |
4.2 故障范围定位
| 可能故障点 | 是否可能 | 判断依据 |
|---|---|---|
| 天线 / 天线匹配电路 | ❌ 排除 | 蓝牙完全正常,说明天线和匹配电路无问题 |
| 2.4G 共用 PA | ❌ 排除 | 蓝牙能正常发射信号,共用 PA 工作正常 |
| WiFi 专用 TX 通路 | ⚠️ 高度怀疑 | WiFi TX 完全无输出,WiFi RX 正常,蓝牙正常 |
| WiFi 基带 / 协议栈 | ❌ 基本排除 | 重刷固件后故障依旧,且扫描正常说明基带 RX 工作 |
4.3 射频架构分析:为什么 WiFi TX 故障不影响蓝牙?
ESP32-C3 的 WiFi 和蓝牙虽然"共用射频",但并非所有部件都共享。射频架构是分层共享 的:
天线和最终 PA 是共用的,但调制器是两套独立的硬件电路。

图:ESP32-C3 射频内部架构分层 --- 黄色为共用部件,绿色正常,红色为故障点
| 层级 | 部件 | 共享方式 | 状态 | 判断依据 |
|---|---|---|---|---|
| 第4层 | 天线 + 匹配电路 | 共用 | ✅ 正常 | BLE 能正常收发,证明天线通路完好 |
| 第3层 | 射频前端:天线开关 / Balun / 共用 PA / LNA / 滤波器 | 共用 | ✅ 正常 | BLE TX 正常工作,共用 PA 和 LNA 无问题 |
| 第2层 | 调制器:WiFi (OFDM/DSSS/CCK) vs BLE (GFSK) | 独立 | ❌ WiFi 故障 | WiFi TX 无输出但 BLE TX 正常 → WiFi 调制器或 WiFi TX 专用通路损坏 |
| 第1层 | 基带/MAC:WiFi MAC vs BLE Link Controller | 独立 | ✅ 部分正常 | WiFi 扫描正常说明 WiFi RX 基带正常;BLE 双向都正常 |
关键原理: "共存"≠"所有部件都共享"。ESP32-C3 的共存机制是通过时分复用 快速切换天线和共用 PA 的使用权,
但调制器和基带是两套独立的硬件电路。WiFi 使用 OFDM/DSSS/CCK 调制,BLE 使用 GFSK 调制,
信号产生方式完全不同。因此 WiFi TX 通路损坏不会影响 BLE 的发射功能。
4.4 最可能的硬件故障点
结合 ESP32-C3 的 WiFi/蓝牙射频架构,故障范围已缩小到 WiFi 专用发射通路(第2层及以内):
- 芯片内部 WiFi 调制器损坏 --- 可能性最高。WiFi 和 BLE 调制器独立,WiFi OFDM 调制电路故障无法产生正确的 WiFi 发射信号,但 BLE GFSK 调制不受影响
- WiFi TX 专用通路(WiFi PA 或驱动级) --- WiFi 发射通路的功率放大级损坏,信号无法送达共用 PA 输入端
- WiFi/RF 切换开关(芯片内部) --- 内部 WiFi 侧开关失效,信号无法切换到共用 PA
最终结论: WiFi 专用发射通路硬件故障,蓝牙 BLE 功能完全正常。
故障位置在芯片内部 WiFi 调制器或 WiFi TX 专用通路(非天线、非匹配电路、非共用射频前端)。
建议:更换 ESP32-C3 芯片。
五、测试脚本
5.1 STA 连接测试脚本
python
import network
import time
wlan = network.WLAN(network.STA_IF)
wlan.active(False)
time.sleep(1)
wlan.active(True)
time.sleep(3)
# 扫描
print('扫描网络:')
nets = wlan.scan()
for n in nets:
s = n[0].decode('utf-8','ignore') if isinstance(n[0], bytes) else n[0]
print(f' {s} RSSI={n[3]}dBm')
# 连接
wlan.connect('ts', 'ts19800309')
for i in range(30):
if wlan.isconnected(): break
time.sleep(1)
print('结果:', '成功 IP=' + wlan.ifconfig()[0] if wlan.isconnected() else '失败')
5.2 AP 模式验证脚本
python
import network
import time
import ubinascii
ap = network.WLAN(network.AP_IF)
ap.active(False)
time.sleep(1)
ap.active(True)
ap.config(ssid='ESP32C3_TEST', key='12345678', channel=6)
time.sleep(2)
print('SSID: ESP32C3_TEST 密码: 12345678')
print('MAC:', ubinascii.hexlify(ap.config('mac'), ':').decode())
print('IP:', ap.ifconfig()[0])
print('用手机搜热点,等30秒...')
for i in range(6):
time.sleep(5)
st = ap.status('stations')
print(f' 剩余 {30-(i+1)*5}s 设备数={len(st)}')
# 手机搜不到 -> TX 硬件故障
# 手机能搜到 -> TX 正常,STA连接失败另查原因
5.3 BLE UART 双向收发测试脚本
python
import bluetooth
import time
# UUID
UART_SERVICE_UUID = bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')
UART_RX_UUID = bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E') # 手机→ESP32
UART_TX_UUID = bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E') # ESP32→手机
class BLEUART:
def __init__(self, ble, name='ESP32C3_BT'):
self.ble = ble
self.ble.active(True)
self.ble.config(gap_name=name)
self.ble.irq(self._irq)
self.service = (UART_SERVICE_UUID, (
(UART_RX_UUID, bluetooth.FLAG_WRITE),
(UART_TX_UUID, bluetooth.FLAG_NOTIFY),
))
((self.rx_handle, self.tx_handle),) = self.ble.gatts_register_services((self.service,))
self._connections = set()
self._advertise()
def _irq(self, event, data):
if event == 1: # 连接
conn_handle, _, _ = data
self._connections.add(conn_handle)
print('[BLE] 设备已连接')
elif event == 2: # 断开
conn_handle, _, _ = data
self._connections.discard(conn_handle)
print('[BLE] 设备已断开')
self._advertise()
elif event == 3: # 收到写数据
conn_handle, value_handle = data
if value_handle == self.rx_handle:
data_bytes = self.ble.gatts_read(self.rx_handle)
print('[BLE] 收到数据:', data_bytes)
reply = b'OK:' + data_bytes
for ch in self._connections:
self.ble.gatts_notify(ch, self.tx_handle, reply)
print('[BLE] 已回包:', reply)
def _advertise(self):
payload = bytearray([0x02, 0x01, 0x06])
name = b'ESP32C3_BT'
payload.append(len(name) + 1)
payload.append(0x09)
payload.extend(name)
self.ble.gap_advertise(100, adv_data=payload)
print('[BLE] 广播中')
ble = bluetooth.BLE()
uart = BLEUART(ble)
案例编号:CASE-ESP32C3-WIFI-TX-20260915 | 文档版本:v2.0 | 更新日期:2026-09-15
