2 ## This file is part of the sigrok-meter project.
4 ## Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
5 ## Copyright (C) 2014 Jens Steinhauser <jens.steinhauser@gmail.com>
7 ## This program is free software; you can redistribute it and/or modify
8 ## it under the terms of the GNU General Public License as published by
9 ## the Free Software Foundation; either version 2 of the License, or
10 ## (at your option) any later version.
12 ## This program is distributed in the hope that it will be useful,
13 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ## GNU General Public License for more details.
17 ## You should have received a copy of the GNU General Public License
18 ## along with this program; if not, write to the Free Software
19 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 import sigrok.core as sr
25 QtCore = qtcompat.QtCore
26 QtGui = qtcompat.QtGui
28 class SamplingThread(QtCore.QObject):
29 '''A class that handles the reception of sigrok packets in the background.'''
31 class Worker(QtCore.QObject):
32 '''Helper class that does the actual work in another thread.'''
34 '''Signal emitted when new data arrived.'''
35 measured = QtCore.Signal(object, object, object)
37 '''Signal emmited in case of an error.'''
38 error = QtCore.Signal(str)
40 def __init__(self, context, drivers):
41 super(self.__class__, self).__init__()
43 self.context = context
44 self.drivers = drivers
49 def start_sampling(self):
51 for name, options in self.drivers:
53 dr = self.context.drivers[name]
54 devices.append(dr.scan(**options)[0])
57 'Unable to get device for driver "{}".'.format(name))
60 self.session = self.context.create_session()
62 self.session.add_device(dev)
64 self.session.add_datafeed_callback(self.callback)
69 # If sampling is 'True' here, it means that 'stop_sampling()' was
70 # not called, therefore 'session.run()' ended too early, indicating
73 self.error.emit('An error occured during the acquisition.')
75 def stop_sampling(self):
80 def callback(self, device, packet):
82 # In rare cases it can happen that the callback fires while
83 # the interpreter is shutting down. Then the sigrok module
84 # is already set to 'None'.
87 if packet.type != sr.PacketType.ANALOG:
90 if not len(packet.payload.channels):
93 # TODO: find a device with multiple channels in one packet
94 channel = packet.payload.channels[0]
96 # the most recent value
97 value = packet.payload.data[0][-1]
99 self.measured.emit(device, channel,
100 (value, packet.payload.unit, packet.payload.mq_flags))
102 # signal used to start the worker across threads
103 _start_signal = QtCore.Signal()
105 def __init__(self, context, drivers):
106 super(self.__class__, self).__init__()
108 self.worker = self.Worker(context, drivers)
109 self.thread = QtCore.QThread()
110 self.worker.moveToThread(self.thread)
112 self._start_signal.connect(self.worker.start_sampling)
114 # expose the signals of the worker
115 self.measured = self.worker.measured
116 self.error = self.worker.error
121 '''Starts sampling'''
122 self._start_signal.emit()
125 '''Stops sampling and the background thread.'''
126 self.worker.stop_sampling()