pybricks / support

Pybricks support and general discussion
MIT License
108 stars 6 forks source link

Connecting several LEGO EV3 MINDSTORM bricks to a laptop via bluetooth #902

Closed Hakurem closed 1 year ago

Hakurem commented 1 year ago

Question

First of all I am using windows 10 and I have been attempting to do the same on mac without much success. Are there any good ways of connecting multiple clients (ev3-bricks running in micropython) to one single server (laptop running in python3)? My question is how to connect the bricks directly to the laptop. I looked at the example repository pybricks-api/examples/ev3/bluetooth_pc at master · pybricks/pybricks-api in which I was unsuccessfull to pair an ev3 with a pc.

Context Using pybricks 2.0.0 I have been able to connect one ev3 device with the laptop via bluetooth (I used the socket library in python3). My main goal is to connect several ev3 devices to a laptop acting as a server. From what I have done, there was an issue in connecting more than one ev3 to the same laptop. If one ev3-brick is already connected, the state of the other ev3-brick is not getting configured and throws an error. Is there a way around this? The image below shows how I tried to connect the ev3 after pairing. Only one ev3 at a time was successfully connected (any additional connection failed).

image

That's when I looked into the bluetooth-messaging system in pybricks. Between two ev3-devices I have been able to connect without any issues. On the other hand between a pc and an ev3, I have yet to be able to connect with the messaging system. I installed pybricks on my windows with the following pip3 install pybricks. The issue seems like it returns immediately after calling client.connect() in the pcclient.py example file regardless of what server address I insert. The same happens if I make the pc the server and calls server.wait_for_connection()

SERVER = "CC:78:AB:D8:4E:F6" 

client = BluetoothMailboxClient()
mbox = TextMailbox("greeting", client)

print("establishing connection...")
client.connect(SERVER) # returns immediately without connecting
print("connected!")

I noticed that bluetooth library was called which I assume is the pybluez module as shown in the following import. I could not install pybluez on my windows, but i was able to install pybluez2. I wonder if this could be the issue that I am not able to connect.

from bluetooth import BluetoothSocket, RFCOMM
from socketserver import ThreadingMixIn
BDADDR_ANY = ""
def str2ba(string, ba):
    """Convert string to Bluetooth address"""
    for i, v in enumerate(string.split(":")):
        ba.b[5 - i] = int(v, 16)

image

dlech commented 1 year ago

Thanks for the detailed report. I have updated the example and removed the 3rd-party dependency. This requires Python 3.10 or newer on Windows.

Hakurem commented 1 year ago

Thank you so much. The pcclient.py works now 😄 where the ev3 is the server. On the other hand I get this error when trying to run the pc as a server (pcserver.py example file). Do you have a suggestion on what I can do? Thanks in advance.

$ python3.10 pcserver.py
Traceback (most recent call last):
  File "C:\Users\admin\Desktop\pybricks-api-master\pybricks-api-master\examples\ev3\bluetooth_pc\pcserver.py", line 16, in <module>
    server = BluetoothMailboxServer()
  File "C:\Users\admin\Desktop\pybricks-api-master\pybricks-api-master\examples\ev3\bluetooth_pc\pybricks\messaging.py", line 267, in __init__
    super(ThreadingRFCOMMServer, self).__init__(
  File "C:\Users\admin\Desktop\pybricks-api-master\pybricks-api-master\examples\ev3\bluetooth_pc\pybricks\bluetooth.py", line 34, in __init__ 
    self.socket.bind(server_address)
PermissionError: [WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions
dlech commented 1 year ago

The RFCOMM channel in the Pybricks libraries is hard-coded to channel 1 to be compatible with the official LEGO software. Windows reserves the first few channels for Windows COM ports which is why you get the error.

So you can either just stick with using the client on Windows or you can modify the code on both ends to use a different RFCOMM channel.

Hakurem commented 1 year ago

Thank you. Do you happen to know if this is supported on mac or linux? On mac (for my Macbook Pro), AF_BLUETOOTH doesn´t seem to be part of the inbuilt socket library in versions python3.10.x on mac os. Have you had any success running the pcserver.pyfile on any operating systems?

dlech commented 1 year ago

I've used it on Linux so I know it works there. I haven't tried it on Mac recently.

Hakurem commented 1 year ago

I will try it on Linux then. For my own curiosity I was also thinking about looking at the RFCOMM channels on the ev3 that you mentioned. Do you have any repository or suggestions on how I would access the source code that the ev3 brick is running on to change the RFCOMM channel? I originally flashed the image on the brick to get the firmware and am uncertain where I can access the code.

dlech commented 1 year ago

The code for ev3dev is at https://github.com/pybricks/pybricks-micropython/tree/master/bricks/ev3dev/modules/pybricks (bluetooth.py and messaging.py). The code is "frozen" on the EV3, so it is only available in binary form there.

We hard-coded EV3_RFCOMM_CHANNEL in messaging.py, so you would need to copy the definition of BluetoothMailboxServer and/or MailboxRFCOMMClient and modify it to take the channel as a parameter.

Hakurem commented 1 year ago

Thank you that worked perfectly for windows.

bradocchs commented 11 months ago

Hi @Hakurem,

Were you able to change the RFCOMM channel on the brick and use the PC as a Bluetooth server? If so, would you be willing to share some instructions?

Thanks!