Visualizzazione post con etichetta Datalogger. Mostra tutti i post
Visualizzazione post con etichetta Datalogger. Mostra tutti i post

lunedì 16 gennaio 2012

Datalogger su Bluetooth

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()

----------------------------------------------------------------------------------------------------------------------------

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

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()
---------------------------------------------------------------------------------------------


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)
-------------------------------------------------------------------------------------------------------------

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)



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



Script Python SL4A
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)



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...