I would like to receive the messages from my phone to raspberry over bluetooth
I have written the following code ,
import bluetooth
hostMACAddress = '18:9E:FC:A1:81:93' # The MAC address of my iphone
port = 3
backlog = 1
size = 1024
s = bluetooth.BluetoothSocket(bluetooth.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()
How can i receive the messages to my Raspberry when i run this code, i see no messages being received, my raspberry detects the MAC address of my iPhone but i would like to send some message and see if the bluetooth of raspberry can receive it
Kindly let me know what modifications i have to do in this code in order to achieve bluetooth connection
I haven't completed building an app using Flutter but I have the server/client code ready using python.
Server.py
import socket
import os
import multiprocessing
from multiprocessing import pool
os.system('sudo python3 relay.py C') #runs relay program and setups up GPIO pins
hostMACAddress = 'B8:27:EB:A3:B6:EB' # The MAC address of a Bluetooth adapter on the server.
backlog = 4
port=3
size = 1024
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.bind((hostMACAddress,port))
s.listen(backlog)
def new_client(client):
while 1:
data = client.recv(size)
if data:
n=data.decode("utf-8")
if n == 'ON':
os.system('sudo python3 relay.py ON')
if n == 'OFF':
os.system('sudo python3 relay.py OFF')
if n == 'CLOSE':
break
client.send(data)
if __name__ == '__main__':
client, address = s.accept()
pool = multiprocessing.Pool(4)
pool.map(new_client, (client, ))
pool.close()
pool.join
print("Closing socket")
client.close()
s.close()
This is my server program running on raspberry pi.
I implemented multithreading to allow 4 active connections(sockets) at all time, since bluetooth is a little different than web socket programming I had to get creative to keep the application running after any client closes connection.
Basically if I get the message ON/OFF, it in turn runs another python program that turn the relay on or off, if I get CLOSE message, I terminate the thread.
Client.py
import bluetooth
bd_addr = 'B8:27:EB:A3:B6:EB'
port = 3
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((bd_addr,port))
print("Connected")
while True:
try:
data = input()
sock.send(data.encode())
if data == 'CLOSE':
break
except KeyboardInterrupt:
sock.close()
This is my client program running on my computer.
Notice the address in both codes in the same(MAC Address of my raspberry pi), because raspberry pi need the address of the bluetooth adapter to use(in case some machines have multiple interfaces) and client needs server bluetooth MAC Address in order to initiate socket connection. You also need to port that you configured in raspbery pi to receive connection in my case 3.
Let me know if you need any additional information.
Have fun making an app that implements socket programming!
Related
I need to make an application that communicates through an RFCOMM socket to a Raspberry Pi, without pairing.
On the Android side, I have the MAC address of the RPi and I'm trying to connect to the server using this code:
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
BluetoothSocket mmSocket = null;
try {
mmSocket = device.createRfcommSocketToServiceRecord(UUID);
mmSocket.connect();
Log.d(TAG, "mmSocket returned");
}
...
UUID is the same as on the server-side, and i've also tried using the createInsecureRfcommSocket method.
On the Raspberry Pi side, I used the pybluez example of an rfcomm server(here is the example)
It once worked but I don't understand why it did or why it doesn't anymore, in the sense that when I tried to initiate the connection from the phone I got a pairing request on the Raspberry Pi without a pairing request on the phone, and the socket object on android had successfully connected.
Does anyone know what I am doing wrong, or any ideas that might help me, and is such a thing even feasible.
Thanks in advance.
I've found this unanswered question and I think I have a working solution at least for my case.
All I needed to do was to call these three commands:
sudo hciconfig hci0 piscan
sudo hciconfig hci0 sspmode 1
sudo hciconfig hci0 class 0x400100
The first two lines make the RPi discoverable, from this answer, which also claims the RPi should pair automatically. That does NOT work for me. It still requires PIN confirmation on both devices, that's unfortunate for a headless RPi.
The third line found in this answer is crucial and it is what allows to connect RFCOMM sockets to unpaired RPi.
It is possible that changing class will make other BT services stop working, not sure, I just need RFCOMM.
After this, the following example works for me with RPI 4B and my Win10 laptop:
import socket
from contextlib import closing
# MAC address of RPi, can be obtained with `bluetoothctl list` on RPi.
rpi_addr = 'e4:5f:01:7d:8A:A3'
# 1-32, some might be used already, e.g. 3 for me, in that case bind fails.
channel = 15
def server():
print("Creating socket")
with closing(socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM,
socket.BTPROTO_RFCOMM)) as s:
print("Binding socket")
s.bind((rpi_addr ,channel))
print("Listening socket")
s.listen()
s_sock, addr = s.accept()
with closing(s_sock):
print ("Accepted connection from "+str(addr))
data = s_sock.send(b"Hello from RPi")
def client():
print("Creating socket")
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM,
socket.BTPROTO_RFCOMM)
print("Connecting socket")
s.connect((rpi_addr,channel))
print("Connected")
data = s.recv(1024)
print(f"Received {data}")
I have a somewhat unusual problem. I want to run some code on my android smartphone via the ADB (which along with SL4A is already set up) and then I want it to act as a server and respond with the program's results while my host machine acts as a client and receives this data. However, I am not an expert in socket operations and I'm getting results I don't understand. My code is as follows:
from device import android
import socket
droid = android.Android()
# Open socket
s = socket.socket()
HOST = socket.gethostname()
PORT = 8000
s.bind((HOST, PORT))
s.listen(5)
print "HOST = ", HOST, ", PORT = ", PORT
# Accept instructions
c, addr = s.accept()
print "Got connection from", addr
data = ""
while True:
chunk = c.recv(1024)
if (not chunk):
break
else:
data.extend(chunk)
s.close()
# DO STUFF WITH RECEIVED INPUT
# Send result
c, addr = s.accept()
print "Got connection from", addr
while True:
if (c.send(str(result)):
break
s.close()
The code I'm running on the client, my host machine, is as follows:
s = socket.socket()
HOST = "localhost"
PORT = 8000
s.connect((HOST, PORT))
s.send(data)
s.close()
# IN A DIFFERENT FUNCTION
s = socket.socket()
HOST = "localhost"
PORT = 8000
try:
s.connect((HOST, PORT))
results = s.recv(1024)
s.close()
return results
except Exception:
return False
The environment has been set up this way:
set AP_PORT=54023
adb forward tcp:%AP_PORT% tcp:%AP_PORT%
So, how this is supposed to work is this: the server is set up to run on my Android smartphone and accept input to run the program on my Android smartphone from another program running on my PC. After the Android program has finished running, it should send the result back to my PC.
However, I'm having several problems. I can't seem to get the first connection open. I either get 10061's or 10049's and I'm not sure why that is. I've looked at the existing documentation available and I'm still not getting results. I'm also not sure if this code is actually running on the Android device and this is very important to my application so I really need some sort of confirmation on this.
Any enlightenment would be greatly appreciated.
The server program never ends until it reaches an exception, because you set up an inf loop: while True.
c.close() close the current connection, then the loop starts again and the program waits for another connection to accept.
The host program instead should end after the message is sent or when it reaches an exception.
What do you mean with: " I'm getting results I don't understand... This code runs without error... The problem I'm having is that I'm not getting any results back"?
What results do you get? Have you checked the data var?
I have a Python script that is running on Android-SL4A that returns the values from the orientation sensor. I would like to transfer those values as text to a raspberry pi 2B+. While I have some Python skills I am unfamiliar with TCP/IP but I found this code below, and similar code to run on the receiving device. While testing the code below, the listening code on a Windows PC appears to be listening just fine but when I execute the sending code (posted below) on the Android device it gives a error at
s.connect((TCP_IP, TCP_PORT))
I receive an error(Errno 111) that the connection was refused.
Any help debugging would be great.
import time, math, sys, traceback
import socket
print "imports done"
TCP_IP = '127.0.0.1'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
print "settings defined"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "socket created"
s.connect((TCP_IP, TCP_PORT))
print "connection made"
print "message sent"
data = s.recv(BUFFER_SIZE)
s.close()
print "received data:", data
print "All Done"
If you don't want to learn how low-level sockets work, you can always use someone else's library.
The popular ones with TCP support are Tornado and Twisted, but I suggest you use simpleTCP, as it doesn't require you learn an entire framework to simply send information over TCP. The project website has the 5-line program for an echo server and an even smaller example of client sockets on its front page.
I try to send AT commands from my computer (ubuntu 13.04) to my phone (Android 5.1) via bluetooth. I want to read the SMS.
I retrieve the MAC address of my phone with :
hcitool scan
I browse all available services on the device with :
sdptool browse XX:XX:XX:XX:XX:XX
I get the good RFCOMM channel for SMS/MMS service and now I'm trying to send the AT command.
I tried with pySerial with a bound and connected rfcomm to my phone but no response :
import serial
phone = serial.Serial('/dev/rfcomm0', 115200, timeout=2)
phone.write(b'AT\r')
data = phone.readall()
print data
I tried the same code on a USB serial port and I have a response :
import serial
phone = serial.Serial('/dev/ttyACM0', 115200, timeout=2)
phone.write(b'AT\r')
data = phone.readall()
print data
# *EMRDY: 1
# AT
# OK
I tried with pyBluez but same problem, no response of my AT command :
import bluetooth
client_sock = bluetooth.BluetoothSocket( bluetooth.RFCOMM )
client_sock.connect(('XX:XX:XX:XX:XX:XX', 4))
client_sock.send(b'AT\r')
data = client_sock.recv(1024)
print "received [%s]" % data
And I finally tried with native python sockets, but no response :
import socket
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.connect(('XX:XX:XX:XX:XX:XX',4))
s.send(b'AT\r')
data = s.recv(1024)
s.close()
print('Received', repr(data))
Note: The phone displays a prompt window to accept that my computer accesses my sms. Of course I accepted.
Can anyone tell me what is wrong and what I can try?
Well, for starter it is better to check first that you have a two-way communication between your Host computer and your Phone on bluetooth, like you said, it did work with USB, then there should be no reason it does not with bluetooth unless you didn't yet established a good communication, so I think it is better to try first that you have good communication by just sending and replying with the same string (kinda hand-shaking protocol) and make sure that you know what your python code is actually sending, may be unseen extra characters using bluetooth that you don't pay attention to, which makes your AT command unrecognizable by your phone.
I am trying to make a bluetooth connection with my Android client and a Python server. However, I am unable to do so since my Android client always fails to connect. Now I am wondering whether it is possible at all to use an Android Bluetooth socket and a python socket together. Is that possible?
And if so, do you have suggestions what else I might try? In a nutshell, this is what I do:
My Android client:
I get a Bluetooth device like this:
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().
getRemoteDevice(deviceAddress);
Where deviceAddress is equal to the bluetooth MAC address of my laptops bluetooth adapter. Which is E0:F8:47:3F:80:49
Then I use that device to create a Socket:
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID);
Where MY_UUID is this string: 00001101-0000-1000-8000-00805F9B34FB
After that I just call connect:
socket.connect();
And that is where it fails to connect. Maybe it is because of server wihich looks like this:
My Python server:
import bluetooth
hostMACAddress = 'E0:F8:47:3F:80:49' # The MAC address of a Bluetooth adapter
port = 3
backlog = 1
size = 1024
s = bluetooth.BluetoothSocket(bluetooth.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()