Search code examples
pythoncbluetoothraspberry-pi-picopybluez

How to send data via bluetooth to Pi pico


I need a way to send data to and from my pi pico via bluetooth. Here is the program I'm running on my pc.

Note: Everything on the pi is working correctly (tested with a bt serial terminal)

import bluetooth as bt

print("Scanning Bluetooth Devices....")

devices = bt.discover_devices(lookup_names=True)

for addr, name in devices:
    print("%s : %s" % (name, addr))

dev_name = input("Enter device name: ")

dev = ""
check = False

for addr, name in devices:
    if dev_name == name:
        dev = addr
        check = True

if not check:
    print("Device Name Invalid!")
else:
    print("Attempting to connect to %s : %s" % (dev_name, dev))

hostMACAddress = dev
port = 3
backlog = 1
size = 1024
s = bt.BluetoothSocket(bt.RFCOMM)
s.bind((hostMACAddress, port))
s.listen(backlog)
try:
    client, clientInfo = s.accept()
    while 1:
        data = client.recv(size)
        if data:
            print(data)
            client.send(data) # Echo back to client
except: 
    print("Closing socket")
    client.close()
    s.close()

It doesn't throw any errors but I don't get anything printed to the terminal when the pi should send "R"

Edit: Here is the working code for anyone interested :)

import bluetooth as bt

print("Scanning Bluetooth Devices....")

devices = bt.discover_devices(lookup_names=True)

for addr, name in devices:
    print("%s : %s" % (name, addr))

dev_name = input("Enter device name: ")

dev = ""
check = False

for addr, name in devices:
    if dev_name == name:
        dev = addr
        check = True

if not check:
    print("Device Name Invalid!")
else:
    print("Sending data to %s : %s" % (dev_name, dev))

hostMACAddress = dev
port = 1
backlog = 1
size = 8
s = bt.BluetoothSocket(bt.RFCOMM)
try:
    s.connect((hostMACAddress, port))
except:
    print("Couldn't Connect!")
s.send("T")
s.send("E")
s.send("S")
s.send("T")
s.send(".")
s.close()

Solution

  • The most straight forward (but not the most efficient way) is to convert the array of integer to a delimited C string and send it the way you are sending "Ready". Let assume the array delimiters are "[" and "]" then the following array

    int arr[] = {1,2,3};
    

    can be converted to a string like the following

    char str[] = "[010203]";
    

    To convert array of integer to the delimited string you can do the following:

    int arr[] = {1,2,3};
    int str_length = 50; // Change the length of str based on your need.
    char str[str_length] = {0};
    int char_written = 0;
    
    char_written = sprintf(str,'[');
    for (int i = 0; i< sizeof(arr)/sizeof(int) - 1; i++){
        char_written = sprintf(&str[char_written], "%02d", arr[i]);
    char_written = sprintf(&str[char_written], ']');
    

    Now you can use your existing code to send this string. In the receiving end, you need to process the string based on "[", "]", and the fact that each integer has width of 2 in the string.

    Edit: Converting array to string and send the string via bluetooth via python.

    To convert an array to string in python the following will do the job

    a = [1,2,3,4,5]
    a_string = "[" + "".join(f"{i:02d}" for i in a) + "]"
    

    To send this string via python over bluetooth you need to use PyBlues library.

    First you need to find the MAC address of the pico bluetooth

    import bluetooth
    # Make sure the only bluetooth device around is the pico.
    devices = bluetooth.discover_devices()
    print(devices)
    

    Now that you know the MAC address, you need to connect to it

    bt_mac = "x:x:x:x:x:x" # Replace with yours.
    port = 1
    sock=bluetooth.BluetoothSocket(bluetooth.RFCOMM)
    sock.connect((bd_addr, port))
    

    Know you can send strings like

    sock.send(a_string.encode())
    

    Finally, in the end of your python program close the socket

    sock.close()
    

    PS: I do not have bluetooth available to test it but it should work.