Codice Python - ST Tracker

Vai ai contenuti

Menu principale:

Codice Python:
Sono stati creati due script python: Activity.py che acquisisce e archivia i dati dell'accelerometro e UpdateDB.py che contiene le funzioni per accedere al Database.

Activity.py

Librerie necessarie:

import smbus                              
import struct
import UpdateDB as mdb
from datetime import datetime
from time import sleep

Indirizzi e bus I2C:

PWR_MGMT_1   = 0x6B
SMPLRT_DIV   = 0x19
CONFIG       = 0x1A
GYRO_CONFIG  = 0x1B
INT_ENABLE   = 0x38
ACCEL_XOUT_H = 0x3B
ACCEL_YOUT_H = 0x3D
ACCEL_ZOUT_H = 0x3F
GYRO_XOUT_H  = 0x43
GYRO_YOUT_H  = 0x45
GYRO_ZOUT_H  = 0x47

Battery_bus = smbus.SMBus(1)    
Battery_Address = 0x36
MPU6050_bus = smbus.SMBus(3)    
MPU6050_Address = 0x68

Inizializzazione dell'accelerometro:

def MPU_Init():
   MPU6050_bus.write_byte_data(MPU6050_Address, SMPLRT_DIV, 7)
   MPU6050_bus.write_byte_data(MPU6050_Address, PWR_MGMT_1, 1)
   MPU6050_bus.write_byte_data(MPU6050_Address, CONFIG, 0)
   MPU6050_bus.write_byte_data(MPU6050_Address, GYRO_CONFIG, 24)
   MPU6050_bus.write_byte_data(MPU6050_Address, INT_ENABLE, 1)

Funzioni per la lettura dei dati dell'accelerometro:

def read_raw_data(addr):
   high = MPU6050_bus.read_byte_data(MPU6050_Address, addr)
   low = MPU6050_bus.read_byte_data(MPU6050_Address, addr+1)
   value = ((high << 8) | low)
   if(value > 32768):
           value = value - 65536
   return value

def read_state():
   acc_x = read_raw_data(ACCEL_XOUT_H)
   acc_y = read_raw_data(ACCEL_YOUT_H)
   acc_z = read_raw_data(ACCEL_ZOUT_H)
   gyro_x = read_raw_data(GYRO_XOUT_H)
   gyro_y = read_raw_data(GYRO_YOUT_H)
   gyro_z = read_raw_data(GYRO_ZOUT_H)
   Ax = acc_x/16384.0
   Ay = acc_y/16384.0
   Az = acc_z/16384.0
   Gx = gyro_x/131.0
   Gy = gyro_y/131.0
   Gz = gyro_z/131.0
   if (Gx<-1.5 or Gy<-1.5 or Gz<-1.5 or Gx>1.5 or Gy>1.5 or Gz>1.5):
       state = 0
   elif (Ax>0.1 and Ax<0.9 and Ay>-1.2 and Ay<-0.4 and Az<0.7 and Az>-0.1):
       state = 1
   elif (Ax>0.6 and Ax<1.4 and Ay>-0.4 and Ay<0.4 and Az<0.0 and Az>-0.8):
       state = 2
   elif (Ax>0.1 and Ax<0.9 and Ay>0.4 and Ay<1.2 and Az<0.7 and Az>-0.1):
       state = 3
   elif (Ax<0.4 and Ax>-0.4 and Ay>-0.4 and Ay<0.4 and Az<1.4 and Az>0.6):
       state = 4    
   elif (Ax>-0.9 and Ax<-0.1 and Ay>-1.2 and Ay<-0.4 and Az<0.1 and Az>-0.7):
       state = 5
   elif (Ax>-1.3 and Ax<-0.5 and Ay>-0.4 and Ay<0.4 and Az<0.8 and Az>0.0):
       state = 6
   elif (Ax>-0.9 and Ax<-0.1 and Ay>0.4 and Ay<1.2 and Az<0.1 and Az>-0.7):
       state = 7
   elif (Ax<0.4 and Ax>-0.4 and Ay>-0.4 and Ay<0.4 and Az<-0.6 and Az>-1.4):
       state = 8
   else:
       state = 0
   return state

Funzioni per la lettura dei dati della batteria:

def read_voltage():
read = Battery
_bus.read_word_data(Battery
_Address, 2)
swapped = struct.unpack("H", read))[0]
voltage = swapped * 78.125 /1000000
return voltage

def read_capacity():
read = Battery
_bus.read_word_data(Battery
_Address, 4)
swapped = struct.unpack("H", read))[0]
capacity = swapped/256
return capacity

Inizializzazione dell'accelerometro e delle variabili necessarie:
nota: è necessario uno sleep di 15 secondi per evitare errori eseguendo lo script all'avvio del sistema.

MPU_Init()
cur_state = 0
old_state = 0
cur_capacity = 0
old_capacity = 0
sleep(15)

Questo ciclo controlla ogni secondo i parametri forniti dell'accelerometro e dalla batteria e, in caso di variazioni, aggiorna il database. A mezzanotte o in caso di cambiamento della data viene chiamata la funzione che calcola il riepilogo della giornata e lo inserisce nella tabella "daily_activities".

while True:
   cur_state = read_state()
   cur_datetime = datetime.now()
   last_datetime = mdb.check_last_date()
   if cur_datetime.day==last_datetime.day and cur_datetime.month==last_datetime.month and cur_datetime.year==last_datetime.year:
       if old_state != cur_state:
           if old_state == 0:
               start_time = cur_datetime
               old_state = cur_state
           elif cur_state == 0:
               end_time = cur_datetime
               mdb.insert_today_activity(old_state, start_time, end_time)
               old_state = cur_state
           else:
               end_time = cur_datetime
               mdb.insert_today_activity(old_state, start_time, end_time)
               start_time = cur_datetime
               old_state = cur_state
       elif (datetime.now().hour == 23 and datetime.now().minute == 59 and datetime.now().second == 58):
           end_time = datetime.now()
           mdb.insert_today_activity(old_state, start_time, end_time)
           mdb.updates_daily_activities()
           sleep(2)
           start_time = cur_datetime
   else:
       mdb.updates_daily_activities()
       sleep(1)
       start_time = cur_datetime
       old_state = cur_state
   cur_capacity = read_capacity()
   if old_capacity != cur_capacity:
       mdb.update_battery_status(read_voltage(), cur_capacity)
       old_capacity = cur_capacity
   sleep(1)


UpdateDB.py

Librerie necessarie:

import MySQLdb
from datetime import datetime
from datetime import timedelta

Funzione per aggiungere un'attività alla tabella "today_time":

def insert_today_activity(state, start, end):
   db = MySQLdb.connect('localhost', 'phpmyadmin', 'BernardiniLab', 'labud19')
   cursor = db.cursor()
   sql = "INSERT INTO today_time SET activity ='%d', start ='%d-%d-%d %d:%d:%d', end='%d-%d-%d %d:%d:%d'" \
       %(state, start.year, start.month, start.day, start.hour, start.minute, start.second, end.year, end.month, end.day, end.hour, end.minute, end.second)
   cursor.execute(sql)
   db.commit()
   print "Data added to the database."
   db.close()
   
def check_last_date():
   db = MySQLdb.connect('localhost', 'phpmyadmin', 'BernardiniLab', 'labud19')
   cursor = db.cursor()
   sql = "SELECT start FROM today_time ORDER BY start DESC LIMIT 1"
   cursor.execute(sql)
   results = cursor.fetchall()
   db.commit()
   db.close()
   if len(results) > 0:
       return results[0][0]
   else:
       return datetime.now()

Funzione per estrarre ore, minuti e secondi dal formato timedelta del database:

def timedelta_to_hms(t):
   s = t.seconds % 60
   m = t.seconds // 60
   h = m // 60
   m = m % 60
   return (h,m,s)

Funzione per calcolare e inserire il riepilogo giornaliero nella tabella "daily_activities":

def updates_daily_activities():
   db = MySQLdb.connect('localhost', 'phpmyadmin', 'BernardiniLab', 'labud19')
   cursor = db.cursor()
   time=[]
   for n in range (1, 9):
       sql = "SELECT * FROM today_time WHERE activity ='%d'" %n
       cursor.execute(sql)
       results = cursor.fetchall()
       diff=timedelta(microseconds = 0)
       for row in results:
           start = row[1]
           end = row[2]
           diff += end - start
       time.append(timedelta_to_hms(diff))
       print "Activity=%s, Time=%s" %(n, time[n-1])
   sql = "SELECT start FROM today_time ORDER BY start DESC LIMIT 1"
   cursor.execute(sql)
   results = cursor.fetchall()
   i = results[0][0]
   sql = "INSERT INTO daily_activities SET data ='%d-%d-%d', \
           act1 ='%d:%d:%d', act2 ='%d:%d:%d', act3 ='%d:%d:%d', act4 ='%d:%d:%d', act5 ='%d:%d:%d', act6 ='%d:%d:%d', act7 ='%d:%d:%d', act8 ='%d:%d:%d' " \
           %(i.year,i.month,i.day, \
           time[0][0], time[0][1], time[0][2], \
           time[1][0], time[1][1], time[1][2], \
           time[2][0], time[2][1], time[2][2], \
           time[3][0], time[3][1], time[3][2], \
           time[4][0], time[4][1], time[4][2], \
           time[5][0], time[5][1], time[5][2], \
           time[6][0], time[6][1], time[6][2], \
           time[7][0], time[7][1], time[7][2])
   cursor.execute(sql)
   db.commit()
   print ("Update done.")
   sql = "DELETE FROM today_time"
   cursor.execute(sql)
   db.commit()
   print ("Reset done.")
   db.close()

Funzione per aggiornare lo stato della batteria nel database:

def update_battery_status(voltage, percentage):
   db = MySQLdb.connect('localhost', 'phpmyadmin', 'BernardiniLab', 'labud19')
   cursor = db.cursor()
   sql = "DELETE FROM battery_status"
   cursor.execute(sql)
   db.commit()
   sql = "INSERT INTO battery_status SET voltage ='%.2f', percentage ='%i'" \
       %(voltage, percentage)
   cursor.execute(sql)
   db.commit()
   print "Battery status updated to the database."
db.close()
Università degli studi di Udine
Dipartimento politecnico di ingegneria e architettura
Designed by Riccardo Deana & Pierluigi Fabbro
Torna ai contenuti | Torna al menu