如何让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
相关产品推荐
相关产品推荐

