summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2018-11-02 10:49:02 +0100
committerDaniel Friesel <derf@finalrewind.org>2018-11-02 10:49:02 +0100
commit471b17b7abbd82854c9239a15148b0cae854a686 (patch)
tree67d36c6db912322b7ede6c406211d522d9ef3e07
parent90eeeaf798b267c42e50a1b7e9c98fe2e278dde4 (diff)
tabs -> spaces
-rwxr-xr-xbin/msp430-etv236
1 files changed, 127 insertions, 109 deletions
diff --git a/bin/msp430-etv b/bin/msp430-etv
index 5fe896f..810c7ce 100755
--- a/bin/msp430-etv
+++ b/bin/msp430-etv
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# vim:tabstop=4:softtabstop=4:shiftwidth=4:textwidth=160:smarttab:expandtab
import getopt
import matplotlib.pyplot as plt
@@ -11,22 +12,22 @@ import sys
opt = dict()
def measure_data(time):
- if not 'LD_LIBRARY_PATH' in os.environ:
- os.environ['LD_LIBRARY_PATH'] = '{}/var/projects/msp430/MSP430Flasher_1.3.7'.format(os.environ['HOME'])
+ if not 'LD_LIBRARY_PATH' in os.environ:
+ os.environ['LD_LIBRARY_PATH'] = '{}/var/projects/msp430/MSP430Flasher_1.3.7'.format(os.environ['HOME'])
- energytrace_cmd = '{}/var/source/energytrace-util/energytrace'.format(os.environ['HOME'])
+ energytrace_cmd = '{}/var/source/energytrace-util/energytrace'.format(os.environ['HOME'])
- res = subprocess.run([energytrace_cmd, str(duration)], stdout = subprocess.PIPE, universal_newlines = True)
+ res = subprocess.run([energytrace_cmd, str(duration)], stdout = subprocess.PIPE, universal_newlines = True)
- return res.stdout
+ return res.stdout
def show_help():
- print('''msp430-etv - MSP430 EnergyTrace Visualizer
+ print('''msp430-etv - MSP430 EnergyTrace Visualizer
USAGE
msp430-etv [--load <file> | <measurement duration>] [--save <file>]
- [--skip <count>] [--threshold <power>] [--plot] [--stat]
+ [--skip <count>] [--threshold <power>] [--plot] [--stat]
DESCRIPTION
@@ -44,111 +45,128 @@ OPTIONS
--skip <count>
Skip <count> data samples. This is useful to avoid startup code
influencing the results of a long-running measurement
+ --threshold <watts>|auto
+ Partition data into points with mean power >= <watts> and points with
+ mean power < <watts>, and print some statistics. higher power is handled
+ as peaks, whereas low-power measurements constitute the baseline.
+ If the threshold is set to "auto", the mean power of all measurements
+ will be used
--plot
Show power/time plot
--stat
Show mean voltage, current, and power as well as total energy consumption.
- ''')
+ ''')
if __name__ == '__main__':
- try:
- optspec = ('help load= save= skip= threshold= plot stat')
- raw_opts, args = getopt.getopt(sys.argv[1:], "", optspec.split(' '))
-
- for option, parameter in raw_opts:
- optname = re.sub(r'^--', '', option)
- opt[optname] = parameter
-
- if 'help' in opt:
- show_help()
- sys.exit(0)
-
- if not 'load' in opt:
- duration = int(args[0])
-
- if 'skip' in opt:
- opt['skip'] = int(opt['skip'])
- else:
- opt['skip'] = 0
-
- if 'threshold' in opt:
- opt['threshold'] = float(opt['threshold'])
-
- except getopt.GetoptError as err:
- print(err)
- sys.exit(2)
- except IndexError:
- print('Usage: msp430-etv <duration>')
- sys.exit(2)
- except ValueError:
- print('Error: duration or skip is not a number')
- sys.exit(2)
-
- if 'load' in opt:
- with open(opt['load'], 'r') as f:
- log_data = f.read()
- else:
- log_data = measure_data(duration)
-
- lines = log_data.split('\n')
- data_count = sum(map(lambda x: len(x) > 0 and x[0] != '#', lines))
- data_lines = filter(lambda x: len(x) > 0 and x[0] != '#', lines)
-
- data = np.empty((data_count - opt['skip'], 4))
-
- for i, line in enumerate(data_lines):
- if i >= opt['skip']:
- timestamp, current, voltage, total_energy = map(float, line.split(' '))
- data[i - opt['skip']] = [timestamp, current, voltage, total_energy]
-
- m_duration = data[-1, 0] - data[0, 0]
- m_energy = data[-1, 3] - data[0, 3]
- m_calc_energy = np.sum(data[1:, 1] * data[1:, 2] * (data[1:, 0] - data[:-1, 0]))
- m_energy_deviation = np.abs(m_energy - m_calc_energy) / np.max([m_energy, m_calc_energy])
-
- print('{:d} measurements in {:.2f} s = {:.0f} Hz sample rate'.format(
- data_count, m_duration, data_count / m_duration))
-
- print('Reported energy: E = {:f} J'.format(m_energy))
- print('Calculated energy: U*I*t = {:f} J'.format(m_calc_energy))
- print('Energy deviation: {:.1f}%'.format(m_energy_deviation * 100))
-
-
- if 'threshold' in opt:
- power = data[:, 1] * data[:, 2]
-
- peaks = []
- peak_start = -1
- for i, dp in enumerate(power):
- if dp >= opt['threshold'] and peak_start == -1:
- peak_start = i
- elif dp < opt['threshold'] and peak_start != -1:
- peaks.append((peak_start, i))
- peak_start = -1
-
- for peak in peaks:
- duration = data[peak[1]-1, 0] - data[peak[0], 0]
- print('{:.2f}ms peak ({:f} -> {:f})'.format(duration * 1000,
- data[peak[0], 0], data[peak[1]-1, 0]))
- print(' {:f} µJ / mean {:f} µW'.format(
- np.mean(power[peak[0] : peak[1]]) * duration * 1e6,
- np.mean(power[peak[0] : peak[1]]) * 1e6 ))
-
- if 'save' in opt:
- with open(opt['save'], 'w') as f:
- f.write(log_data)
-
- if 'stat' in opt:
- print('Mean voltage: {:f}'.format(np.mean(data[:, 2])))
- print('Mean current: {:f}'.format(np.mean(data[:, 1])))
- print('Mean power: {:f}'.format(np.mean(data[:, 1] * data[:, 2])))
- print('Total energy: {:f}'.format(m_energy))
-
- if 'plot' in opt:
- pwrhandle, = plt.plot(data[:, 0], data[:, 1] * data[:, 2], 'b-', label='U*I', markersize=1)
- #energyhandle, = plt.plot(data[1:, 0], (data[1:, 3] - data[:-1, 3]) / (data[1:, 0] - data[:-1, 0]), 'r-', label='E/Δt', markersize=1)
- plt.legend(handles=[pwrhandle])
- plt.xlabel('Time [s]')
- plt.ylabel('Power [W]')
- plt.grid(True)
- plt.show()
+ try:
+ optspec = ('help load= save= skip= threshold= plot stat')
+ raw_opts, args = getopt.getopt(sys.argv[1:], "", optspec.split(' '))
+
+ for option, parameter in raw_opts:
+ optname = re.sub(r'^--', '', option)
+ opt[optname] = parameter
+
+ if 'help' in opt:
+ show_help()
+ sys.exit(0)
+
+ if not 'load' in opt:
+ duration = int(args[0])
+
+ if 'skip' in opt:
+ opt['skip'] = int(opt['skip'])
+ else:
+ opt['skip'] = 0
+
+ if 'threshold' in opt and opt['threshold'] != 'auto':
+ opt['threshold'] = float(opt['threshold'])
+
+ except getopt.GetoptError as err:
+ print(err)
+ sys.exit(2)
+ except IndexError:
+ print('Usage: msp430-etv <duration>')
+ sys.exit(2)
+ except ValueError:
+ print('Error: duration or skip is not a number')
+ sys.exit(2)
+
+ if 'load' in opt:
+ with open(opt['load'], 'r') as f:
+ log_data = f.read()
+ else:
+ log_data = measure_data(duration)
+
+ lines = log_data.split('\n')
+ data_count = sum(map(lambda x: len(x) > 0 and x[0] != '#', lines))
+ data_lines = filter(lambda x: len(x) > 0 and x[0] != '#', lines)
+
+ data = np.empty((data_count - opt['skip'], 4))
+
+ for i, line in enumerate(data_lines):
+ if i >= opt['skip']:
+ timestamp, current, voltage, total_energy = map(float, line.split(' '))
+ data[i - opt['skip']] = [timestamp, current, voltage, total_energy]
+
+ m_duration = data[-1, 0] - data[0, 0]
+ m_energy = data[-1, 3] - data[0, 3]
+ m_calc_energy = np.sum(data[1:, 1] * data[1:, 2] * (data[1:, 0] - data[:-1, 0]))
+ m_energy_deviation = np.abs(m_energy - m_calc_energy) / np.max([m_energy, m_calc_energy])
+
+ print('{:d} measurements in {:.2f} s = {:.0f} Hz sample rate'.format(
+ data_count, m_duration, data_count / m_duration))
+
+ print('Reported energy: E = {:f} J'.format(m_energy))
+ print('Calculated energy: U*I*t = {:f} J'.format(m_calc_energy))
+ print('Energy deviation: {:.1f}%'.format(m_energy_deviation * 100))
+
+
+ if 'threshold' in opt:
+ power = data[:, 1] * data[:, 2]
+
+ if opt['threshold'] == 'auto':
+ opt['threshold'] = np.mean(power)
+ print('Threshold set to {:.0f} µW'.format(opt['threshold'] * 1e6))
+
+ if np.any(power < opt['threshold']):
+ print('Baseline mean: {:.0f} µW'.format(
+ np.mean(power[power < opt['threshold']]) * 1e6 ))
+ if np.any(power >= opt['threshold']):
+ print('Peak mean: {:.0f} µW'.format(
+ np.mean(power[power >= opt['threshold']]) * 1e6))
+
+ peaks = []
+ peak_start = -1
+ for i, dp in enumerate(power):
+ if dp >= opt['threshold'] and peak_start == -1:
+ peak_start = i
+ elif dp < opt['threshold'] and peak_start != -1:
+ peaks.append((peak_start, i))
+ peak_start = -1
+
+ for peak in peaks:
+ duration = data[peak[1]-1, 0] - data[peak[0], 0]
+ print('{:.2f}ms peak ({:f} -> {:f})'.format(duration * 1000,
+ data[peak[0], 0], data[peak[1]-1, 0]))
+ print(' {:f} µJ / mean {:f} µW'.format(
+ np.mean(power[peak[0] : peak[1]]) * duration * 1e6,
+ np.mean(power[peak[0] : peak[1]]) * 1e6 ))
+
+ if 'save' in opt:
+ with open(opt['save'], 'w') as f:
+ f.write(log_data)
+
+ if 'stat' in opt:
+ print('Mean voltage: {:f}'.format(np.mean(data[:, 2])))
+ print('Mean current: {:f}'.format(np.mean(data[:, 1])))
+ print('Mean power: {:f}'.format(np.mean(data[:, 1] * data[:, 2])))
+ print('Total energy: {:f}'.format(m_energy))
+
+ if 'plot' in opt:
+ pwrhandle, = plt.plot(data[:, 0], data[:, 1] * data[:, 2], 'b-', label='U*I', markersize=1)
+ #energyhandle, = plt.plot(data[1:, 0], (data[1:, 3] - data[:-1, 3]) / (data[1:, 0] - data[:-1, 0]), 'r-', label='E/Δt', markersize=1)
+ plt.legend(handles=[pwrhandle])
+ plt.xlabel('Time [s]')
+ plt.ylabel('Power [W]')
+ plt.grid(True)
+ plt.show()