Esempio di comunicazione via Bluetooth
Per funzionare si deve caricare sia sul telefono che sul computer la libreria PyBluez.
Per il telefono si deve seguire la procedura per importare i moduli di Py4a e quindi si deve scaricare il file .egg da posizionare poi nella directory download della scheda SD
Per la libreria sul computer ho riscontrato che scaricando i file tgz ed eseguendo python setup.py install si genera un errore di compilazione su gcc. Per questo motivo ho installato il pacchetto Debian gia' compilato python-bluez
----------------------------------------------------------------------------------------------------------------------------
# file: rfcomm-server.py
# auth: Albert Huang <albert@csail.mit.edu>
# desc: simple demonstration of a server application that uses RFCOMM sockets
#
# $Id: rfcomm-server.py 518 2007-08-10 07:20:07Z albert $
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
advertise_service( server_sock, "SampleServer",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
# protocols = [ OBEX_UUID ]
)
print "Waiting for connection on RFCOMM channel %d" % port
client_sock, client_info = server_sock.accept()
print "Accepted connection from ", client_info
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print "%s" % data
except IOError:
pass
print "disconnected"
client_sock.close()
server_sock.close()
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
# file: rfcomm-client.py
# auth: Albert Huang <albert@csail.mit.edu>
# desc: simple demonstration of a client application that uses RFCOMM sockets
# intended for use with rfcomm-server
#
# $Id: rfcomm-client.py 424 2006-08-24 03:35:54Z albert $
from bluetooth import *
import sys
import android
import time
import math
addr = None
droid = android.Android();
droid.startSensingTimed(1,1000)
time.sleep(3)
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
service_matches = find_service( uuid = uuid, address = addr )
if len(service_matches) == 0:
print "couldn't find the SampleServer service =("
sys.exit(0)
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
sock=BluetoothSocket( RFCOMM )
sock.connect((host, port))
print "Connesso"
while True:
az = str(math.degrees(droid.sensorsReadOrientation().result[0]))
pitch = str(math.degrees(droid.sensorsReadOrientation().result[1]))
roll = str(math.degrees(droid.sensorsReadOrientation().result[2]))
data = az+";"+pitch+";"+roll
if len(data) == 0: break
sock.send(data)
sock.close()
----------------------------------------------------------------------------------------------------------------------------
Visualizzazione post con etichetta Datalogger. Mostra tutti i post
Visualizzazione post con etichetta Datalogger. Mostra tutti i post
lunedì 16 gennaio 2012
Datalogger in UDP
L'ennesima versione del datalogger che usa il protocollo UDP per scambiare i dati
-----------------------------------------------------------------------------------------------------
import android
import socket
import time
import math
droid = android.Android();
hostname = "192.168.0.1";
port = 21567;
data = "";
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM);
s.connect((hostname,port));
droid.startSensingTimed(1,1000)
time.sleep(3)
while True:
az = str(math.degrees(droid.sensorsReadOrientation().result[0]))
pitch = str(math.degrees(droid.sensorsReadOrientation().result[1]))
roll = str(math.degrees(droid.sensorsReadOrientation().result[2]))
s.sendto(az+";"+pitch+";"+roll,(hostname,port));
-----------------------------------------------------------------------------------------------------
# Server program
import string
from socket import *
host = "192.168.0.1"
port = 21567
buf = 1024
addr = (host,port)
UDPSock = socket(AF_INET,SOCK_DGRAM)
UDPSock.bind(addr)
while 1:
data,addr = UDPSock.recvfrom(buf)
if not data:
print "Client has exited!"
break
else:
valori = string.split(data,";")
print valori[0]
print valori[1]
print valori[2]
# Close socket
UDPSock.close()
domenica 15 gennaio 2012
Limitazioni sui sensori dei telefoni Android
Accelerometri
Come riportato qui la misura delle accelerazioni con i sensori dei telefoni e' chiaramente dipendente dal tipo di chip che si utilizza ma in ogni caso Android mostrera' un valore con un numero di cifre decimali che e' di molto superiore a quello realmente significativo per lo strumento. Per esempio (qui) il sensore Bosch BMA 150 campiona solo su 8 bit quindi in un range 0-2g vede solo variazioni di 0.08g.
In generale inoltre i sensori a basso costo sono molto rumorosi; il comando StartSensing cerca di ridurre il rumore dello strumento.
In alcuni casi il costruttore limita il range di misura da 0 a 2g
Sensore di luce
In molti casi il sensore di luce viene impiegato come sensore di prossimita' quindi in alcuni casi la risposta del sensore e', a livello software, limitata ad una risposta di tipo binario anche se di fatto l'hardware sarebbe in grado di effettuare misure piu' precise. Inoltre il sensore di luce puo' essere molto lento nel refresh del proprio stato anche a valori prossimi ad 1 secondo
Magnetometro
Questo sensore, che fornisce informazioni anche di orientamento, e' fortemente affetto dalla presenza di sostanze metalliche nelle vicinanze
Da un breve test basato su 120 misure effettuate lasciando il telefono su un tavolo senza muoverlo ho registrato che
Accelerazione X = -0.41 +- 0.11 m/sec2
Accelerazione Y = -0.032 +- 0.23 m/sec2
Accelerazione Z = 9.91 +- 0.14 m/sec2
Come riportato qui la misura delle accelerazioni con i sensori dei telefoni e' chiaramente dipendente dal tipo di chip che si utilizza ma in ogni caso Android mostrera' un valore con un numero di cifre decimali che e' di molto superiore a quello realmente significativo per lo strumento. Per esempio (qui) il sensore Bosch BMA 150 campiona solo su 8 bit quindi in un range 0-2g vede solo variazioni di 0.08g.
In generale inoltre i sensori a basso costo sono molto rumorosi; il comando StartSensing cerca di ridurre il rumore dello strumento.
In alcuni casi il costruttore limita il range di misura da 0 a 2g
Sensore di luce
In molti casi il sensore di luce viene impiegato come sensore di prossimita' quindi in alcuni casi la risposta del sensore e', a livello software, limitata ad una risposta di tipo binario anche se di fatto l'hardware sarebbe in grado di effettuare misure piu' precise. Inoltre il sensore di luce puo' essere molto lento nel refresh del proprio stato anche a valori prossimi ad 1 secondo
Magnetometro
Questo sensore, che fornisce informazioni anche di orientamento, e' fortemente affetto dalla presenza di sostanze metalliche nelle vicinanze
Da un breve test basato su 120 misure effettuate lasciando il telefono su un tavolo senza muoverlo ho registrato che
Accelerazione X = -0.41 +- 0.11 m/sec2
Accelerazione Y = -0.032 +- 0.23 m/sec2
Accelerazione Z = 9.91 +- 0.14 m/sec2
Azimuth = -0.44 +- 0.075 (errore di circa 4.2°)
Pitch = 0.0017 +- 0.024 (errore di circa 1.35°)
Roll = 0.04 +- 0.014 (errore di circa 0.8°)
venerdì 13 gennaio 2012
Datalogger + Twetter
Una versione del Datalogger con salvataggio su Twetter (poco utile a fini scientifici). Dalle prime prove la latenza di Twetter e' decisamente superiore a quella di GDocs
---------------------------------------------------------------------------------------------
import android, time, tweepy
from time import strftime
CONSUMER_KEY = 'xxxxxxxxx'
CONSUMER_SECRET = 'xxxxxxxxxxxxx'
ACCESS_KEY = 'xxxxxxxxxxxxxxxx'
ACCESS_SECRET = 'xxxxxxxxxxxxxxxxxxx'
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)
droid = android.Android()
droid.startSensingTimed(1,1000)
time.sleep(3)
acq = 0
while True:
accx = str(droid.sensorsReadAccelerometer().result[0])
accy = str(droid.sensorsReadAccelerometer().result[1])
accz = str(droid.sensorsReadAccelerometer().result[2])
az = str(droid.sensorsReadOrientation().result[0])
pitch = str(droid.sensorsReadOrientation().result[1])
roll = str(droid.sensorsReadOrientation().result[2])
orario = strftime("%Y-%m-%d %H:%M:%S")
outString = "Azimuth: " + az + " Pitch: " + pitch + " Roll: " + roll + " - " + orario
api.update_status(outString)
acq = acq + 1
print "Dato " + str(acq)
time.sleep(30)
droid.stopSensing()
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
import android, time, tweepy
from time import strftime
CONSUMER_KEY = 'xxxxxxxxx'
CONSUMER_SECRET = 'xxxxxxxxxxxxx'
ACCESS_KEY = 'xxxxxxxxxxxxxxxx'
ACCESS_SECRET = 'xxxxxxxxxxxxxxxxxxx'
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)
droid = android.Android()
droid.startSensingTimed(1,1000)
time.sleep(3)
acq = 0
while True:
accx = str(droid.sensorsReadAccelerometer().result[0])
accy = str(droid.sensorsReadAccelerometer().result[1])
accz = str(droid.sensorsReadAccelerometer().result[2])
az = str(droid.sensorsReadOrientation().result[0])
pitch = str(droid.sensorsReadOrientation().result[1])
roll = str(droid.sensorsReadOrientation().result[2])
orario = strftime("%Y-%m-%d %H:%M:%S")
outString = "Azimuth: " + az + " Pitch: " + pitch + " Roll: " + roll + " - " + orario
api.update_status(outString)
acq = acq + 1
print "Dato " + str(acq)
time.sleep(30)
droid.stopSensing()
---------------------------------------------------------------------------------------------
Twitter via Android su telefono
Inviare tweet dal telefono Android prevede una procedura un po' differente rispetto a quella pubblicata qualche post fa.
Per prima cosa si deve scaricare da qui la libreria tweepy, in particolare a me funziona la versione 2.6
Successivamente dal telefono si deve aprire Python per Android/Import Modules e si seleziona la libreria per l'installazione
Lo script per postare su Tweet e' semplice come nell'esempio ripreso da un libro su SL4A
-------------------------------------------------------------------------------------------------------------
import android, datetime, time, tweepy
CONSUMER_KEY = 'xxxxxxx'
CONSUMER_SECRET = 'xxxxxxxxxxxxx'
ACCESS_KEY = 'xxxxxxxxxxx'
ACCESS_SECRET = 'xxxxxxxxxxxx'
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)
droid = android.Android()
droid.startLocating()
time.sleep(15)
loc = droid.readLocation()
droid.stopLocating()
if 'gps' in loc.result:
lat = str(loc.result['gps']['latitude'])
lon = str(loc.result['gps']['longitude'])
else:
lat = str(loc.result['network']['latitude'])
lon = str(loc.result['network']['longitude'])
now = str(datetime.datetime.now())
outString = 'I am here: ' + now + ' ' + lat + ' ' + lon
api.update_status(outString)
-------------------------------------------------------------------------------------------------------------
Per prima cosa si deve scaricare da qui la libreria tweepy, in particolare a me funziona la versione 2.6
Successivamente dal telefono si deve aprire Python per Android/Import Modules e si seleziona la libreria per l'installazione
Lo script per postare su Tweet e' semplice come nell'esempio ripreso da un libro su SL4A
-------------------------------------------------------------------------------------------------------------
import android, datetime, time, tweepy
CONSUMER_KEY = 'xxxxxxx'
CONSUMER_SECRET = 'xxxxxxxxxxxxx'
ACCESS_KEY = 'xxxxxxxxxxx'
ACCESS_SECRET = 'xxxxxxxxxxxx'
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)
droid = android.Android()
droid.startLocating()
time.sleep(15)
loc = droid.readLocation()
droid.stopLocating()
if 'gps' in loc.result:
lat = str(loc.result['gps']['latitude'])
lon = str(loc.result['gps']['longitude'])
else:
lat = str(loc.result['network']['latitude'])
lon = str(loc.result['network']['longitude'])
now = str(datetime.datetime.now())
outString = 'I am here: ' + now + ' ' + lat + ' ' + lon
api.update_status(outString)
-------------------------------------------------------------------------------------------------------------
Datalogger + GDocs + Python + Android
Una versione differente del datalogger con salvataggio non in locale ma in real timesu Goggle Docs
Per prima cosa si deve creare uno Spreadsheet su Google Docs mettendo nella prima riga il nome delle colonne che saranno poi di riferimento per lo scrpit Python (i nomi devono essere minucoli e senza caratteri speciali)
Ci si deve inoltre annotare la key che compare nella URL
a questo punto lo script del Datalogger e' modificato come segue utilizzando le librerie GData che sono incluse in Python per SL4A nel pacchetto extra
-----------------------------------------------------------------------------------------------------
import android, time
from time import strftime
import gdata.spreadsheet.service
droid = android.Android()
email = 'lucainnoc@gmail.com'
password = 'password'
# Find this value in the url with 'key=XXX' and copy XXX below
spreadsheet_key = '0AvBeE7yoBqdHdFdmOW1UQUthVFpMZzF1S0lRWjRWdFE'
worksheet_id = 'od6' #indica il primo foglio
spr_client = gdata.spreadsheet.service.SpreadsheetsService()
spr_client.email = email
spr_client.password = password
spr_client.source = 'Example Spreadsheet Writing Application'
spr_client.ProgrammaticLogin()
droid.startSensingTimed(1,1000)
time.sleep(3)
acq = 0
while True:
accx = str(droid.sensorsReadAccelerometer().result[0])
accy = str(droid.sensorsReadAccelerometer().result[1])
accz = str(droid.sensorsReadAccelerometer().result[2])
az = str(droid.sensorsReadOrientation().result[0])
pitch = str(droid.sensorsReadOrientation().result[1])
roll = str(droid.sensorsReadOrientation().result[2])
orario = strftime("%Y-%m-%d %H:%M:%S")
dict = {}
#dict['date'] = time.strftime('%m/%d/%Y')
dict['time'] = orario
dict['accx'] = accx
dict['accy'] = accy
dict['accz'] = accz
dict['az'] = az
dict['pitch'] = pitch
dict['roll'] = roll
entry = spr_client.InsertRow(dict, spreadsheet_key, worksheet_id)
if isinstance(entry, gdata.spreadsheet.SpreadsheetsList):
#print "Insert row succeeded."
acq = acq + 1
print "Dato " + str(acq)
else:
print "Insert row failed."
time.sleep(1)
droid.stopSensing()
conn.close()
-----------------------------------------------------------------------------------
Lanciando lo script su telefono e tenendo aperto il foglio di calcolo nel browser del computer si vedranno le righe popolarsi con il passare del tempo. Il tempo di campionamento minimo e' piuttosto lungo (al minimo occorre circa 1 secondo per acquisizione) a causa della latenza della rete
Riferimenti : http://www.brokenairplane.com/2011/08/im-not-texting-im-programming.html (il sistema di autenticazione del mio script rispetto a quello di DoScience.py e' differente in quanto con il metodo proposto al link Google risponde con un errore di autenticazione)
Per prima cosa si deve creare uno Spreadsheet su Google Docs mettendo nella prima riga il nome delle colonne che saranno poi di riferimento per lo scrpit Python (i nomi devono essere minucoli e senza caratteri speciali)
Ci si deve inoltre annotare la key che compare nella URL
a questo punto lo script del Datalogger e' modificato come segue utilizzando le librerie GData che sono incluse in Python per SL4A nel pacchetto extra
-----------------------------------------------------------------------------------------------------
import android, time
from time import strftime
import gdata.spreadsheet.service
droid = android.Android()
email = 'lucainnoc@gmail.com'
password = 'password'
# Find this value in the url with 'key=XXX' and copy XXX below
spreadsheet_key = '0AvBeE7yoBqdHdFdmOW1UQUthVFpMZzF1S0lRWjRWdFE'
worksheet_id = 'od6' #indica il primo foglio
spr_client = gdata.spreadsheet.service.SpreadsheetsService()
spr_client.email = email
spr_client.password = password
spr_client.source = 'Example Spreadsheet Writing Application'
spr_client.ProgrammaticLogin()
droid.startSensingTimed(1,1000)
time.sleep(3)
acq = 0
while True:
accx = str(droid.sensorsReadAccelerometer().result[0])
accy = str(droid.sensorsReadAccelerometer().result[1])
accz = str(droid.sensorsReadAccelerometer().result[2])
az = str(droid.sensorsReadOrientation().result[0])
pitch = str(droid.sensorsReadOrientation().result[1])
roll = str(droid.sensorsReadOrientation().result[2])
orario = strftime("%Y-%m-%d %H:%M:%S")
dict = {}
#dict['date'] = time.strftime('%m/%d/%Y')
dict['time'] = orario
dict['accx'] = accx
dict['accy'] = accy
dict['accz'] = accz
dict['az'] = az
dict['pitch'] = pitch
dict['roll'] = roll
entry = spr_client.InsertRow(dict, spreadsheet_key, worksheet_id)
if isinstance(entry, gdata.spreadsheet.SpreadsheetsList):
#print "Insert row succeeded."
acq = acq + 1
print "Dato " + str(acq)
else:
print "Insert row failed."
time.sleep(1)
droid.stopSensing()
conn.close()
-----------------------------------------------------------------------------------
Lanciando lo script su telefono e tenendo aperto il foglio di calcolo nel browser del computer si vedranno le righe popolarsi con il passare del tempo. Il tempo di campionamento minimo e' piuttosto lungo (al minimo occorre circa 1 secondo per acquisizione) a causa della latenza della rete
Riferimenti : http://www.brokenairplane.com/2011/08/im-not-texting-im-programming.html (il sistema di autenticazione del mio script rispetto a quello di DoScience.py e' differente in quanto con il metodo proposto al link Google risponde con un errore di autenticazione)
giovedì 12 gennaio 2012
Datalogger (prima versione funzionante)
Uno degli obbiettivi che mi sono posto nella programmazione in Python SL4A e' quello di realizzare un sensore a basso costo (una sorta di datalogger con la possibilita' anche di invio dei dati via Internet)
Il primo passo e' quello di registrare i dati ed inserirli in DB
Di seguito il programma ed una prima prova
Struttura del Database
Il primo passo e' quello di registrare i dati ed inserirli in DB
Di seguito il programma ed una prima prova
Struttura del Database
Script Python SL4A
Il programma registra le accelerazione e le inclinazione sui tre assi del telefono e li inserisce in DB SQLite
Il programma registra le accelerazione e le inclinazione sui tre assi del telefono e li inserisce in DB SQLite
------------------------------------------------------------------------------------------------------
import android, time, sqlite3
from time import strftime
droid = android.Android()
conn = sqlite3.connect('/sdcard/datalogger.db')
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS dati (accx REAL,accy REAL,accz REAL,tiltx REAL,tilty REAL,tiltz REAL,id INTEGER PRIMARY KEY AUTOINCREMENT,tempo DATETIME)")
droid.startSensingTimed(1,1000)
time.sleep(3)
while True:
accx = str(droid.sensorsReadAccelerometer().result[0])
accy = str(droid.sensorsReadAccelerometer().result[1])
accz = str(droid.sensorsReadAccelerometer().result[2])
az = str(droid.sensorsReadOrientation().result[0])
pitch = str(droid.sensorsReadOrientation().result[1])
roll = str(droid.sensorsReadOrientation().result[2])
orario = strftime("%Y-%m-%d %H:%M:%S")
sql_string = "INSERT INTO dati (accx,accy,accz,tiltx,tilty,tiltz,tempo) VALUES ('"+accx+"','"+accy+"','"+accz+"','"+az+"','"+pitch+"','"+roll+"','"+orario+"')"
cursor.execute(sql_string)
conn.commit()
time.sleep(1)
droid.stopSensing()
conn.close()
----------------------------------------------------------------------------------------------
Grafico della prima prova
La prima prova e' stata eseguita salendo e scendendo due rampe di scale (in rosso l'asse Z)
Grafico della prima prova
La prima prova e' stata eseguita salendo e scendendo due rampe di scale (in rosso l'asse Z)
Iscriviti a:
Post (Atom)
Debugger integrato ESP32S3
Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede nell'ID USB della porta Jtag. Nel modulo...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...