Python: Trying to scan for active bluetooth devices - python

I found online multiple sources that said that discover_devices scans for active bluetooth devices, but for me it was printing all the bluetooth devices that remembered on my computer. Is there something wrong with my code/settings?
`
import bluetooth
nearby_devices = bluetooth.discover_devices(lookup_names=True)
print(nearby_devices)
for addr, name in nearby_devices:
print('\nname = ', name, "\naddress = ", addr)
`

Related

Recognition of a specific USB device in python

I am making app in python, that connects with Arduino. I want this app to work on different computers, when arduino is connected to any port. I was trying to do a function that checks to which port is arduino connected to:
def arduinoConnect():
t=0
temp = 0;
while 1:
i = str(t)
try:
temp = serial.Serial('com'+i, 9600)
if temp:
print("COM" + i + " Connected")
break
except:
print("COM" + i + " Empty")
t = t + 1
if t == 41:
break
return temp
But this code only sees if anything is connected, so when i am also using some bluetooth devices, or other microcontrolers, it takes the device that is connected to the com port with the lowest number.
Next idea was to take PID and VID number:
import serial
import serial.tools.list_ports
for port in serial.tools.list_ports.comports():
print(port.hwid)
But i have one more device connected to COM Port, that gives exactly the same numbers, only different location:
USB VID:PID=1A86:7523 SER= LOCATION=1-4
USB VID:PID=1A86:7523 SER= LOCATION=1-5
I also tried to get a specific id of a connected USB device:
import serial
def serial_ports():
ports = ['COM%s' % (i + 1) for i in range(256)]
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
print(s)
except (OSError, serial.SerialException):
pass
return result
if __name__ == '__main__':
print(serial_ports())
And it returns the ID of a device, which is unique to every device, but changes every time i disconnect and connect again the device.
My question is how to let my code recognize and connect one and only device I want? On any computer, connected to any port.
I understand your problem as such that you wish to have python code that can connect to an arduino device which is connected to any port, on any computer.
So the solution is to uniquely identify the arduino device even when other devices are plugged in.
It should work when you get the device serial number:
import serial
import serial.tools.list_ports
def get_arduino_serial_number():
for port in serial.tools.list_ports.comports():
if 'Arduino' in port.description:
return port.serial_number
return None
whether this works or not is dependent on port.description.
Change USB COM port description
Get ports by description
With the serial number of the Arduino device, you can then connect to it using:
ser = serial.Serial(port='COMx', baudrate=9600, timeout=1,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
Opening serial ports | pySerial

Receive data via bluetooth using python on android phone

I have an ESP32 board which sends data via bluetooth. I can receive data on PC using this python code:
from bluetooth import *
import sys
def input_and_send():
while True:
data = input()
if len(data) == 0: break
sock.send(data)
sock.send("\n")
def rx_and_echo():
sock.send("\nsend anything\n")
while True:
data = sock.recv(buf_size)
if data:
print(data.decode('utf-8'))
sock.send(data)
addr = "XX:XX:XX:XX:XX:XX"
service_matches = find_service( address = addr )
buf_size = 1024
if len(service_matches) == 0:
print("couldn't find the SampleServer service =(")
sys.exit(0)
for s in range(len(service_matches)):
print("\nservice_matches: [" + str(s) + "]:")
print(service_matches[s])
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
port = 1
print("connecting to \"%s\" on %s, port %s" % (name, host, port))
sock = BluetoothSocket(RFCOMM)
sock.connect((host, port))
print("connected")
# input_and_send()
rx_and_echo()
sock.close()
Data.append(data.decode('utf-8'))
Now, I want to get data on android phone. I wrote a python program using kivy, but bluetooth package does not work on android. I tried bleak and jnius packages, but they did not work. Is there another packages which can use bluetooth of phone properly? I see, some persons advise using jnius package for android, but I could not get data using "BluetoothReceive" function.
Any help is appreciated.
I understood how to receive data using python on android. I used jnius package, and tried to look errors using this code on android phone.
I found theBufferReader should be used instead of getInputStream(), and readLine() instead of readline(). You can receive data using the below code:
from jnius import autoclass
BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
BluetoothDevice = autoclass('android.bluetooth.BluetoothDevice')
BluetoothSocket = autoclass('android.bluetooth.BluetoothSocket')
UUID = autoclass('java.util.UUID')
BufferReader = autoclass('java.io.BufferedReader')
InputStream = autoclass('java.io.InputStreamReader')
paired_devices = BluetoothAdapter.getDefaultAdapter().getBondedDevices().toArray()
socket = None
for device in paired_devices:
if device.getName() == 'ESP32':
socket = device.createRfcommSocketToServiceRecord(
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
recv_stream = BufferReader(InputStream(socket.getInputStream()))
break
socket.connect()
Serial_Data = recv_stream.readLine()
Add this bluetooth permision to your buildozer.spec file.
android.permissions = BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_FINE_LOCATION
Since jnius package does not work on PC (Windows or Linux), I hope there be another way to debug the python code directly, without making application and testing it on android phone.

Error while connecting HC-05 bluetooth module with python via bluetooth

I have been trying to connect my hc 05 bt module with my laptop and to achieve a communication with Idle.
At first i connected my bt device manually from laptop's bluetooth settings and then I was able to get the module's bt address by using the following code:
import bluetooth
target_name = "HC-05"
target_address = None
nearby_devices = bluetooth.discover_devices()
for bdaddr in nearby_devices:
if target_name == bluetooth.lookup_name( bdaddr ):
target_address = bdaddr
break
if target_address is not None:
print "found target bluetooth device with address ", target_address
else:
print "could not find target bluetooth device nearby"
I received the bluetooth address as "98:D3:31:70:7D:2D"
Now i wrote the following code to connect HC-05 via python..
bd_addr = "98:D3:31:70:7D:2D"
port = 20
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((bd_addr, port))
sock.send("1")
sock.close()
Now i browse through my laptop's bluetooth comm port settings and found 2 things
1st...
COM19
Direction--- Incoming...
Name--- HC-05
2nd...
COM20
Direction--- Outgoing
...
Name--- HC-05 'Dev B'
Hence I chose COM20 as I want to transmit data from Python.
When I run this code i get error:
Traceback (most recent call last):
File "C:\Python27\TestBluetooth.py", line 26, in <module>
sock.connect((bd_addr, port))
File "C:\Python27\lib\site-packages\bluetooth\msbt.py", line 72, in connect
bt.connect (self._sockfd, addr, port)
IOError: A socket operation failed because the destination host was down.
I tried both COM19 and COM20 but got the same error.
My Bluetooth is connected via TX pin to arduino's RX pin and the arduino is connected to my PC so there is no error of COM port sharing that occurs sometimes.
Also when I connect my bluetooth module with laptop bluetooth and open Bluetooth Serial terminal and transmit data from there it works fine.
So there's some problem in my understanding and writing of Python code.
Please help...

Python Bluetooth Passkey/Password Linux

I'm working on a Python script to control my Mindstorms NXT with a Raspberry Pi.
My problem is, that the NXT has a Bluetooth passkey. You can change the passkey but not delete it.
I want to know how you can connect the PyBluez socket to a device with a passkey.
This is the current program:
import bluetooth
import socket
target_name = "Jerry"
target_address = None
print "performing inquiry..."
nearby_devices = bluetooth.discover_devices()
print "found %d devices" % len(nearby_devices)
for bdaddr in nearby_devices:
if target_name == bluetooth.lookup_name( bdaddr ):
target_address = bdaddr
break
if target_address is not None:
print "found target bluetooth device with address ", target_address
else:
print "could not find target bluetooth device nearby"
bluesock= socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
bluesock.connect((target_address, 1))
I'm not sure there's a Python specific answer. The py-nxt posts I saw seemed to point at the OS.
Does starting this background process (on your computer) with a passkey help you?
bluetooth-agent 1234 &
I've found it useful to pair with the NXT first using:
hcitool cc 00:16:53:0A:17:16
Whereby, I'd found the MAC address with:
hcitool scan
If you hadn't already tried the rfcomm related bits for Linux, there's a worthwhile ref here.
On Windows, I just had to go into go into Bluetooth settings and pair with the device, entering the passkey on Windows and then on the NXT. It never showed a screen saying that it had paired, seemingly getting stuck pairing, but it did work and I was able to connect with nxt-python.

Python: Binding a socket to /dev/rfcommX

I have a script that loads a Firmware on an embedded device over a serial port. The script takes the /dev/xxx adress of the serial port as an argument.
I have a special setup, where I do this over Bluetooth.
I managed to connect via bluetooth to the module in python. However I just can't find any example/information on how to register the local socket in a serial device like /dev/rfcomm0.
####### ORCA Bluetooth uploader Script #######
#As an input argument the script needs the BT Adress of the racer.
#if none is given, the script looks for nearby devices.
import bluetooth
import subprocess
import sys
import os
#Check if we received a BT ADDR
if sys.argv[-1] != 'bt_comm.py':
#Define the Pin for binding and the connection Port
#Our Pin is 0000
pin = "0000"
#The Bootoader is listening on Port 1 for a connection
port = 1
rfcomm_port = 0
#The BT Addr we get from the command line input
#TAG:TODO:Check the input for sanity
addr = sys.argv[-1]
#Build the Firmware image
subprocess.call("python ./px_mkfw.py --image ../../Firmware_orca/Images/px4fmu.bin > orca_fw",shell=True)
#Create an RFCOMM Socket
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
#Connect to the device
server_sock.connect((addr, port))
print "Connected to ",addr
Here I need some way to register server_sock at /dev/rfcomm0
#Call the px_uploader script
subprocess.call("python ./px_uploader.py --port /dev/rfcomm%d orca_fw" % rfcomm_port,shell=True)
#Close the connection
server_sock.close()
else:
#Look for BT Devices and print them
discovered_devices = bluetooth.discover_devices(lookup_names = True, flush_cache = True, duration = 20)
if discovered_devices is not None:
for addr in discovered_devices:
print "Found bluetooth device: ", addr
else:
print "Could not find any bluetooth device nearby"

Categories

Resources