我正在用 MicroPython 编写。目标是通过调用设备的 IP 地址来控制的伺服电机。 Raspberry Pi Pico 运行一个监听传入请求的服务器:
http://192.168.178.22/servo/on should start the servo motor
http://192.168.178.22/servo/off should stop the servo motor
如果调用不是异步的,它可以工作,但我需要随时停止伺服,因此需要异步(应该无限期地运行,直到调用“off”)。这就是我想出 uasyncio 的原因。一切正常,但仅在第二次请求后,服务器不再响应。
main
在循环中运行,仅显示内存(用于以后的实现):
async def main():
print("Setting up event loop...")
showFilesOnPico()
connectToWifi(secrets.SSID, secrets.PASSWORD, ledInternal)
servoStartUp()
# The event loop will keep running while the server is running
while True:
print(".")
# check for low memory
print("Free Memory:", gc.mem_free(), "bytes" )
##
await uasyncio.sleep(1) # Yield control to other tasks
服务器逻辑的启动:
async def startServer():
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
server = await uasyncio.start_server(handle_request, *addr)
handle_request
(为了测试,我禁用了伺服开/关,因为问题也出现在“测试部门”请求上):
async def handle_request(reader, writer):
print('handle_request called')
try:
request = await reader.read(1024)
request = str(request)
print("Request:", request)
#led_on = request.find('/servo/on')
#led_off = request.find('/servo/off')
testing = request.find('/testingdepartment')
#if led_on != -1:
# ledInternal.value(1)
# uasyncio.create_task(demoServo())
#if led_off != -1:#
# ledInternal.value(0)
# uasyncio.create_task(deactivateServo())
if testing != -1:
print("testing clicked")
await uasyncio.sleep(1)
print("before writer.drain")
response = b'HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n'
writer.write(response)
await writer.drain()
print("after writer.drain")
except Exception as e:
print('Error in handle_request:', e)
finally:
reader.close()
writer.close()
print("end of handle request reached :-D :-D :-D")
await uasyncio.sleep(1)
异步循环开始:
loop = uasyncio.get_event_loop()
loop.create_task(main())
loop.create_task(startServer())
loop.run_forever()
它仅适用于少数请求。我无法隔离问题。请求是通过调用前面提到的 URL 发出的。伺服电机通过此功能设置有效(测试电机仅重复运动 6 次)。
async def demoServo():
print('DemoServo is called')
global isServoRoutineRunning
global shouldAbortServoRoutine
if not isServoRoutineRunning:
# Reset shouldAbortServoRoutine to False
shouldAbortServoRoutine = False
isServoRoutineRunning = True
for x in range(6):
if shouldAbortServoRoutine:
break
print('pos 90')
pwm.duty_ns(grad090)
await uasyncio.sleep(2)
print('pos 0')
pwm.duty_ns(grad000)
await uasyncio.sleep(2)
pwm.deinit()
print('end')
isServoRoutineRunning = False
我刚刚遇到了这个问题。对我来说,解决方案是缓冲区。问题是 10-15 次后循环停止并等待,没有错误消息。 wait writer.drain() 会停止它,因为它将数据卸载到缓冲区中,但接收数据的程序在另一端并不活动,只是被堵塞了。客户端读取数据后,就没有问题了。如果您要发送较大的材料,值得从 1024 改为 4096。