forked from strawbot/TimbreTalk
/
serialio.py
128 lines (115 loc) · 3.25 KB
/
serialio.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# serial port object Rob Chapman Jan 26, 2011
# create a serial port object which can be opened to a serial port
# input and output are done through signals and slots
# a default rate can be set
# port can be opened and closed
from pyqtapi2 import *
import sys, traceback, serial, time
from message import warning, error, note, message
from signalcatch import initSignalCatcher
class serialPort(QThread):
# define signals
source = pyqtSignal(object)
ioError = pyqtSignal(object)
ioException = pyqtSignal(object)
closed = pyqtSignal()
opened = pyqtSignal()
stopbits = serial.STOPBITS_ONE
noparity, evenparity, oddparity = serial.PARITY_NONE, serial.PARITY_EVEN, serial.PARITY_ODD
parity = noparity
bytesize = serial.EIGHTBITS
def __init__(self, rate=9600):
QThread.__init__(self) # needed for signals to work!!
self.port = None
self.rate = self.default = rate
self.inputs = 0
self.outputs = 0
# initSignalCatcher()
# shutdown signal
def shutdown(self):
# note('shutting down serial port\n\r')
self.closePort()
self.quit()
def run(self): # perhaps open read and close are all in this thread
while self.port:
try:
c = self.port.read(1) # figure out why it doesn't block!!!
c += self.port.read(self.port.inWaiting()) # get rest of chars
self.inputs += len(c)
if c:
self.source.emit(c)
except IOError:
self.closePort()
note('Alert: device removed while open ')
except Exception, e:
self.closePort()
#error("run - serial port exception: %s" % e)
self.closed.emit()
def open(self, prefix, port, rate=None):
if self.isOpen():
error("Already opened!")
else:
if rate == None:
self.rate = self.default
else:
self.rate = rate
self.prefix = prefix
self.name = port
portname = prefix+port
try:
self.port = serial.Serial(portname,
rate,
timeout=.01, # time to accumulate characters: 10 ms @ 115200, thats up to 115.2 chars
parity=self.parity,
stopbits=self.stopbits,
xonxoff=0,
rtscts=0, # hw flow control
bytesize=self.bytesize)
note('opened %s at %d'%(port, rate))
self.start() # run serial in thread
self.opened.emit()
except Exception, e:
if self.port:
self.port.close()
self.port = None
# error('open port failed for '+prefix+port)
raise Exception('open port failed for '+prefix+port)
def closePort(self):
if self.isOpen():
port = self.port
self.port = None
try:
port.flush()
port.close()
except:
pass
note('closed %s'%self.name)
else:
self.port = None
def close(self):
self.ioError.disconnect()
self.ioException.disconnect()
self.closed.disconnect()
self.source.disconnect()
self.closePort()
self.wait(1000)
def sink(self, s):
if self.isOpen():
try:
self.port.write(s)
self.outputs += len(s)
except IOError:
self.ioError.emit('Alert: device closed while writing ')
except Exception, e:
if self.port:
self.ioException.emit("Error: sink - serial port exception: %s" % e)
def setRate(self, rate):
if self.rate != rate:
note('Baudrate changed to %d'%rate)
self.rate = rate
if self.isOpen():
self.port.baudrate = rate
def isOpen(self):
if self.port:
return self.port.isOpen()
return False