Ассистент MicroPython WiFi с Pico Pi W

Вопрос или проблема

Я совершенно новичок в программировании на MicroPython. Я посмотрел несколько видео о CircuitPython, так как хотел подключить свой Pico Pi W по Bluetooth, чтобы управлять светодиодами, которые я к нему подключил. Выяснилось, что CircuitPython не поддерживает Bluetooth, хотя Pico Pi W его поддерживает. Мне сказали, что, скорее всего, я должен использовать CircuitPython, так как он похож, но все же сможет выполнить задачу. Я искал и не смог найти ни одного кода или чего-либо, что позволило бы мне подключиться по Bluetooth, но я нашел код для подключения к Wi-Fi. Мой код позволяет мне подключиться к Wi-Fi сети (если я знаю SSID и пароль), затем я могу подключиться к нему, перейдя по IP-адресу, который получает Pico. Он отображает очень простую HTML-страницу с кнопками, которые позволяют мне статически менять цвет. Я могу менять его с красного на синий, зеленый и затем выключать. Когда я пытаюсь запустить что-то вроде анимации (для этого нужно в цикле, по крайней мере, согласно моим маленьким знаниям), похоже, что он отключается от Wi-Fi соединения (по крайней мере, перестает себя транслировать) и не позволяет мне вернуть цвета обратно к статическому или даже выключить. Мне приходится либо отключать питание платы, либо вручную останавливать программу в Thonny. Я вставлю свой код ниже, чтобы узнать, может ли кто-то помочь.

import network
import socket
import machine, neopixel, random, math, time
from time import sleep
from picozero import pico_led

p = machine.Pin.board.GP0
n = neopixel.NeoPixel(p, 30)

ssid = ''
password = ''

def connect():
    #Подключиться к WLAN
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)
    while wlan.isconnected() == False:
        print('Ожидание подключения...')
        sleep(1)
    ip = wlan.ifconfig()[0]
    print(f'Подключено на {ip}')
    return ip

def open_socket(ip):
    #Открыть сокет
    address = (ip, 80)
    connection = socket.socket()
    connection.bind(address)
    connection.listen(1)
    return connection

def webpage(state):
    #Шаблон HTML
    html = f"""
            <!DOCTYPE html>
            <html>
            <body>
            <form action="./red">
            <input type="submit" value="КРАСНЫЙ" />
            </form>
            <form action="./green">
            <input type="submit" value="ЗЕЛЕНЫЙ" />
            </form>
            <form action="./blue">
            <input type="submit" value="СИНИЙ" />
            </form>
            <form action="./xmas">
            <input type="submit" value="Рождество" />
            </form>
            <form action="./lightoff">
            <input type="submit" value="выключить свет" />
            </form>
            <p>Светодиод {state}</p>
            </body>
            </html>
            """
    return str(html)

## Создать случайную функцию
def randint(lower, upper):
    gap = upper - lower
    if gap == 0:
        return lower
    return (random.getrandbits(int(math.log(gap, 2))) % gap) + lower

ChristmasColors = [(255, 0, 0), (0, 255, 0), (255, 0, 0), (0, 255, 0)]
AllColors = [(255, 0, 0), (0, 255, 0), (255, 255, 255), (0, 0, 255)]
WhiteBlue = [(255, 255, 255), (0, 0, 255), (255, 255, 255), (0, 0, 255)]
Red = [(255, 0, 0), (255, 0, 0), (255, 0, 0), (255, 0, 0)]
Blue = [(0, 0, 255), (0, 0, 255), (0, 0, 255), (0, 0, 255)]
Green = [(0, 255, 0), (0, 255, 0), (0, 255, 0), (0, 255, 0)]
Yellow = [(255, 255, 0), (255, 255, 0), (255, 255, 0), (255, 255, 0)]
Orange = [(255, 165, 0), (255, 165, 0), (255, 165, 0), (255, 165, 0)]
Fire = [(255, 165, 0), (255, 0, 0), (255, 165, 0), (255, 0, 0)]

def serve(connection):
    #Запустить веб-сервер
    state="ВЫКЛ"
    pico_led.off()
    while True:
        client = connection.accept()[0]
        request = client.recv(1024)
        request = str(request)
        print(request)
        try:
            request = request.split()[1]
        except IndexError:
            pass
        if request == '/red?':
            pico_led.on()
            for i in range(30):
                n[i] = (i * 8, 0, 0)
                n.write()
            state="КРАСНЫЙ"
        elif request == '/green?':
            pico_led.on()
            for i in range(30):
                n[i] = (0, i * 8, 0)
                n.write()
            state="ЗЕЛЕНЫЙ"
        elif request == '/blue?':
            pico_led.on()
            for i in range(30):
                n[i] = (0, 0, i * 8)
                n.write()
            state="СИНИЙ"
        elif request == '/xmas?':
            pico_led.on()
            try:
                while True:
                    for i in range(30):
                        n[i] = ChristmasColors[randint(0, 4)]
                        #n[i-2] = (0, 0, 0)
                        n.write()
                        machine.idle()
                        time.sleep(.01)
            except KeyboardInterrupt:
                pico_led.off()
                state="ЖЕЛТЫЙ"
        elif request == '/lightoff?':
            pico_led.off()
            for i in range(30):
                n[i] = (0, 0, 0)
                n.write()
            state="ВЫКЛ"
        html = webpage(state)
        client.send(html)
        client.close()

try:
    ip = connect()
    connection = open_socket(ip)
    serve(connection)
except KeyboardInterrupt:
    machine.reset()

Я действительно хочу попробовать переключиться на Bluetooth и использовать совместимое Bluetooth-приложение на своем мобильном телефоне (iPhone 15), чтобы подключиться вместо Wi-Fi, так как мне нужно будет запустить точку доступа, чтобы подключить его, когда я буду вне дома с моим оборудованием. Может ли кто-то помочь с этим, пожалуйста, заранее спасибо!

С уважением,
Эндрю

Я пытался устранить цикл, но если я это делаю, он просто становится статическим рождественским цветом (чередующий красный и зеленый), когда он должен случайным образом меняться между этими двумя цветами, выглядя как рождественские огоньки. Я пытался добавить операторы break, но они, похоже, не работают. Я не уверен, что именно я делаю неправильно.

Ответ или решение

Дорогой Эндрю,

Благодарю вас за ваш вопрос и за предоставленный код. Я понимаю, что вы хотите, чтобы ваш Pico Pi W работал с Bluetooth для управления светодиодами, вместо использования Wi-Fi. Давайте разберемся с вашей задачей.

  1. Проблема с Wi-Fi:
    Из вашего описания видно, что вы столкнулись с проблемой при запуске анимации, поскольку ваш сервер отключается. Это связано с тем, что в функции serve() у вас установлено бесконечное выполнение цикла, и когда выполняется один из анимационных сценариев (например, /xmas?), программа не возвращается к основной логике обработки запросов. Рекомендуется использовать многопоточность или асинхронные вызовы для запуска анимации, так чтобы основной поток продолжал обрабатывать входящие запросы.

  2. Внедрение многопоточности (или асинхронности):
    Для решения вашей проблемы с Wi-Fi можно использовать библиотеку uasyncio, чтобы позволить вашей программе выполнять анимации в фоновом режиме, не блокируя основной поток. Пример кода может выглядеть следующим образом:

import uasyncio as asyncio

async def xmas_animation():
    while True:
        # Ваш код для управления анимацией
        for i in range(30):
            n[i] = ChristmasColors[randint(0, 4)]
            n.write()
            await asyncio.sleep(0.01)  # Небольшая задержка

async def serve(connection):
    state = "OFF"
    pico_led.off()
    while True:
        client = connection.accept()[0]
        request = client.recv(1024)
        request = str(request)
        print(request)
        try:
            request = request.split()[1]
        except IndexError:
            pass
        if request == '/xmas?':
            pico_led.on()
            await asyncio.create_task(xmas_animation())  # Запуск анимации
            state = "ANIMATING"  # Установка состояния, чтобы показать, что анимация работает
        # Обработка остальных запросов
        # ...
        html = webpage(state)
        client.send(html)
        client.close()

# Замените вызов serve(connection) на asyncio.run(serve(connection))
try:
    ip = connect()
    connection = open_socket(ip)
    asyncio.run(serve(connection))
except KeyboardInterrupt:
    machine.reset()
  1. Перевод на Bluetooth:
    Переход на использование Bluetooth потребует изменений в коде, так как нужно будет использовать библиотеку для Bluetooth, такую как bluetooth или ubluetooth, которая доступна в MicroPython. Однако стоит отметить, что работа с Bluetooth может быть менее документированной и сложнее, чем Wi-Fi.

Пример использования Bluetooth может включать следующий код:

import ubluetooth

def bt_callback(event, data):
    if event == ubluetooth.CLIENT_CONNECTED:
        print('Клиент подключен')
    elif event == ubluetooth.CLIENT_DISCONNECTED:
        print('Клиент отключен')

bt = ubluetooth.Bluetooth()
bt.active(True)
bt.irq(handler=bt_callback)
bt.advertise(100, b'LED Controller')  # Имя вашего устройства Bluetooth

# Замените на ваш код для управления цветами светодиодов

Для управления светодиодами вы можете установить обработчики событий для каждого подключенного клиента, а затем управлять светодиодами через Bluetooth команды.

Надеюсь, эти рекомендации помогут вам улучшить ваш проект и успешно использовать Bluetooth для управления вашими светодиодами. Если у вас есть дополнительные вопросы или проблемы, не стесняйтесь обращаться!

С уважением,
[Ваше Имя]

Оцените материал
Добавить комментарий

Капча загружается...