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

Pico Pi W的MicroPython WiFi控制LED异常及蓝牙改造需求

问题解决:Pico W WiFi控制断连 + 蓝牙BLE控制改造

一、WiFi控制时圣诞灯循环导致断连的解决方法

问题根源是阻塞式的动画循环占用了全部CPU时间,没有给WiFi协议栈留处理连接的机会,导致WiFi超时断开。不能用while True+sleep的死循环,必须改成非阻塞式的时间片轮询。

改造思路:

  • 记录上次切换颜色的时间戳
  • 主循环优先处理HTTP请求(网页控制)
  • 仅当时间间隔达到设定值时,才切换圣诞灯颜色

代码示例(替换原圣诞灯循环):

import utime
import random

# 假设你已经有LED控制函数set_color(r,g,b)
last_color_change = utime.ticks_ms()
christmas_interval = 500  # 每500ms切换一次颜色

while True:
    # 先处理网页的HTTP请求(保留你原有的handle_web_requests逻辑)
    handle_web_requests()
    
    # 非阻塞式检查是否需要切换圣诞灯颜色
    current_time = utime.ticks_ms()
    if utime.ticks_diff(current_time, last_color_change) >= christmas_interval:
        # 随机圣诞色系(红、绿、白)
        color = random.choice([(255,0,0), (0,255,0), (255,255,255)])
        set_color(*color)
        last_color_change = current_time
    
    utime.sleep_ms(10)  # 给系统留一点处理时间

这样WiFi请求能被及时响应,不会出现断连的情况。之前加break无效是因为循环根本没机会处理WiFi请求,必须彻底抛弃阻塞式循环。


二、改为iPhone蓝牙BLE控制的实现方案

MicroPython的Pico W支持BLE(蓝牙低功耗),可以直接通过BLE与iPhone通信,无需依赖WiFi。以下是完整实现步骤:

1. 准备工作

  • 确保Pico W刷入支持BLE的MicroPython固件(最新版固件默认支持)
  • 下载官方的ble_advertising.py文件到Pico(用于BLE广播)

2. 完整代码实现

import bluetooth
from ble_advertising import advertising_payload
from machine import Pin, PWM
import utime
import random

# RGB LED硬件配置(根据你的接线调整引脚)
red = PWM(Pin(13))
green = PWM(Pin(14))
blue = PWM(Pin(15))
red.freq(1000)
green.freq(1000)
blue.freq(1000)

def set_color(r, g, b):
    # 转换0-255到PWM的0-65535范围
    red.duty_u16(r * 257)
    green.duty_u16(g * 257)
    blue.duty_u16(b * 257)

def turn_off():
    set_color(0, 0, 0)

# BLE控制器类
_IRQ_CENTRAL_CONNECT = 1
_IRQ_CENTRAL_DISCONNECT = 2
_IRQ_GATTS_WRITE = 3

class BLELED:
    def __init__(self, device_name="Pico-LED"):
        self.ble = bluetooth.BLE()
        self.ble.active(True)
        self.ble.irq(self._ble_irq)
        
        # 定义BLE服务和特征(通用串口服务UUID,方便手机APP识别)
        self.service_uuid = bluetooth.UUID("0000FFE0-0000-1000-8000-00805F9B34FB")
        self.char_uuid = bluetooth.UUID("0000FFE1-0000-1000-8000-00805F9B34FB")
        self.service = self.ble.gatts_register_services([(
            self.service_uuid,
            [(self.char_uuid, bluetooth.FLAG_WRITE | bluetooth.FLAG_NOTIFY,)],
        )])
        self.char_handle = self.service[0][0]
        
        # 开始BLE广播
        self.advertise_payload = advertising_payload(name=device_name, services=[self.service_uuid])
        self.ble.gap_advertise(100000, adv_data=self.advertise_payload)
        
        self.connected = False
        self.current_mode = "off"  # 模式:off/red/green/blue/christmas
        self.last_christmas_change = utime.ticks_ms()
        self.christmas_interval = 500

    def _ble_irq(self, event, data):
        if event == _IRQ_CENTRAL_CONNECT:
            self.connected = True
        elif event == _IRQ_CENTRAL_DISCONNECT:
            self.connected = False
            # 断开后重新广播
            self.ble.gap_advertise(100000, adv_data=self.advertise_payload)
        elif event == _IRQ_GATTS_WRITE:
            # 接收iPhone发送的指令
            cmd = self.ble.gatts_read(self.char_handle).decode().strip().lower()
            if cmd in ["off", "red", "green", "blue", "christmas"]:
                self.current_mode = cmd
                # 立即执行静态颜色指令
                if cmd == "red":
                    set_color(255, 0, 0)
                elif cmd == "green":
                    set_color(0, 255, 0)
                elif cmd == "blue":
                    set_color(0, 0, 255)
                elif cmd == "off":
                    turn_off()

    def update(self):
        # 非阻塞处理圣诞灯动画
        if self.current_mode == "christmas":
            now = utime.ticks_ms()
            if utime.ticks_diff(now, self.last_christmas_change) >= self.christmas_interval:
                # 随机切换圣诞色系
                color = random.choice([(255,0,0), (0,255,0), (255,255,255)])
                set_color(*color)
                self.last_christmas_change = now

# 初始化BLE控制器
led_controller = BLELED()

# 主循环
while True:
    led_controller.update()
    utime.sleep_ms(10)

3. iPhone操作步骤

  1. 安装免费的LightBlue APP(App Store可搜)
  2. 打开APP,找到名为Pico-LED的设备并连接
  3. 找到FFE1特征,进入写入界面
  4. 输入指令并发送:
    • red:切换红色
    • green:切换绿色
    • blue:切换蓝色
    • off:关闭LED
    • christmas:启动圣诞灯随机动画

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:55:01