Enquanto alpha-tester do firmware do Pybricks para hubs Powered Up sugeri que implementassem a função 'input'. Já era possível fazer 'print', indo para o ambiente IDE por intermédio de um serviço Nordic UART Service (NUS) que permite abrir um canal série (UART) com o hub (é este serviço que permite por exemplo actualizar o firmware do Pybrick "pelo ar").
O David Lechner incluiu isso há umas semanas e desde dia 2 de Julho que faz parte da imagem oficial (2.4.0 do projecto, que por qualquer motivo no Control+ é identificada como 3.0.0a4) mas uns dias antes descobri como ir buscar versões intermédias e consegui dar uso a esta nova função.
Para quem usa apenas o IDE não é lá muito atractiva: permite usar o teclado para input, ficando o programa parado à espera que o utilizador escreva qualquer coisa e "dê ENTER".
Escrevi um pequeno programa que mostra como usar o teclado para comandar o Top Gear Car:
Código: Selecionar todos
from pybricks.pupdevices import Motor
from pybricks.hubs import CPlusHub
from pybricks.parameters import Port
from pybricks.tools import wait
hub = CPlusHub()
mDir = Motor(Port.B)
mMove = Motor(Port.D)
DirSPEED = 360
DirANGLE = 60
MoveSPEED = 720
MoveTIME = 1000
mDir.reset_angle()
while True:
i = input("?")
if i == "l":
mDir.run_target(DirSPEED, -DirANGLE)
elif i == 'r':
mDir.run_target(DirSPEED, DirANGLE)
elif i == 'z':
mDir.run_target(DirSPEED,0)
elif i == 's':
mMove.stop()
elif i == 'f':
mMove.run_time(MoveSPEED, MoveTIME)
elif i == 'b':
mMove.run_time(-MoveSPEED, MoveTIME)
else:
print("!")
[list][list][/list][/list]
a grande vantagem, enquanto o Projecto Pybricks não chega às mailboxes BT, ao IP over BLE e ao MQTT over IP over BLE, é podermos comunicar com o hub FORA do IDE. Existem App para falar com o NUS mas muito genéricas por isso fiz o meu próprio "controlador" em python (e chamo aqui a atenção que é python e não micropython).
Código: Selecionar todos
#!/usr/bin/env python3
from bluepy.btle import *
from time import sleep
#HUB_ID = "90:84:2B:4B:BF:59"
HUB_ID = "90:84:2B:52:DA:8B"
CR = '\x0D'
class MyDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
# ... initialise here
def handleNotification(self, cHandle, data):
# ... perhaps check cHandle
# ... process 'data'
print(data.decode("utf-8").rstrip())
#handle: 0x000e, char properties: 0x04, char value handle: 0x000f, uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e
#handle: 0x0010, char properties: 0x10, char value handle: 0x0011, uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e
NORDIC_UART_SERVICE = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"
RX_CHARACTERISTIC = '6e400002-b5a3-f393-e0a9-e50e24dcca9e' #RX Write no response
TX_CHARACTERISTIC = '6e400003-b5a3-f393-e0a9-e50e24dcca9e' #TX notify
def send_command(hub, handle, command):
hub.writeCharacteristic(handle, bytes(command+CR, 'utf-8'), withResponse=False)
# Initialisation -------
hub = Peripheral(HUB_ID)
hub.setDelegate( MyDelegate( ))
hub_svcs = hub.getServices() # without this cannot get ServiceByUUID to work ????
hub_svcs = hub.getServiceByUUID( UUID(NORDIC_UART_SERVICE) )
hub_tx = hub_svcs.getCharacteristics( UUID(TX_CHARACTERISTIC) )[0]
hub_tx_handle = hub_tx.valHandle
hub_rx = hub_svcs.getCharacteristics( UUID(RX_CHARACTERISTIC) )[0]
hub_rx_handle = hub_rx.valHandle
#turn notifications ON
hub.writeCharacteristic(hub_tx_handle + 1, b'\x01\x00', withResponse=False)
commands = ['z','f','b','l','f','f','f','f','f','f','f','z','b','l','b','b','b','b','b','b','b']
cmd_count = 0
rcv_count = 0
prompt = False
sleep(1.0) # sometimes it doesn't start properly so maybe this helps
# very scientific :)
send_command(hub, hub_rx_handle, commands[cmd_count])
while True:
if hub.waitForNotifications(0.2):
# handleNotification() was called
rcv_count+=1
if rcv_count > 1:
rcv_count = 0
prompt = True
continue
if prompt == True:
cmd_count+=1
if cmd_count == len(commands):
cmd_count = 0
send_command(hub, hub_rx_handle, commands[cmd_count])
sleep(0.4)
else:
print("waiting")
Este último programa usa uma library de python chamada bluepy. Não é a melhor (agora está na moda o bleak, usado também pelo Pybricks mas é muito pesada em termos de dependências) mas é aquela que consigo instalar no ev3dev do EV3.