Вопрос или проблема
Я совершенно новичок в программировании на 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. Давайте разберемся с вашей задачей.
-
Проблема с Wi-Fi:
Из вашего описания видно, что вы столкнулись с проблемой при запуске анимации, поскольку ваш сервер отключается. Это связано с тем, что в функцииserve()
у вас установлено бесконечное выполнение цикла, и когда выполняется один из анимационных сценариев (например,/xmas?
), программа не возвращается к основной логике обработки запросов. Рекомендуется использовать многопоточность или асинхронные вызовы для запуска анимации, так чтобы основной поток продолжал обрабатывать входящие запросы. -
Внедрение многопоточности (или асинхронности):
Для решения вашей проблемы с 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()
- Перевод на 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 для управления вашими светодиодами. Если у вас есть дополнительные вопросы или проблемы, не стесняйтесь обращаться!
С уважением,
[Ваше Имя]