You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Pico W AP转Station模式WiFi连接失败求助

树莓派Pico W AP模式转Station模式连接WiFi失败

我的树莓派Pico W被配置为AP接入点+Web服务器,用户可通过网页输入目标WiFi的SSID和密码。表单数据能正常传回设备,但关闭AP后无法用给定的SSID和密码连接目标WiFi。除WiFi连接外,其他功能(包括数据回传)均正常,单独测试Station模式连接WiFi是可行的,但结合AP和Web服务流程就失败。

以下是我的代码:

import network
import socket
import re

# Webserver Konfiguration
server_address = ('', 8080)
html = """<!DOCTYPE html>
<html>
<head>
  <title>SSID und Passwort eingeben</title>
<style>
    body {
      text-align: center;
    }
    form {
      display: inline-block;
      margin-top: 50px;
      text-align: left;
    }
    label {
      display: block;
      margin-bottom: 10px;
    }
input[type="text"],
    input[type="password"] {
      width: 250px;
      height: 30px;
      font-size: 16px;
      margin-bottom: 20px;
    }
    input[type="submit"] {
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
      padding: 10px 20px;
    }
    input[type="submit"]:hover {
      background-color: #45a049;
    }
  </style>
</head>
<body>
  <h1>SSID und Passwort eingeben</h1>
  <form method="post" action="/">
    <label for="ssid">SSID:</label>
    <input type="text" id="ssid" name="ssid" required>
    <label for="password">Passwort:</label>
    <input type="password" id="password" name="password" required>
    <br>
    <input type="submit" value="Verbinden">
  </form>
</body>
</html>
"""

# Access Point Konfiguration
ap_ssid = "pico-wifi"
ap_password = "pico-wifi-password"

# Webserver starten
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(server_address)
server_socket.listen(1)
print('Webserver gestartet auf:', server_address)

while True:
    # Access Point starten
    ap = network.WLAN(network.AP_IF)
    ap.config(essid=ap_ssid, password=ap_password)
    ap.active(True)
    print(ap.ifconfig())

    # Auf Verbindungen warten
    print('Warten auf Verbindung...')
    client_socket, client_address = server_socket.accept()

    # HTTP Anfrage empfangen
    request = client_socket.recv(1024)
    request = str(request)

    # SSID und Passwort aus dem Formular auslesen
    ssid_match = re.search("ssid=([^&]+)", request)
    password_match = re.search("password=([^&]+)", request)
    ssid = ssid_match.group(1) if ssid_match else ""
    password = password_match.group(1) if password_match else ""

    # SSID und Passwort auf der Konsole ausgeben
    print('SSID:', ssid)
    print('Passwort:', password)
    
    # HTTP Antwort senden
    response = 'HTTP/1.1 200 OK\nContent-Type: text/html\n\n' + html
    client_socket.send(response.encode('utf-8'))

    # Verbindung zum Access Point trennen
    ap.active(False)
    
    # Versuche, mit dem WLAN zu verbinden
    if ssid and password:
        print('Versuche, mit WLAN zu verbinden...')
        sta_if = network.WLAN(network.STA_IF)
        if not sta_if.isconnected():
            sta_if.active(True)
            sta_if.connect
            
            
            # Versuche, mit dem WLAN zu verbinden
sta = network.WLAN(network.STA_IF)
sta.active(True)
sta.connect(ssid, password)

# Warten, bis die Verbindung hergestellt ist
while not sta.isconnected():
    pass

# Verbindungsinformationen ausgeben
print('Verbunden mit WLAN:', ssid)
print('IP-Adresse:', sta.ifconfig()[0])

问题分析与修复方案

1. 核心逻辑缩进错误

代码后半段的Station连接逻辑完全跳出了while True循环和if ssid and password判断块,导致程序启动时就尝试连接空的SSID/PASSWORD,而非在接收表单数据后执行。

2. 方法调用缺失括号与参数

原代码中sta_if.connect仅引用方法,未实际调用,也未传入SSID和密码参数,导致连接动作未执行。

3. 重复创建Station实例

代码先后创建sta_if和sta两个Station接口实例,造成资源冗余与逻辑混乱。

4. 无连接超时机制

无限循环等待连接可能导致设备挂起,需添加超时控制。

修复后的完整代码

import network
import socket
import re
import time

# Webserver Konfiguration
server_address = ('', 8080)
html = """<!DOCTYPE html>
<html>
<head>
  <title>SSID und Passwort eingeben</title>
<style>
    body {
      text-align: center;
    }
    form {
      display: inline-block;
      margin-top: 50px;
      text-align: left;
    }
    label {
      display: block;
      margin-bottom: 10px;
    }
input[type="text"],
    input[type="password"] {
      width: 250px;
      height: 30px;
      font-size: 16px;
      margin-bottom: 20px;
    }
    input[type="submit"] {
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
      padding: 10px 20px;
    }
    input[type="submit"]:hover {
      background-color: #45a049;
    }
  </style>
</head>
<body>
  <h1>SSID und Passwort eingeben</h1>
  <form method="post" action="/">
    <label for="ssid">SSID:</label>
    <input type="text" id="ssid" name="ssid" required>
    <label for="password">Passwort:</label>
    <input type="password" id="password" name="password" required>
    <br>
    <input type="submit" value="Verbinden">
  </form>
</body>
</html>
"""

# Access Point Konfiguration
ap_ssid = "pico-wifi"
ap_password = "pico-wifi-password"

# Webserver starten
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(server_address)
server_socket.listen(1)
print('Webserver gestartet auf:', server_address)

while True:
    # Access Point starten
    ap = network.WLAN(network.AP_IF)
    ap.config(essid=ap_ssid, password=ap_password)
    ap.active(True)
    print(ap.ifconfig())

    # Auf Verbindungen warten
    print('Warten auf Verbindung...')
    client_socket, client_address = server_socket.accept()

    # HTTP Anfrage empfangen
    request = client_socket.recv(1024)
    request = str(request)

    # SSID und Passwort aus dem Formular auslesen
    ssid_match = re.search("ssid=([^&]+)", request)
    password_match = re.search("password=([^&]+)", request)
    ssid = ssid_match.group(1) if ssid_match else ""
    password = password_match.group(1) if password_match else ""

    # SSID und Passwort auf der Konsole ausgeben
    print('SSID:', ssid)
    print('Passwort:', password)
    
    # HTTP Antwort senden
    response = 'HTTP/1.1 200 OK\nContent-Type: text/html\n\n' + html
    client_socket.send(response.encode('utf-8'))
    # 关闭客户端连接,释放资源
    client_socket.close()

    # Verbindung zum Access Point trennen
    ap.active(False)
    
    # Versuche, mit dem WLAN zu verbinden
    if ssid and password:
        print('Versuche, mit WLAN zu verbinden...')
        sta = network.WLAN(network.STA_IF)
        # 先关闭再重新激活,清除遗留状态
        sta.active(False)
        time.sleep(1)
        sta.active(True)
        
        # 执行连接动作,传入SSID和密码
        sta.connect(ssid, password)
        
        # 添加超时机制,最多等待10秒
        timeout = 10
        while not sta.isconnected() and timeout > 0:
            time.sleep(1)
            timeout -= 1
            print(f"Verbindungsversuch... verbleibende Zeit: {timeout}s")
        
        if sta.isconnected():
            print('Verbunden mit WLAN:', ssid)
            print('IP-Adresse:', sta.ifconfig()[0])
            # 连接成功后可退出循环或执行后续逻辑
            break
        else:
            print("Verbindung fehlgeschlagen! Kehre zurück zur AP-Modus.")
            # 连接失败,重新开启AP等待用户重试
            continue

额外注意事项

  • 发送HTTP响应后必须关闭客户端套接字,避免资源泄漏
  • 切换网络模式时添加短暂延迟,确保硬件状态切换完成
  • 连接失败后自动回到AP模式,允许用户重新输入WiFi信息

内容的提问来源于stack exchange,提问作者Jonasus123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:44:58