Python Code - ST Tracker

Go to content

Main menu:

Python code:
Two python scripts have been created: Activity.py which acquires and stores accelerometer data and UpdateDB.py which contains the functions to access the Database.

Activity.py

Libraries:

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

I2C addresses and buses:

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

Accelerometer initialization:

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)

Functions for reading accelerometer data:

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

Functions for reading battery data:

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

Initialising accelerometer and necessary variables:
note: a 15 second sleep is required to avoid errors by running the script at system startup.

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

This cycle checks every second the accelerometer and battery parameters and, in case of variations, updates the database. At midnight or in case of changed date, the function that calculates the summary of the day is called.

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

Libraries:

import MySQLdb
from datetime import datetime
from datetime import timedelta

Function to add an activity to the "today_time" table:

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

Function to extract hours, minutes and seconds from the timedelta format of the database:

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

Function to calculate and insert daily summary in the "daily_activities" table:

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

Function to update battery status in the 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
Back to content | Back to main menu