Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
Show encoder number, accel and rise time after key press
Browse files Browse the repository at this point in the history
  • Loading branch information
ijager committed Nov 5, 2019
1 parent dd5f0b2 commit 4489df7
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 104 deletions.
2 changes: 2 additions & 0 deletions app/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ verify_ssl = true
pyside2 = "*"
pyserial = "*"
matplotlib = "*"
numpy = "*"
pandas = "*"

[requires]
python_version = "3.7"
69 changes: 51 additions & 18 deletions app/Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions app/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@

class KeyPress:

def __init__(self, timestamps: list, positionData: list):
def __init__(self, encoder: int, timestamps: list, positionData: list):

self.encoder = encoder
record_threshold_min_mm = 1
complete_threshold_mm = 15
self.timestamps, i = np.unique(np.array(timestamps), return_index=True)
Expand Down Expand Up @@ -46,7 +47,9 @@ def metrics(self):

rise_time = self.t[-1] - self.t[0]

return rise_time, average_acceleration
force_N = (DOWNWEIGHTS_g[self.encoder - 1] * average_acceleration) / 1000

return rise_time, average_acceleration, force_N

def speed_data(self):
time_s = self.t / 1000
Expand Down
65 changes: 47 additions & 18 deletions app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,43 @@
from tools import set_background_color
from views import MainView

from comports import SerialConnection, SerialParser
from analysis import KeyPress

FPS = 20


class PianoApp(QtWidgets.QApplication):

def __init__(self):
super(PianoApp, self).__init__()

self.SerialConnection = SerialConnection()


self.window = MainWindow()
self.window.setWindowTitle("Piano Force Sensor")

self.window.show()
signal.signal(signal.SIGINT, self.window.quit)

self.toolbar = QtWidgets.QToolBar()
self.window.addToolBar(self.toolbar)
self.mainView = MainView(self.toolbar, self.SerialConnection.getDropdownWidget())
self.window.setCentralWidget(self.mainView)

self.mainView.refresh.connect(self.SerialConnection.refresh)

self.parser = SerialParser()
self.SerialConnection.textStream.connect(self.parser.parse_line)
self.SerialConnection.textStream.connect(self.mainView.textOutputView.addText)

# self.parser.newDataSet.connect
# self.parser.newDataSet.connect(estimateAcceleration)

self.parser.newDataSet.connect(lambda i, t, p: self.mainView.resultsView.new_results(KeyPress(i, t,p)))


class MainWindow(QtWidgets.QMainWindow):
"""
Class docstring
Expand All @@ -33,14 +68,16 @@ def __init__(self):

def _setupView(self):
"""Initialize Main Window"""
# self.setWindowIcon(QtGui.QIcon('assets/icon.png'))
self.setWindowIcon(QtGui.QIcon('assets/icon.jpeg'))
self.setGeometry(50, 50, 1600, 900)
set_background_color(self, 'white')
# set_background_color(self, '#5a5d73')
set_background_color(self, 'gray')

self._center()
self.raise_()
self.activateWindow()


def closeEvent(self, event):
"""Handle window close event"""
if event:
Expand All @@ -66,6 +103,13 @@ def _center(self):
frameGm.moveCenter(centerPoint)
self.move(frameGm.topLeft())

# qRect = self.frameGeometry()
# centerPoint = QtWidgets.QDesktopWidget().availableGeometry().center()
# qRect.moveCenter(centerPoint)
# self.move(qRect.topLeft())



def _update(self):
""" Gui Thread poll """
if not self._running:
Expand All @@ -75,22 +119,7 @@ def _update(self):
pass

if __name__ == "__main__":
app = QtWidgets.QApplication([])


window = MainWindow()

window.setWindowTitle("Piano Force Sensor")


window.show()
signal.signal(signal.SIGINT, window.quit)
# signal.signal(signal.SIGINT, signal.SIG_DFL)

toolbar = QtWidgets.QToolBar()
window.addToolBar(toolbar)
widget = MainView(toolbar)
window.setCentralWidget(widget)
app = PianoApp()

if sys.flags.interactive != 1:
sys.exit(app.exec_())
58 changes: 47 additions & 11 deletions app/comports.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,27 @@

codecs.register(lambda c: hexlify_codec.getregentry() if c == 'hexlify' else None)

class SerialManager(QtCore.QObject):
class SerialConnection(QtCore.QObject):


# newCOMPorts = QtCore.Signal(list)

textStream = QtCore.Signal(str)

def __init__(self):
super(SerialManager, self).__init__()
super(SerialConnection, self).__init__()

self.dropdown = QtWidgets.QComboBox()
self.dropdown.currentIndexChanged.connect(self.selectCOMPort)

self.availablePorts = None
self.refresh()

self.serial = None
self.alive = None
self._reader_alive = None
self.alive = False
self._reader_alive = False
self.receiver_thread = None

self.refresh()
# self.rx_decoder = codecs.getincrementaldecoder('UTF-8')('replace')
self.rx_decoder = codecs.getdecoder('UTF-8') #('replace')

Expand All @@ -39,15 +39,14 @@ def __init__(self):

@QtCore.Slot(str)
def selectCOMPort(self, index):
if index:
if index > 0:
port = self.availablePorts[index-1]
print('select', port)
self.change_port(port)
else:
self._stop_reader()
self.serial = None


def getDropdownWidget(self):
return self.dropdown

Expand All @@ -58,8 +57,6 @@ def refresh(self):
self.dropdown.addItems([p.device for p in self.availablePorts])
# self.newCOMPorts.emit([p.device for p in self.availablePorts])



def change_port(self, port: serial.Serial):

if port and self.serial and port != self.serial.port:
Expand All @@ -82,9 +79,11 @@ def _start_reader(self):
def _stop_reader(self):
"""Stop reader thread only, wait for clean exit of thread"""
self._reader_alive = False
if hasattr(self.serial, 'cancel_read'):
if self.serial and hasattr(self.serial, 'cancel_read'):
self.serial.cancel_read()
self.receiver_thread.join()

if self.receiver_thread:
self.receiver_thread.join()

def reader(self):
"""loop and copy serial->console"""
Expand All @@ -103,3 +102,40 @@ def reader(self):
self.alive = False
# self.console.cancel()
raise # XXX handle instead of re-raise?


START = 'Start Encoder'
END = 'End'

class SerialParser(QtCore.QObject):


newDataSet = QtCore.Signal(int, list, list)

def __init__(self):
super(SerialParser, self).__init__()
self.started = False
self.timestamps = []
self.positions = []
self.current_encoder = None

@QtCore.Slot(str)
def parse_line(self, line: str):

if line.startswith(END):
self.started = False
self.newDataSet.emit(self.current_encoder, self.timestamps, self.positions)

if line.startswith(START):
self.current_encoder = int(line[len(START):])
self.started = True
self.timestamps = []
self.positions = []
return

if self.started:
res = line.split(":")
self.timestamps.append(int(res[0]))
self.positions.append(int(res[1]))


Loading

0 comments on commit 4489df7

Please sign in to comment.