Skip to content
Snippets Groups Projects
Commit f8a39401 authored by Fanis Baikas's avatar Fanis Baikas
Browse files

README.md file and MCU_Current_Measurements folder added

parent 7e8e368f
No related branches found
No related tags found
No related merge requests found
No preview for this file type
File added
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
MCU_Current_Measurements/current_plots.png

107 KiB

MCU_Current_Measurements/current_plots_small.png

75.7 KiB

import csv
from dataclasses import dataclass
from matplotlib import pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
from numpy import trapz
def get_data_from_csv(filename):
data = []
with open(filename, 'r') as file:
reader = csv.reader(file)
for row in reader:
data.append(row)
# Remove first lines
data = data[22:len(data)]
measurements = []
for i in range(len(data)):
row = str(data[i])
row = row.split(';;')
measurement = row[0]
measurement = measurement[2:len(measurement)]
measurements.append(float(measurement))
return measurements
dnn_current_measurements = get_data_from_csv('DNN.CSV')
cnn_current_measurements = get_data_from_csv('CNN.CSV')
dnn_current_measurements = dnn_current_measurements[300:len(dnn_current_measurements)]
cnn_current_measurements = cnn_current_measurements[370:len(cnn_current_measurements)]
fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(15, 7))
t = np.arange(len(dnn_current_measurements)) / 200
ax[0].plot(t, dnn_current_measurements)
ax[0].set_title('DNN Keyword Spotting', weight='bold')
ax[0].set_xlabel('t (sec)')
ax[0].set_ylabel('MCU current (A)')
ax[0].set_xticks(range(0, 21, 1))
ax[0].set_xlim([0, 12.0])
ax[0].grid()
# Add shaded regions
a, b = 370 - 300, 790 - 300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[0].add_patch(poly)
ax[0].text(0.5 * (t[a] + t[b]), 0.01, "MCU Init \n + 2s delay",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 791 - 300, 1389 - 300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[0].add_patch(poly)
ax[0].text(0.5 * (t[a] + t[b]), 0.01, "Sleep (3s)",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 1390 - 300, 1500 - 300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[0].add_patch(poly)
ax[0].text(0.5 * (t[a] + t[b]), 0.01, "MFCC",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 1501 - 300, 2094 - 300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[0].add_patch(poly)
ax[0].text(0.5 * (t[a] + t[b]), 0.01, "Sleep (3s)",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 2095 - 300, 2115 - 300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[0].add_patch(poly)
ax[0].text(0.5 * (t[a] + t[b]), 0.01, "DNN",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 2116 - 300, 2699 - 300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[0].add_patch(poly)
t = np.arange(len(cnn_current_measurements)) / 200
ax[1].set_title('ds-CNN Keyword Spotting', weight='bold')
ax[1].plot(t, cnn_current_measurements)
ax[1].set_xlabel('t (sec)')
ax[1].set_ylabel('MCU current (A)')
ax[1].set_xticks(range(0, 21, 1))
ax[1].set_xlim([0, 12.0])
ax[1].grid()
# Add shaded regions
a, b = 360 - 300, 780 - 300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[1].add_patch(poly)
ax[1].text(0.5 * (t[a] + t[b]), 0.01, "MCU Init \n + 2s delay",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 781 - 300, 1376 - 300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[1].add_patch(poly)
ax[1].text(0.5 * (t[a] + t[b]), 0.01, "Sleep (3s)",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 1377 - 300, 1545 - 300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[1].add_patch(poly)
ax[1].text(0.5 * (t[a] + t[b]), 0.01, "MFCC",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 1546 - 300, 2144 - 300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[1].add_patch(poly)
ax[1].text(0.5 * (t[a] + t[b]), 0.01, "Sleep (3s)",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 2143 - 300, 2640 - 300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[1].add_patch(poly)
ax[1].text(0.5 * (t[a] + t[b]), 0.01, "ds-CNN",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 2640 - 300, len(t)-1
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[1].add_patch(poly)
voltage = 3.3
# DNN power calculations
# Compute the area under the MFCC curve
DNN_MFCC_curve = dnn_current_measurements[1390 - 300:1500 - 300]
DNN_MFCC_area = trapz(DNN_MFCC_curve, dx=1/200)
DNN_MFCC_energy = DNN_MFCC_area * voltage
print("DNN MFCC energy =", DNN_MFCC_energy)
DNN_classification_curve = dnn_current_measurements[2095 - 300:2115 - 300]
DNN_classification_area = trapz(DNN_classification_curve, dx=1/200)
DNN_classification_energy = DNN_classification_area * voltage
print("DNN classification energy =", DNN_classification_energy)
# CNN power calculations
CNN_MFCC_curve = cnn_current_measurements[1377 - 300:1545 - 300]
CNN_MFCC_area = trapz(CNN_MFCC_curve, dx=1/200)
CNN_MFCC_energy = CNN_MFCC_area * voltage
print("CNN MFCC energy = ", CNN_MFCC_energy)
CNN_classification_curve = cnn_current_measurements[2143 - 300:2640 - 300]
CNN_classification_area = trapz(CNN_classification_curve, dx=1/200)
CNN_classification_energy = CNN_classification_area * voltage
print("CNN classification energy =", CNN_classification_energy)
str_plot_DNN = "VDD_MCU = 3.3 V \n" + "MFCC energy: " + str(round(1000*DNN_MFCC_energy, 1)) + " mJ \n" + "Classification energy: " + str(round(1000*DNN_classification_energy, 1)) + " mJ"
str_plot_CNN = "VDD_MCU = 3.3 V \n" + "MFCC energy: " + str(round(1000*CNN_MFCC_energy, 1)) + " mJ \n" + "Classification energy: " + str(round(1000*CNN_classification_energy, 1)) + " mJ"
ax[0].text(9.5, 0.04, str_plot_DNN, bbox=dict(facecolor='yellow', alpha=0.5))
ax[1].text(9.5, 0.043, str_plot_CNN, bbox=dict(facecolor='yellow', alpha=0.5))
plt.tight_layout()
plt.savefig('current_plots.png')
plt.show()
\ No newline at end of file
import csv
from dataclasses import dataclass
from matplotlib import pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
from numpy import trapz
def get_data_from_csv(filename):
data = []
with open(filename, 'r') as file:
reader = csv.reader(file)
for row in reader:
data.append(row)
# Remove first lines
data = data[22:len(data)]
measurements = []
for i in range(len(data)):
row = str(data[i])
row = row.split(';;')
measurement = row[0]
measurement = measurement[2:len(measurement)]
measurements.append(float(measurement))
return measurements
dnn_current_measurements = get_data_from_csv('DNN.CSV')
cnn_current_measurements = get_data_from_csv('CNN.CSV')
dnn_current_measurements = dnn_current_measurements[1300:len(dnn_current_measurements)]
cnn_current_measurements = cnn_current_measurements[1370:len(cnn_current_measurements)]
fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(8, 5))
t = np.arange(len(dnn_current_measurements)) / 200
ax[0].plot(t, dnn_current_measurements)
ax[0].set_title('DNN Keyword Spotting', weight='bold')
ax[0].set_xlabel('t (sec)')
ax[0].set_ylabel('MCU current (A)')
ax[0].set_xticks(range(0, 21, 1))
ax[0].set_xlim([0, 7.0])
ax[0].grid()
a, b = 0, 1389 - 1300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[0].add_patch(poly)
a, b = 1390 - 1300, 1500 - 1300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[0].add_patch(poly)
ax[0].text(0.5 * (t[a] + t[b]), 0.022, "MFCC",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 1501 - 1300, 2094 - 1300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[0].add_patch(poly)
ax[0].text(0.5 * (t[a] + t[b]), 0.022, "Sleep (3s)",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 2095 - 1300, 2115 - 1300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[0].add_patch(poly)
ax[0].text(0.5 * (t[a] + t[b]), 0.022, "DNN",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 2116 - 1300, 2699 - 1300
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[0].add_patch(poly)
t = np.arange(len(cnn_current_measurements)) / 200
ax[1].set_title('ds-CNN Keyword Spotting', weight='bold')
ax[1].plot(t, cnn_current_measurements)
ax[1].set_xlabel('t (sec)')
ax[1].set_ylabel('MCU current (A)')
ax[1].set_xticks(range(0, 21, 1))
ax[1].set_xlim([0, 7.0])
ax[1].grid()
# Add shaded regions
a, b = 0, 1376 - 1300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[1].add_patch(poly)
a, b = 1377 - 1300, 1545 - 1300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[1].add_patch(poly)
ax[1].text(0.5 * (t[a] + t[b]), 0.022, "MFCC",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 1546 - 1300, 2144 - 1300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[1].add_patch(poly)
ax[1].text(0.5 * (t[a] + t[b]), 0.022, "Sleep (3s)",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 2143 - 1300, 2640 - 1300
ix = t[a:b]
iy = cnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax[1].add_patch(poly)
ax[1].text(0.5 * (t[a] + t[b]), 0.022, "ds-CNN",
horizontalalignment='center', fontsize=10, weight='bold')
a, b = 2640 - 1300, len(t)-1
ix = t[a:b]
iy = dnn_current_measurements[a:b]
verts = [(t[a], 0), *zip(ix, iy), (t[b], 0)]
poly = Polygon(verts, facecolor='0.65', edgecolor='0.5')
ax[1].add_patch(poly)
voltage = 3.3
# DNN power calculations
# Compute the area under the MFCC curve
DNN_MFCC_curve = dnn_current_measurements[1390 - 1300:1500 - 1300]
DNN_MFCC_area = trapz(DNN_MFCC_curve, dx=1/200)
DNN_MFCC_energy = DNN_MFCC_area * voltage
print("DNN MFCC energy =", DNN_MFCC_energy)
DNN_classification_curve = dnn_current_measurements[2095 - 1300:2115 - 1300]
DNN_classification_area = trapz(DNN_classification_curve, dx=1/200)
DNN_classification_energy = DNN_classification_area * voltage
print("DNN classification energy =", DNN_classification_energy)
# CNN power calculations
CNN_MFCC_curve = cnn_current_measurements[1377 - 1300:1545 - 1300]
CNN_MFCC_area = trapz(CNN_MFCC_curve, dx=1/200)
CNN_MFCC_energy = CNN_MFCC_area * voltage
print("CNN MFCC energy = ", CNN_MFCC_energy)
CNN_classification_curve = cnn_current_measurements[2143 - 1300:2640 - 1300]
CNN_classification_area = trapz(CNN_classification_curve, dx=1/200)
CNN_classification_energy = CNN_classification_area * voltage
print("CNN classification energy =", CNN_classification_energy)
str_plot_DNN = "VDD_MCU = 3.3 V \n" + "MFCC energy: " + str(round(1000*DNN_MFCC_energy, 1)) + " mJ \n" + "Classification energy: " + str(round(1000*DNN_classification_energy, 1)) + " mJ"
str_plot_CNN = "VDD_MCU = 3.3 V \n" + "MFCC energy: " + str(round(1000*CNN_MFCC_energy, 1)) + " mJ \n" + "Classification energy: " + str(round(1000*CNN_classification_energy, 1)) + " mJ"
ax[0].text(1.7, 0.03, str_plot_DNN, bbox=dict(facecolor='yellow', alpha=0.5))
ax[1].text(1.7, 0.03, str_plot_CNN, bbox=dict(facecolor='yellow', alpha=0.5))
plt.tight_layout()
plt.savefig('current_plots_small.png')
plt.show()
\ No newline at end of file
## Project description
The aim of this project was to monitor the energy required per inference from DNN and ds-CNN neural networks running on
an Arm Cortex M7 microcontroller to perform audio keyword recognition.
Folder F756ZG_KWS contains the source code and additional files used by STM32 CubeIDE. To distinguish between the MFCC
feature extraction and inference stages, the MCU is put in sleep mode for 3s intervals between MCU initialization,
MFCC and neural net classification.
The original implmentations of the neural netowrks can be found in:
https://github.com/ARM-software/ML-KWS-for-MCU/tree/master/Deployment
Current measurements were obtained from an STM32 Nulceo-F756ZG development board. To monitor the current supply to the
the MCU, solder bridge SB13 was removed and an ammeter was connected to jumper JP5 as described in the board's
reference manual (https://www.st.com/resource/en/user_manual/dm00244518-stm32-nucleo-144-boards-stmicroelectronics.pdf)
The .csv files containing the raw data from the current measurements can be found in the MCU_Current_Measurements
folder. The folder also contains the Python scrpits used for energy calculation and plot generation.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment