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.
Related
I'm having issues when trying to use bluetooth on my project. On previous version I used the HC-05 module for bluetooth and it gives me a simple serial connection right after any device connects. Now the project evolved and we opted on using SIM800H because it gives us GSM+Bluetooth.
When I connect any android device it gives me some profiles but never SPP. I can pair normally but when using any SPP server app (https://stackoverflow.com/a/4037619/2637661) I can never send or get data from my device. If I start the connection from the Android app, it says that it's connecting while the SIM800 gives me the URC and I respond:
+BTCONNECTING: "34:c7:31:aa:37:5b","SPP"
AT+BTACPT=1
OK
+BTCONNECT: 1,"Android",34:c7:31:aa:37:5b,"SPP"
But it stays on server mode and I can't use the commands AT+BTSPPSEND or AT+BTSPPGET, as the documentation says.
On the other hand, if I start the connection from my device just like the docs say:
AT+BTCONNECT=1,4 // Device is 1 and SPP profile is 4
OK
AT+BTSPPSEND
>I type anything here + ctrl+z
SEND FAIL
and get nothing on the Android side.
Plus in both cases the connection drops after something like 30s and I can't reestablish it unless I turn the SIM800H off and on again.
Got no success using the APP mode either (sending the string "SIMCOMSPPFORAPP" right after connection succeeds for transparent communication).
The SIM800H firmware version is
AT+CGMR
Revision:1309B07SIM800H32_BT
and I tried using the following apps
Bluetooth Terminal
Bluetooth spp pro
BlueSPP
The GSM side works flawlessly and I can send/receive TCP messages everytime I try.
Does anyone have any kind of experience using this module? Thanks for reading!
UPDATE:
I'm using a simple sketch in order to talk with the module's serial, don't know if it's relevant but here it goes.
#define SIM800_POWER 23
void setup() {
Serial.begin(9600);
Serial1.begin(19200);
Serial.print("Setting all up");
pinMode(SIM800_POWER, OUTPUT);
Serial.print(".");
delay(500);
digitalWrite(SIM800_POWER, HIGH);
Serial.print(".");
Serial.println("OK");
}
void loop() {
if(Serial1.available()){
Serial.write(Serial1.read());
}
if(Serial.available()){
Serial1.write(Serial.read());
}
}
And what I get after trying Andrii's answer:
Setting all up..OK
AT
OK
AT
OK
AT
OK
AT+BTPOWER=0
OK
AT+BTPOWER=1
OK
AT+BTCONNECT=1,4
OK
+BTCONNECT: 1,"Will",d4:87:d8:77:37:0b,"SPP"
AT+BTSTATUS?
+BTSTATUS: 5
P: 1,"Will",d4:87:d8:77:37:0b
C: 1,"Will",d4:87:d8:77:37:0b,"SPP"
OK
AT+BTSPPSEND
> SIMCOMSPPFORAPP
SEND FAIL
Seems AT+BTSPPSEND without any parameters is only for AT-command send from client (your SIM800H) to server (other SIM800, not your Android device unless your Android device implements AT-command support). For data sending you should use AT+BTSPPSEND and after receiving > symbol send SIMCOMSPPFORAPP keyword and then, after receiving SEND OK response send command AT+BTSPPSEND=<LENGTH_OF_YOUR_DATA> and then, after receiving > symbol, send your data until Ctrl+Z code e.g.:
AT+BTSPPSEND
> SIMCOMSPPFORAPP
SEND OK
AT+BTSPPSEND=5
> HELLO
SEND OK
^Z
where HELLO - is your data, and 5 in AT+BTSPPSEND=5 is length of HELLO string. Details in SIM800H_BT_Application_Note.
UPDATE
Selected by bold small, but important part of answer (thanks to hlovdal)
I just got started with Raspberry pi and I wanted to make a program on my Raspberry which gets input from an app on my Android/iOS device over bluetooth. I wanted to first check if something like this is possible and second if you have any clues on how to do something like this.
Thanks
PS: Since I just got started I'm only looking for clues and I don't want anyone to write and app for me so don't down vote
You would likely need to establish a network communication between the Raspberry Pi and the device.
For the server:
import socket
HOST = '' # This should receive from all available interfaces.
PORT = 1111 # Random port number.
data = "Test" # Data to send to the client.
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((HOST, PORT))
while True:
s.sendto(data, (HOST, PORT))
print data
On the client, very similar code but add:
data, addr = s.recvfrom(1024)
print addr
print "Message received: ", data
Under the while True
Reference the following for setting up RPI wireless hotspot:
http://elinux.org/RPI-Wireless-Hotspot
The HOST for each is going to be the device IPv4 address, usually in format:
192.168.x.x.
I have not personally found a way without using serials for data communication. The most common way to communicate information between devices is over network. Look into peer-to-peer network solutions.
The code may not work as is, you will need to make client/server-side code specific for your needs.
Reference the following for setting up sockets and a low-level network interface: https://docs.python.org/2/howto/sockets.html
Hopefully this helps.
EDIT:
There is a Bluetooth method for RPI.
Here's a good branch in Github that contains example of the Bluetooth library used in Python:
https://github.com/karulis/pybluez/blob/master/examples/simple
Good references:
Bluetooth programming with Python.
http://people.csail.mit.edu/albert/bluez-intro/c212.html
How to create a Bluetooth tag with RPI.
https://www.raspberrypi.org/magpi/create-a-raspberry-pi-3-bluetooth-tag/
in my current project it is a requirement to send a file from a windows computer to an android device over bluetooth without anything on the phone other than it's standard state and of course a paired bluetooth connection. i've looked over pybluez and it seemed simple enough to send files between a client and server architecture (and in fact got it sending between my laptop and desktop rather quickly) but I cannot for the life of me find any way to get python to send a file from the computer to android once the connection is established; my attempts have been grabbing the bluetooth mac address like thing from the device like so
nearby_devices = bluetooth.discover_devices(
duration=8, lookup_names=True, flush_cache=True, lookup_class=False)
and then later trying to send the files like so
port = 1
for addr, name in nearby_devices:
bd_addr = addr
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((bd_addr, port))
sock.send("download-app")
sock.close()
Of course with the example script given by the pybluez documentation I can seamlessly send files between a client and a server but I am still stuck without a way to send a file to the selected android device (even if I specify it's address and know it's within range)
You're most of the way there...
As you know, you need something to talk to at the other end of your Bluetooth connection. You just need to replace your custom server with a well-known service (generally one of these options).
In my case, my phone supports the "OBEX Object Push" service, so I just need to connect to that and use a suitable client to talk the right protocol. Fortunately, the combination of PyOBEX and PyBluez does the trick here!
The following code (quickly patched together from PyOBEX and PyBluez samples) runs on my Windows 10, Python 2.7 installation and creates a simple text file on the phone.
from bluetooth import *
from PyOBEX.client import Client
import sys
addr = sys.argv[1]
print("Searching for OBEX service on %s" % addr)
service_matches = find_service(name=b'OBEX Object Push\x00', address = addr )
if len(service_matches) == 0:
print("Couldn't find the service.")
sys.exit(0)
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
print("Connecting to \"%s\" on %s" % (name, host))
client = Client(host, port)
client.connect()
client.put("test.txt", "Hello world\n")
client.disconnect()
Looks like PyOBEX is a pretty minimal package, though, and isn't Python 3 compatible, so you may have a little porting to do if that's a requirement.
I haven't personally explored it but check out this blog -
http://recolog.blogspot.com/2013/07/transferring-files-via-bluetooth-using.html
The author uses the lightblue package as an API for the Obex protocol and send files over the connection. Now the lightblue package appears to be unmaintained. There are other packages like PyObex (which I could not import for whatever reason) which you could also explore as alternatives but lightblue seems to be the way to go.
I have made a Python 3 port of PyOBEX based on the PyOBEX code on bitbucket. I've tested so far only the client functionalities, but I expect the server to be working fine as well, since most of the compatibility issues with Python 3 were due to struct.pack/struct.unpack binary blobs appended to strings that should have all been tackled.
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 willing to create a server and client program on my android mobile devices.
The devices communicate with each other on the same wifi network, therefore, some simple scanning mechanism must be implemented - The client phones search for a server phone through some kind of broadcast.
What I did:
My protocol - the client phone broadcasts a message port p on the wifi, the server listens on port p. when the server gets the broadcast message it sends a message back, therefore discovering itself to the client.
My code -
I have opened a broadcast socket on my app, it sends a broadcast message.
Meanwhile there is a python script on my PC that listens and replies - I use python so that my testing will be easier - Wireshark on the PC and I can see everything.
What happens:
When I use one of my Galaxy S phones - it works and I get a response.
When I use the other Galaxy S phone - it doesn't work.
Now this is what I know:
The phone that works actually has Nexus ROM on it Ver. 4.1.1
The phone that doesn't work has 2.3.3 regular galaxy ROM
The python code says it receives both of the broadcasts sent from both phones, and replies to both of them without raising any exception.
So far I was thought the problem may be
1. the older version'd phone.
2. the windows firewall
3. the router firewall
So I have opened Wireshark, and Indeed I saw that both phones are sending their broadcasts - it was logged on Wireshark.
But the python script only responded to the first one.
So this is why 1 & 3 are irrelevant - if the router firewall was blocking my UDP I would have still seen the python server response, same with the older versioned phone.
To get rid of 2 i just disabled the windows firewall - still same problem.
Does anyone has a clue to why this effect might happen?
Thanks!
Edit
My python code:
def scan(data, addr, sock):
print "received scan message:", data, addr
name = u"name".encode("utf-16-le")
data = "DISC" + short2bytes(len(name)) + name
print "sending back %s to %s" % (data, addr)
sock.sendto(data, addr)
if __name__ == "__main__":
sock = socket(AF_INET, SOCK_DGRAM)
sock.bind(('', UDP_PORT))
while 1:
data, addr = sock.recvfrom(1500)
print "received packet " + data
if data.startswith("SCAN"):
scan(data, addr, sock)
edit 2:
Okay! Seems like my code and protocol DID work.
As it turns out the 2.3.3 phone had some severe ARP problems.
After some resets it works flawlessly!