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

如何让Raspberry Pi Pico W通过WPS连接WiFi?解决属性报错

问题概述

使用Raspberry Pi Pico W实现股价监测并通过LED显示价格状态,设备优先读取your_wifi_details.txt中的SSID和密码连接WiFi;连接失败时进入WPS模式,通过按钮触发连接。但WPS功能调用时报错,正常填写配置文件可正常联网,需避免用户通过Thonny编辑文件。

报错信息

'CYW43' object has no attribute 'scan_wps'

问题代码片段
# If the button is pressed, scan for WiFi networks that support WPS
if not button.value():
    sta_if.scan_wps()

    # Connect to the first WiFi network that supports WPS
    sta_if.connect_wps()
完整原始代码
import urequests
import network
import time
import machine

# Set up the button (connected to pin 15)
button = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)
print ('pin 15 set as button')

while True:
    print ('enter while true loop')
    # Connect to the WiFi network
    sta_if = network.WLAN(network.STA_IF)
    #print ('firstline passed, sleeping for 10 seconds')

#ignore this, unnecessary now
    #for i in range (0, 20):
     #   time.sleep(0.55)
      #  print ('sleeping...')

    #print ('nap over, trying to continue..')
    sta_if.active(True)
    print ('firing up connection')

    # Read the WiFi SSID and password from the text file
    with open("your_wifi_details.txt", "r") as f:
        ssid = f.readline().strip()
        password = f.readline().strip()
        print ('read your_wifi_details.txt successfully')

    # Try to connect to the WiFi network
    sta_if.connect(ssid, password)
    print ('attempting to connect to wifi')

    # Wait until the device is connected to the WiFi network
    while not sta_if.isconnected():
        # Flash the LEDs to indicate that the device is unable to connect
        print ('connection failed, attempting to flash LEDs')
        green_led.on()
        red_led.on()
        time.sleep(0.5)
        green_led.off()
        red_led.off()
        time.sleep(0.5)

        # Set up the button (connected to pin 0)
        print ('setting up button for WPS')
        button = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)

        # If the button is pressed, scan for WiFi networks that support WPS
        if not button.value():
            sta_if.scan_wps()

            # Connect to the first WiFi network that supports WPS
            sta_if.connect_wps()

            # Save the WiFi SSID and password to the "your_wifi_details.txt" file
            with open("your_wifi_details.txt", "w") as f:
            f.write(sta_if.config("essid") + "\n")
            f.write(sta_if.config("password") + "\n")
            print ('wifi details written to file')

# Print the WiFi connection status in the terminal so I can see if it worked
print("Connected to WiFi:", sta_if.isconnected())
解决方案

1. WPS报错原因

MicroPython官方固件针对Pico W的CYW43芯片,并未封装scan_wps()和connect_wps()方法,这两个不属于标准MicroPython WiFi API,因此调用会触发属性不存在的报错。需通过调用CYW43底层AT指令实现WPS功能。

2. 代码修复与优化

核心修复点

  • 用CYW43的AT指令实现WPS PBC(按钮触发)模式
  • 补全LED引脚初始化代码
  • 移除循环内重复的按钮初始化逻辑
  • 修复文件写入的缩进错误
  • 优化WiFi连接逻辑,避免重复创建连接对象

优化后完整代码

import urequests
import network
import time
import machine

# 硬件初始化(根据实际接线调整引脚)
green_led = machine.Pin(13, machine.Pin.OUT)
red_led = machine.Pin(14, machine.Pin.OUT)
button = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)

def connect_wifi_from_file(sta_if):
    """从配置文件读取WiFi凭证并尝试连接"""
    try:
        with open("your_wifi_details.txt", "r") as f:
            ssid = f.readline().strip()
            password = f.readline().strip()
        if ssid and password:
            sta_if.connect(ssid, password)
            # 等待连接,超时10秒
            for _ in range(10):
                if sta_if.isconnected():
                    return True
                time.sleep(1)
    except OSError:
        print("WiFi配置文件不存在或读取失败")
    return False

def connect_via_wps(sta_if):
    """通过WPS PBC模式连接WiFi"""
    print("启动WPS模式,请按下路由器WPS按钮")
    try:
        # 发送AT指令启动WPS PBC模式
        sta_if._nic.atcmd('AT+WPS=PBC')
    except Exception as e:
        print(f"WPS指令发送失败: {str(e)}")
        return False

    # 等待连接完成,超时30秒
    timeout = 30
    while timeout > 0 and not sta_if.isconnected():
        green_led.toggle()
        red_led.toggle()
        time.sleep(0.5)
        timeout -= 1

    green_led.off()
    red_led.off()

    if sta_if.isconnected():
        ssid = sta_if.config("essid")
        print(f"WPS连接成功,当前SSID: {ssid}")
        return True
    else:
        print("WPS连接超时")
        return False

def main():
    sta_if = network.WLAN(network.STA_IF)
    sta_if.active(True)

    # 优先尝试配置文件连接
    if not connect_wifi_from_file(sta_if):
        print("配置文件连接失败,进入WPS触发等待")
        while not sta_if.isconnected():
            # 双闪LED提示连接失败
            green_led.on()
            red_led.on()
            time.sleep(0.5)
            green_led.off()
            red_led.off()
            time.sleep(0.5)

            # 检测按钮按下(低电平触发)
            if not button.value():
                if connect_via_wps(sta_if):
                    break

    # 联网后执行股价监测逻辑
    print(f"WiFi连接状态: {sta_if.isconnected()}")
    while sta_if.isconnected():
        try:
            # 替换为实际的股价API接口
            response = urequests.get("https://api.example.com/stock-price")
            price = response.json().get("price")
            # 根据价格状态控制LED(示例逻辑)
            if price > 100:
                green_led.on()
                red_led.off()
            else:
                red_led.on()
                green_led.off()
            response.close()
        except Exception as e:
            print(f"股价获取失败: {str(e)}")
            green_led.off()
            red_led.off()
        time.sleep(60)  # 每分钟刷新一次股价

if __name__ == "__main__":
    main()

关键说明

  • WPS密码保存限制:MicroPython无法直接读取WPS连接后的WiFi密码,因此无法将密码写入your_wifi_details.txt。若需保存凭证,可改用WPS PIN模式(需生成并显示PIN码给用户输入到路由器)。
  • AT指令兼容性:sta_if._nic.atcmd()调用的是CYW43底层接口,建议使用最新版MicroPython官方固件以保证兼容性。
  • 硬件接线:需确保LED、按钮的引脚定义与实际接线一致,避免引脚冲突或短路。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:35:28