class TcpS(QDialog, Ui_TcpServer):
    """
    Class documentation goes here.
    """

    sendFileName = pyqtSignal(str)

    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget
        @type QWidget
        """
        super(TcpS, self).__init__(parent)
        self.setupUi(self)
        self.payloadSize = 64 * 1024
        self.totalBytes = 0
        self.bytesWritten = 0
        self.bytesToWrite = 0
        self.theFileName = ""
        self.fileName = ""
        self.localFile = QFile()
        self.outBlock = QByteArray()
        self.time = QTime()
        self.initServer()

    def initServer(self):
        """
        网络设置初始化
        """
        self.tcpPort = 7788
        self.tcpServer = QTcpServer(self)
        self.clientConnection = QTcpSocket(self)
        self.tcpServer.newConnection.connect(self.sendMessage)
        self.serverStatuslabel.setText("请选择要传送的文件")
        self.progressBar.reset()
        self.serverOpenBtn.setEnabled(True)
        self.serverSendBtn.setEnabled(False)
        self.tcpServer.close()

    def refused(self):
        """
        对端拒绝接收文件
        """
        self.tcpServer.close()
        self.serverStatuslabel.setText("对方拒绝接收")

    def closeEvent(self, event):
        """
        关闭事件
        """
        self.on_serverCloseBtn_clicked()

    def sendMessage(self):
        """
        发送文件
        """
        self.serverSendBtn.setEnabled(False)
        self.clientConnection = self.tcpServer.nextPendingConnection()
        self.clientConnection.bytesWritten.connect(self.updateClientProgress)
        self.serverStatuslabel.setText("开始传送文件 {} !".format(self.theFileName))

        self.localFile = QFile(self.fileName)
        if not (self.localFile.open(QFile.ReadOnly)):
            errorMsg = "无法读取文件 {}:\n {}".format(self.fileName,
                                                self.localFile.errorString())
            QMessageBox.warning(self, "应用程序", errorMsg)
            return

        self.serverCloseBtn.setText("取消")

        self.totalBytes = self.localFile.size()  #单位:字节
        sendOut = QDataStream(self.outBlock, QIODevice.WriteOnly)
        sendOut.setVersion(QDataStream.Qt_5_4)
        self.time.start()
        currentFile = self.fileName.split("/")[-1]
        sendOut.writeInt64(0)
        sendOut.writeInt64(0)
        sendOut.writeQString(currentFile)
        self.totalBytes += self.outBlock.size()
        sendOut.device().seek(0)
        sendOut.writeInt64(self.totalBytes)
        sendOut.writeInt64(self.outBlock.size() - 2)
        self.bytesToWrite = self.totalBytes - self.clientConnection.write(
            self.outBlock)
        self.outBlock.resize(0)

    def updateClientProgress(self, numBytes):
        """
        发送进度显示
        """
        qApp.processEvents()
        self.bytesWritten += numBytes
        if self.bytesWritten > 0:
            self.block = self.localFile.read(
                min(self.bytesToWrite, self.payloadSize))
            self.bytesToWrite -= self.clientConnection.write(self.block)
        else:
            self.localFile.close()

        byteSent = self.bytesWritten / (1024 * 1024)
        useTime = self.time.elapsed() / 1000
        speed = self.bytesWritten / useTime / (1024 * 1024)
        total = self.totalBytes / (1024 * 1024)
        left = (total - byteSent) / speed

        if byteSent < 0.01:
            byteSent = self.bytesWritten / 1024
            speed = self.bytesWritten / useTime / 1024
            total = self.totalBytes / 1024
            if left > 0:
                sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format(
                    byteSent, speed, total, useTime, left)
            else:
                sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 用时:{3:.1f}秒\n".format(
                    byteSent, speed, total, useTime)
        else:
            if left > 0:
                sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format(
                    byteSent, speed, total, useTime, left)
            else:
                sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 用时:{3:.1f}秒\n".format(
                    byteSent, speed, total, useTime)

        self.progressBar.setMaximum(total)
        self.progressBar.setValue(byteSent)

        if self.bytesWritten == self.totalBytes:
            self.serverCloseBtn.setText("关闭")

        self.serverStatuslabel.setText(sendInfo)

    @pyqtSlot()
    def on_serverOpenBtn_clicked(self):
        """
        打开文件
        """
        self.fileName = QFileDialog.getOpenFileName(self, '打开文件', './')[0]
        if self.fileName:
            self.theFileName = self.fileName.split("/")[-1]
            self.serverStatuslabel.setText("要传送的文件为:{}".format(
                self.theFileName))
            self.serverSendBtn.setEnabled(True)
            self.serverOpenBtn.setEnabled(False)

    @pyqtSlot()
    def on_serverSendBtn_clicked(self):
        """
        发送文件
        """
        if not (self.tcpServer.listen(QHostAddress.Any, self.tcpPort)):
            errorMsg = self.tcpServer.errorString()
            QMessageBox.warning(self, "错误", "发送失败:\n {}".format(errorMsg))
            self.TcpServer.close()
            return

        self.serverStatuslabel.setText("等待对方接收... ...")
        self.serverSendBtn.setEnabled(False)
        self.sendFileName.emit(self.theFileName)

    @pyqtSlot()
    def on_serverCloseBtn_clicked(self):
        """
        取消或者关闭
        """
        if self.tcpServer.isListening():
            self.tcpServer.close()
            if self.localFile.isOpen():
                self.localFile.close()
            self.clientConnection.abort()

        if self.serverCloseBtn.text() == "取消":
            self.serverCloseBtn.setText("关闭")
        else:
            self.close()
            self.serverOpenBtn.setEnabled(True)
            self.serverSendBtn.setEnabled(False)
            self.progressBar.reset()
            self.totalBytes = 0
            self.bytesWritten = 0
            self.bytesToWrite = 0
            self.serverStatuslabel.setText("请选择要传送的文件")
class TcpC(QDialog, Ui_TcpClient):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget
        @type QWidget
        """
        super(TcpC, self).__init__(parent)
        self.setupUi(self)
        self.TotalBytes = 0
        self.bytesReceive = 0
        self.fileNameSize = 0
        self.bytesToReceive = 0
        self.fileName = ""
        self.tcpClient = QTcpSocket(self)
        self.tcpPort = 7788
        self.time = QTime()

        self.tcpClient.readyRead.connect(self.readMessage)
        self.tcpClient.error.connect(self.displayError)

    def setHostAddress(self, address):
        """
        设置服务器地址
        """
        self.hostAddress = address
        self.newConnect()

    def setFileName(self, file):
        """
        待接收文件的文件名
        """
        self.localFile = QFile(file)

    def closeEvent(self, event):
        """
        关闭事件
        """
        self.on_tcpClientCloseBtn_clicked()

    def newConnect(self):
        """
        连接服务器并开始计时
        """
        self.tcpClient.abort()
        self.tcpClient.connectToHost(self.hostAddress, self.tcpPort)
        self.time.start()

    def readMessage(self):
        """
        读取文件数据
        """
        receiver = QDataStream(self.tcpClient)
        receiver.setVersion(QDataStream.Qt_5_4)

        if self.bytesReceive <= 2:
            if self.tcpClient.bytesAvailable() >= 2 and self.fileNameSize == 0:
                self.TotalBytes = receiver.readInt64()
                self.fileNameSize = receiver.readInt64()
                self.bytesReceive += 2

            if self.tcpClient.bytesAvailable() >= self.fileNameSize and self.fileNameSize != 0:
                self.fileName = receiver.readQString()
                self.bytesReceive += self.fileNameSize
                if not(self.localFile.open(QFile.WriteOnly)):
                    QMessageBox.warning(self, "应用程序", "无法读取文件 {}:\n {}".format(self.fileName, self.localFile.errorString()))
                    return
            else:
                return

        if self.bytesReceive < self.TotalBytes:
            self.bytesReceive += self.tcpClient.bytesAvailable()
            inBlock = self.tcpClient.readAll()
            self.localFile.write(inBlock)
            inBlock.resize(0)

        useTime = self.time.elapsed() / 1000
        
        bytesReceived = self.bytesReceive / (1024*1024)
        speed = bytesReceived / useTime
        total = self.TotalBytes / (1024*1024)
        left = (total - bytesReceived) / speed

        if bytesReceived < 0.01:
            bytesReceived = self.bytesReceive / 1024
            speed = bytesReceived / useTime / 1024
            total = self.TotalBytes / 1024
            if left > 0:
                msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left)
            else:
                msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime)

        else:
            if left > 0:
                msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left)
            else:
                msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime)

        self.progressBar.setMaximum(total)
        self.progressBar.setValue(bytesReceived)

        self.tcpClientStatuslabel.setText(msg)
        
        if self.bytesReceive == self.TotalBytes:
            self.localFile.close()
            self.tcpClient.close()
            self.tcpClientStatuslabel.setText("接收文件{}完毕".format(self.fileName))
            self.tcpClientBtn.setEnabled(False)


    def displayError(self, socketError):
        """
        显示错误
        """
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        else:
            errorMsg = self.tcpClient.errorString()
            QMessageBox.warning(self, "应用程序", errorMsg)
            return

    @pyqtSlot()
    def on_tcpClientBtn_clicked(self):
        """
        取消接收
        """
        self.tcpClient.abort()
        if self.localFile.isOpen():
            self.localFile.close()
        
        self.tcpClientBtn.setEnabled(False)
    
    @pyqtSlot()
    def on_tcpClientCloseBtn_clicked(self):
        """
        关闭
        """
        self.tcpClient.abort()
        if self.localFile.isOpen():
            self.localFile.close()
        self.close()
        self.tcpClientBtn.setEnabled(True)
class MainWindow(QMainWindow):

    WaitingAnimation = [' |', ' /', ' -', ' \\']
    WaitingAnimationFrameDurationMs = 100
    ConnectionTimerTimeoutMs = 5000
    DataExchangeTimerTimeoutMs = 250

    def __init__(self):
        super().__init__()
        self.targetAddr = '0.0.0.0'
        self.targetPort = 0
        QSettings.setPath(QSettings.IniFormat, QSettings.UserScope,
                          QDir.currentPath())
        self.settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                                  'config')
        self.readSettings()

        self.connectionSettings = ConnectionSettings(self.targetAddr,
                                                     self.targetPort, self)
        self.connectionSettings.settingsChanged.connect(
            self.onConnectionSettingsSettingsChanged)
        self.socket = QTcpSocket(self)
        self.socket.stateChanged.connect(self.onSocketStateChanged)
        self.socket.readyRead.connect(self.onSocketReadyRead)
        self.frameLength = 0
        self.lastSocketState = QAbstractSocket.UnconnectedState
        self.animationTimer = QTimer(self)
        self.animationTimer.timeout.connect(self.onAnimationTimerTimeout)
        self.animationCounter = 0
        self.connectionTimer = QTimer(self)
        self.connectionTimer.setSingleShot(True)
        self.connectionTimer.timeout.connect(self.onConnectionTimerTimeout)
        self.dataExchangeTimer = QTimer(self)
        self.dataExchangeTimer.timeout.connect(self.onDataExchangeTimerTimeout)

        self.initUI()
        self.onConnectionSettingsSettingsChanged(self.targetAddr,
                                                 self.targetPort)
        self.onSocketStateChanged()

    #     self.cap = cv2.VideoCapture(0)
    #     self.dispTimer = QTimer(self)
    #     self.dispTimer.timeout.connect(self.onDispTimerTimeout)
    #     self.dispTimer.start(100)

    # @pyqtSlot()
    # def onDispTimerTimeout(self):
    #     ret, frame = self.cap.read()
    #     image = self.cvToQtIm(frame)
    #     pixmap = QPixmap.fromImage(image)
    #     self.streamDisp.setPixmap(pixmap)

    def initUI(self):
        self.setGeometry(300, 300, 300, 300)
        self.setWindowTitle('Diag Tool')

        statusBar = QStatusBar(self)
        self.targetInfo = QLabel(self)
        self.connectionStatus = QLabel(self)
        statusBar.addWidget(self.targetInfo, 0)
        statusBar.addWidget(self.connectionStatus, 1)
        self.setStatusBar(statusBar)

        self.streamDisp = QLabel(self)
        self.streamDisp.setSizePolicy(QSizePolicy.MinimumExpanding,
                                      QSizePolicy.MinimumExpanding)

        layout = QGridLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.streamDisp, 0, 0, 0, 4)
        self.setCentralWidget(QWidget(self))
        self.centralWidget().setLayout(layout)

        self.menuTarget = self.menuBar().addMenu('Target')
        self.menuTargetConnect = QAction('Connect', self)
        self.menuTargetConnect.triggered.connect(self.onMenuTargetConnect)
        self.menuTargetSettings = QAction('Settings', self)
        self.menuTargetSettings.triggered.connect(self.onMenuTargetSettings)
        self.menuTarget.addAction(self.menuTargetConnect)
        self.menuTarget.addAction(self.menuTargetSettings)

    def closeEvent(self, event):
        self.writeSettings()

    def cvToQtIm(self, cvIm):
        cvIm = cv2.cvtColor(cvIm, cv2.COLOR_BGR2RGB)
        return QImage(cvIm.data, cvIm.shape[1], cvIm.shape[0],
                      QImage.Format_RGB888)

    def readSettings(self):
        value = self.settings.value('target/addr')
        if value: self.targetAddr = str(value)
        value = self.settings.value('target/port')
        if value: self.targetPort = int(value)

    def writeSettings(self):
        self.settings.setValue('target/addr', self.targetAddr)
        self.settings.setValue('target/port', self.targetPort)

    @pyqtSlot()
    def onMenuTargetConnect(self):
        if QAbstractSocket.UnconnectedState == self.socket.state():
            self.menuTargetConnect.setEnabled(False)
            self.connectionSettings.setUserInputEnabled(False)
            self.socket.connectToHost(QHostAddress(self.targetAddr),
                                      self.targetPort)
            self.connectionTimer.start(self.ConnectionTimerTimeoutMs)
        elif QAbstractSocket.ConnectedState == self.socket.state():
            self.menuTargetConnect.setEnabled(False)
            self.socket.disconnectFromHost()

    @pyqtSlot()
    def onMenuTargetSettings(self):
        self.connectionSettings.show()

    @pyqtSlot()
    def onSocketStateChanged(self):
        #print(self.socket.state())
        if QAbstractSocket.UnconnectedState == self.socket.state():
            self.dataExchangeTimer.timeout.emit()
            self.dataExchangeTimer.start(self.DataExchangeTimerTimeoutMs)
            self.animationTimer.stop()
            self.menuTargetConnect.setText('Connect')
            self.menuTargetConnect.setEnabled(True)
            self.connectionStatus.setText('Offline')
            self.connectionSettings.setUserInputEnabled(True)
            if QAbstractSocket.ConnectingState == self.lastSocketState:
                QMessageBox.warning(self, 'Warning', 'Unable to connect!')
        elif QAbstractSocket.ConnectedState == self.socket.state():
            self.connectionTimer.stop()
            self.animationTimer.stop()
            self.dataExchangeTimer.start()
            self.menuTargetConnect.setText('Disconnect')
            self.menuTargetConnect.setEnabled(True)
            self.connectionStatus.setText('Online')
        elif QAbstractSocket.ConnectingState == self.socket.state():
            self.connectionStatus.setText('Connecting')
            self.animationCounter = 0
            self.animationTimer.start(self.WaitingAnimationFrameDurationMs)
        elif QAbstractSocket.ClosingState == self.socket.state():
            self.connectionStatus.setText('Disconnecting')
            self.animationCounter = 0
            self.animationTimer.start(self.WaitingAnimationFrameDurationMs)
        self.lastSocketState = self.socket.state()

    @pyqtSlot()
    def onSocketReadyRead(self):
        if 0 == self.frameLength:
            if self.socket.canReadLine():
                data = self.socket.readLine()[:-1]
                self.frameLength = int(data)

        if self.frameLength != 0:
            if self.socket.bytesAvailable() >= self.frameLength:
                data = self.socket.read(self.frameLength)
                arr = np.frombuffer(data, dtype=np.uint8)
                cvIm = cv2.imdecode(arr, cv2.IMREAD_COLOR)
                self.frameLength = 0
                image = self.cvToQtIm(cvIm)
                pixmap = QPixmap.fromImage(image)
                self.streamDisp.setPixmap(pixmap)

    @pyqtSlot(str, int)
    def onConnectionSettingsSettingsChanged(self, addr, port):
        self.targetInfo.setText('Target (' + addr + ':' + str(port) + ')')
        self.targetAddr = addr
        self.targetPort = port

    @pyqtSlot()
    def onAnimationTimerTimeout(self):
        if QAbstractSocket.ConnectingState == self.socket.state():
            text = 'Connecting'
        else:
            text = 'Disconnecting'

        text += self.WaitingAnimation[self.animationCounter]
        self.animationCounter = (self.animationCounter + 1) % len(
            self.WaitingAnimation)
        self.connectionStatus.setText(text)

    @pyqtSlot()
    def onConnectionTimerTimeout(self):
        self.socket.abort()

    @pyqtSlot()
    def onDataExchangeTimerTimeout(self):
        if QAbstractSocket.ConnectedState == self.socket.state():
            self.socket.writeData('get\n'.encode())
Exemple #4
0
class VNA(QMainWindow, Ui_VNA):

  max_size = 16383

  formatter = matplotlib.ticker.FuncFormatter(lambda x, pos: '%1.1fM' % (x * 1e-6) if abs(x) >= 1e6 else '%1.1fk' % (x * 1e-3) if abs(x) >= 1e3 else '%1.1f' % x if abs(x) >= 1e0 else '%1.1fm' % (x * 1e+3) if abs(x) >= 1e-3 else '%1.1fu' % (x * 1e+6) if abs(x) >= 1e-6 else '%1.1f' % x)

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variable
    self.idle = True
    # sweep parameters
    self.sweep_start = 100
    self.sweep_stop = 60000
    self.sweep_size = 600
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(32 * VNA.max_size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    self.adc1 = np.zeros(VNA.max_size, np.complex64)
    self.adc2 = np.zeros(VNA.max_size, np.complex64)
    self.dac1 = np.zeros(VNA.max_size, np.complex64)
    self.open = np.zeros(VNA.max_size, np.complex64)
    self.short = np.zeros(VNA.max_size, np.complex64)
    self.load = np.zeros(VNA.max_size, np.complex64)
    self.dut = np.zeros(VNA.max_size, np.complex64)
    self.mode = 'dut'
    # create figure
    self.figure = Figure()
    self.figure.set_facecolor('none')
    self.canvas = FigureCanvas(self.figure)
    self.plotLayout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # remove subplots action
    actions = self.toolbar.actions()
    self.toolbar.removeAction(actions[7])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.sweepFrame.setEnabled(False)
    self.dutSweep.setEnabled(False)
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(self.sweep_open)
    self.shortSweep.clicked.connect(self.sweep_short)
    self.loadSweep.clicked.connect(self.sweep_load)
    self.dutSweep.clicked.connect(self.sweep_dut)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.openPlot.clicked.connect(self.plot_open)
    self.shortPlot.clicked.connect(self.plot_short)
    self.loadPlot.clicked.connect(self.plot_load)
    self.dutPlot.clicked.connect(self.plot_dut)
    self.smithPlot.clicked.connect(self.plot_smith)
    self.impPlot.clicked.connect(self.plot_imp)
    self.rcPlot.clicked.connect(self.plot_rc)
    self.swrPlot.clicked.connect(self.plot_swr)
    self.rlPlot.clicked.connect(self.plot_rl)
    # create timer
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.socket.abort()
    self.offset = 0
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(True)
    self.dutSweep.setEnabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_start(self.startValue.value())
    self.set_stop(self.stopValue.value())
    self.set_size(self.sizeValue.value())
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(True)
    self.dutSweep.setEnabled(True)

  def read_data(self):
    size = self.socket.bytesAvailable()
    if self.offset + size < 32 * self.sweep_size:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.buffer[self.offset:32 * self.sweep_size] = self.socket.read(32 * self.sweep_size - self.offset)
      self.offset = 0
      self.adc1 = self.data[0::4]
      self.adc2 = self.data[1::4]
      self.dac1 = self.data[2::4]
      getattr(self, self.mode)[0:self.sweep_size] = self.adc1[0:self.sweep_size] / self.dac1[0:self.sweep_size]
      self.sweepFrame.setEnabled(True)
      self.selectFrame.setEnabled(True)
      getattr(self, 'plot_%s' % self.mode)()

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000)))

  def set_stop(self, value):
    self.sweep_stop = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000)))

  def set_size(self, value):
    self.sweep_size = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(value)))

  def sweep(self):
    if self.idle: return
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(False)
    self.socket.write(struct.pack('<I', 3<<28))

  def sweep_open(self):
    self.mode = 'open'
    self.sweep()

  def sweep_short(self):
    self.mode = 'short'
    self.sweep()

  def sweep_load(self):
    self.mode = 'load'
    self.sweep()

  def sweep_dut(self):
    self.mode = 'dut'
    self.sweep()

  def impedance(self):
    return 50.0 * (self.open[0:self.sweep_size] - self.load[0:self.sweep_size]) * (self.dut[0:self.sweep_size] - self.short[0:self.sweep_size]) / ((self.load[0:self.sweep_size] - self.short[0:self.sweep_size]) * (self.open[0:self.sweep_size] - self.dut[0:self.sweep_size]))

  def gamma(self):
    z = self.impedance()
    return (z - 50.0)/(z + 50.0)

  def plot_magphase(self, data):
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(top = 0.98, right = 0.88)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(VNA.formatter)
    axes1.yaxis.set_major_formatter(VNA.formatter)
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    axes1.plot(self.xaxis, np.absolute(data), color = 'blue')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Magnitude')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red')
    self.canvas.draw()

  def plot_open(self):
    self.plot_magphase(self.open[0:self.sweep_size])

  def plot_short(self):
    self.plot_magphase(self.short[0:self.sweep_size])

  def plot_load(self):
    self.plot_magphase(self.load[0:self.sweep_size])

  def plot_dut(self):
    self.plot_magphase(self.dut[0:self.sweep_size])

  def plot_smith(self):
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(top = 0.90, right = 0.90)
    axes = self.figure.add_subplot(111, projection = 'smith', axes_radius = 0.55, axes_scale = 50.0)
    axes.cla()
    axes.plot(self.impedance())
    self.canvas.draw()

  def plot_imp(self):
    self.plot_magphase(self.impedance())

  def plot_rc(self):
    self.plot_magphase(self.gamma())

  def plot_swr(self):
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(top = 0.98, right = 0.88)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(VNA.formatter)
    axes1.yaxis.set_major_formatter(VNA.formatter)
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('SWR')
    magnitude = np.absolute(self.gamma())
    swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude)))
    axes1.plot(self.xaxis, swr, color = 'blue')
    self.canvas.draw()

  def plot_rl(self):
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(top = 0.98, right = 0.88)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(VNA.formatter)
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Return loss, dB')
    magnitude = np.absolute(self.gamma())
    axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue')
    self.canvas.draw()

  def write_cfg(self):
    name = QFileDialog.getSaveFileName(self, 'Write configuration settings', '.', '*.ini')
    settings = QSettings(name[0], QSettings.IniFormat)
    self.write_cfg_settings(settings)

  def read_cfg(self):
    name = QFileDialog.getOpenFileName(self, 'Read configuration settings', '.', '*.ini')
    settings = QSettings(name[0], QSettings.IniFormat)
    self.read_cfg_settings(settings)

  def write_cfg_settings(self, settings):
    settings.setValue('start', self.startValue.value())
    settings.setValue('stop', self.stopValue.value())
    size = self.sizeValue.value()
    settings.setValue('size', size)
    for i in range(0, size):
      settings.setValue('open_real_%d' % i, float(self.open.real[i]))
      settings.setValue('open_imag_%d' % i, float(self.open.imag[i]))
    for i in range(0, size):
      settings.setValue('short_real_%d' % i, float(self.short.real[i]))
      settings.setValue('short_imag_%d' % i, float(self.short.imag[i]))
    for i in range(0, size):
      settings.setValue('load_real_%d' % i, float(self.load.real[i]))
      settings.setValue('load_imag_%d' % i, float(self.load.imag[i]))
    for i in range(0, size):
      settings.setValue('dut_real_%d' % i, float(self.dut.real[i]))
      settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i]))

  def read_cfg_settings(self, settings):
    self.startValue.setValue(settings.value('start', 100, type = int))
    self.stopValue.setValue(settings.value('stop', 60000, type = int))
    size = settings.value('size', 600, type = int)
    self.sizeValue.setValue(size)
    for i in range(0, size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut[i] = real + 1.0j * imag

  def write_s1p(self):
    name = QFileDialog.getSaveFileName(self, 'Write s1p file', '.', '*.s1p')
    fh = open(name[0], 'w')
    gamma = self.gamma()
    size = self.sizeValue.value()
    fh.write('# GHz S MA R 50\n')
    for i in range(0, size):
      fh.write('0.0%.8d   %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
    fh.close()
Exemple #5
0
class VNA(QMainWindow, Ui_VNA):

  max_size = 16384

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variables
    self.idle = True
    self.reading = False
    # sweep parameters
    self.sweep_start = 100
    self.sweep_stop = 60000
    self.sweep_size = 600
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(24 * VNA.max_size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    self.adc1 = np.zeros(VNA.max_size, np.complex64)
    self.adc2 = np.zeros(VNA.max_size, np.complex64)
    self.dac1 = np.zeros(VNA.max_size, np.complex64)
    self.open = np.zeros(VNA.max_size, np.complex64)
    self.short = np.zeros(VNA.max_size, np.complex64)
    self.load = np.zeros(VNA.max_size, np.complex64)
    self.dut = np.zeros(VNA.max_size, np.complex64)
    self.mode = 'dut'
    # create figure
    self.figure = Figure()
    self.figure.set_facecolor('none')
    self.canvas = FigureCanvas(self.figure)
    self.plotLayout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # initialize cursor
    self.cursor = None
    # remove subplots action
    actions = self.toolbar.actions()
    self.toolbar.removeAction(actions[7])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.sweepFrame.setEnabled(False)
    self.dutSweep.setEnabled(False)
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(self.sweep_open)
    self.shortSweep.clicked.connect(self.sweep_short)
    self.loadSweep.clicked.connect(self.sweep_load)
    self.dutSweep.clicked.connect(self.sweep_dut)
    self.csvButton.clicked.connect(self.write_csv)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.s2pButton.clicked.connect(self.write_s2p)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.rateValue.addItems(['500', '100', '50', '10', '5', '1'])
    self.rateValue.lineEdit().setReadOnly(True)
    self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
    for i in range(0, self.rateValue.count()):
      self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    self.corrValue.valueChanged.connect(self.set_corr)
    self.levelValue.valueChanged.connect(self.set_level)
    self.openPlot.clicked.connect(self.plot_open)
    self.shortPlot.clicked.connect(self.plot_short)
    self.loadPlot.clicked.connect(self.plot_load)
    self.dutPlot.clicked.connect(self.plot_dut)
    self.smithPlot.clicked.connect(self.plot_smith)
    self.impPlot.clicked.connect(self.plot_imp)
    self.rcPlot.clicked.connect(self.plot_rc)
    self.swrPlot.clicked.connect(self.plot_swr)
    self.rlPlot.clicked.connect(self.plot_rl)
    self.gainPlot.clicked.connect(self.plot_gain)
    # create timer
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.socket.abort()
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(True)
    self.dutSweep.setEnabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_start(self.startValue.value())
    self.set_stop(self.stopValue.value())
    self.set_size(self.sizeValue.value())
    self.set_rate(self.rateValue.currentIndex())
    self.set_corr(self.corrValue.value())
    self.set_level(self.levelValue.value())
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(True)
    self.dutSweep.setEnabled(True)

  def read_data(self):
    if not self.reading:
      self.socket.readAll()
      return
    size = self.socket.bytesAvailable()
    self.progress.setValue((self.offset + size) / 24)
    limit = 24 * (self.sweep_size + 1)
    if self.offset + size < limit:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.buffer[self.offset:limit] = self.socket.read(limit - self.offset)
      self.adc1 = self.data[0::3]
      self.adc2 = self.data[1::3]
      self.dac1 = self.data[2::3]
      getattr(self, self.mode)[0:self.sweep_size] = self.adc1[1:self.sweep_size + 1] / self.dac1[1:self.sweep_size + 1]
      getattr(self, 'plot_%s' % self.mode)()
      self.reading = False
      self.sweepFrame.setEnabled(True)
      self.selectFrame.setEnabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000)))

  def set_stop(self, value):
    self.sweep_stop = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000)))

  def set_size(self, value):
    self.sweep_size = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(value)))

  def set_rate(self, value):
    if self.idle: return
    rate = [1, 5, 10, 50, 100, 500][value]
    self.socket.write(struct.pack('<I', 3<<28 | int(rate)))

  def set_corr(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value)))

  def set_level(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(32767 * np.power(10.0, value / 20.0))))

  def sweep(self):
    if self.idle: return
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(False)
    self.socket.write(struct.pack('<I', 6<<28))
    self.offset = 0
    self.reading = True
    self.progress = QProgressDialog('Sweep status', 'Cancel', 0, self.sweep_size + 1)
    self.progress.setModal(True)
    self.progress.setMinimumDuration(1000)
    self.progress.canceled.connect(self.cancel)

  def cancel(self):
    self.offset = 0
    self.reading = False
    self.socket.write(struct.pack('<I', 7<<28))
    self.sweepFrame.setEnabled(True)
    self.selectFrame.setEnabled(True)

  def sweep_open(self):
    self.mode = 'open'
    self.sweep()

  def sweep_short(self):
    self.mode = 'short'
    self.sweep()

  def sweep_load(self):
    self.mode = 'load'
    self.sweep()

  def sweep_dut(self):
    self.mode = 'dut'
    self.sweep()

  def gain(self):
    size = self.sweep_size
    return self.dut[0:size]/self.short[0:size]

  def impedance(self):
    size = self.sweep_size
    return 50.0 * (self.open[0:size] - self.load[0:size]) * (self.dut[0:size] - self.short[0:size]) / ((self.load[0:size] - self.short[0:size]) * (self.open[0:size] - self.dut[0:size]))

  def gamma(self):
    z = self.impedance()
    return (z - 50.0)/(z + 50.0)

  def plot_gain(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    gain = self.gain()
    axes1.plot(self.xaxis, 20.0 * np.log10(np.absolute(gain)), color = 'blue', label = 'Gain')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Gain, dB')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(gain, deg = True), color = 'red', label = 'Phase angle')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_magphase(self, data):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    axes1.plot(self.xaxis, np.absolute(data), color = 'blue', label = 'Magnitude')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Magnitude')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red', label = 'Phase angle')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_open(self):
    self.plot_magphase(self.open[0:self.sweep_size])

  def plot_short(self):
    self.plot_magphase(self.short[0:self.sweep_size])

  def plot_load(self):
    self.plot_magphase(self.load[0:self.sweep_size])

  def plot_dut(self):
    self.plot_magphase(self.dut[0:self.sweep_size])

  def plot_smith_grid(self, axes, color):
    load = 50.0
    ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0])
    for tick in ticks * load:
      axis = np.logspace(-4, np.log10(1.0e3), 200) * load
      z = tick + 1.0j * axis
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      z = axis + 1.0j * tick
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      if tick == 0.0:
        axes.text(1.0, 0.0, u'\u221E', color = color, ha = 'left', va = 'center', clip_on = True, fontsize = 18.0)
        axes.text(-1.0, 0.0, u'0\u03A9', color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0)
        continue
      lab = u'%d\u03A9' % tick
      x = (tick - load) / (tick + load)
      axes.text(x, 0.0, lab, color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0)
      lab = u'j%d\u03A9' % tick
      z =  1.0j * tick
      gamma = (z - load)/(z + load) * 1.05
      x = gamma.real
      y = gamma.imag
      angle = np.angle(gamma) * 180.0 / np.pi - 90.0
      axes.text(x, y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = angle, fontsize = 12.0)
      lab = u'-j%d\u03A9' % tick
      axes.text(x, -y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = -angle, fontsize = 12.0)

  def plot_smith(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.0, bottom = 0.0, right = 1.0, top = 1.0)
    axes1 = self.figure.add_subplot(111)
    self.plot_smith_grid(axes1, 'blue')
    gamma = self.gamma()
    plot, = axes1.plot(gamma.real, gamma.imag, color = 'red')
    axes1.axis('equal')
    axes1.set_xlim(-1.12, 1.12)
    axes1.set_ylim(-1.12, 1.12)
    axes1.xaxis.set_visible(False)
    axes1.yaxis.set_visible(False)
    for loc, spine in axes1.spines.items():
      spine.set_visible(False)
    self.cursor = datacursor(plot, formatter = SmithFormatter(self.xaxis), display = 'multiple')
    self.canvas.draw()

  def plot_imp(self):
    self.plot_magphase(self.impedance())

  def plot_rc(self):
    self.plot_magphase(self.gamma())

  def plot_swr(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('SWR')
    magnitude = np.absolute(self.gamma())
    swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude)))
    axes1.plot(self.xaxis, swr, color = 'blue', label = 'SWR')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_rl(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Return loss, dB')
    magnitude = np.absolute(self.gamma())
    axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue', label = 'Return loss')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def write_cfg(self):
    dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.write_cfg_settings(settings)

  def read_cfg(self):
    dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.read_cfg_settings(settings)

  def write_cfg_settings(self, settings):
    settings.setValue('addr', self.addrValue.text())
    settings.setValue('start', self.startValue.value())
    settings.setValue('stop', self.stopValue.value())
    settings.setValue('rate', self.rateValue.currentIndex())
    settings.setValue('corr', self.corrValue.value())
    size = self.sizeValue.value()
    settings.setValue('size', size)
    for i in range(0, size):
      settings.setValue('open_real_%d' % i, float(self.open.real[i]))
      settings.setValue('open_imag_%d' % i, float(self.open.imag[i]))
    for i in range(0, size):
      settings.setValue('short_real_%d' % i, float(self.short.real[i]))
      settings.setValue('short_imag_%d' % i, float(self.short.imag[i]))
    for i in range(0, size):
      settings.setValue('load_real_%d' % i, float(self.load.real[i]))
      settings.setValue('load_imag_%d' % i, float(self.load.imag[i]))
    for i in range(0, size):
      settings.setValue('dut_real_%d' % i, float(self.dut.real[i]))
      settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i]))

  def read_cfg_settings(self, settings):
    self.addrValue.setText(settings.value('addr', '192.168.1.100'))
    self.startValue.setValue(settings.value('start', 100, type = int))
    self.stopValue.setValue(settings.value('stop', 60000, type = int))
    self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int))
    self.corrValue.setValue(settings.value('corr', 0, type = int))
    size = settings.value('size', 600, type = int)
    self.sizeValue.setValue(size)
    for i in range(0, size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut[i] = real + 1.0j * imag

  def write_csv(self):
    dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
    dialog.setDefaultSuffix('csv')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n')
      for i in range(0, size):
        fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (self.xaxis[i], self.open.real[i], self.open.imag[i], self.short.real[i], self.short.imag[i], self.load.real[i], self.load.imag[i], self.dut.real[i], self.dut.imag[i]))
      fh.close()

  def write_s1p(self):
    dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
    dialog.setDefaultSuffix('s1p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('# GHz S MA R 50\n')
      for i in range(0, size):
        fh.write('0.0%.8d   %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
      fh.close()

  def write_s2p(self):
    dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
    dialog.setDefaultSuffix('s2p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gain = self.gain()
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('# GHz S MA R 50\n')
      for i in range(0, size):
        fh.write('0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True)))
      fh.close()
Exemple #6
0
class Scanner(QMainWindow, Ui_Scanner):
    def __init__(self):
        super(Scanner, self).__init__()
        self.setupUi(self)
        # IP address validator
        rx = QRegExp(
            '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
        )
        self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
        # state variable
        self.idle = True
        # number of samples to show on the plot
        self.xsize = self.xsizeValue.value()
        self.ysize = self.xsizeValue.value()
        self.size = self.xsize * self.ysize
        self.x = np.arange(self.xsize)  #X array for plotting
        self.y = np.arange(self.ysize)  #Y array for plotting
        self.freq = 125.0

        figure = Figure()
        figure.set_facecolor('none')
        self.axes = figure.add_subplot(111)
        self.canvas = FigureCanvas(figure)
        self.plotLayout.addWidget(self.canvas)
        self.change_scan_size()
        self.plotLayout.addWidget(self.toolbar)

        # create TCP socket
        self.socket = QTcpSocket(self)
        self.socket.connected.connect(self.connected)
        self.socket.readyRead.connect(self.read_data)
        self.socket.error.connect(self.display_error)
        # connect signals from buttons and boxes
        self.connectButton.clicked.connect(self.start)
        self.scanButton.clicked.connect(self.scan)
        self.periodValue.valueChanged.connect(self.set_period)
        self.trgtimeValue.valueChanged.connect(self.set_trgtime)
        self.trginvCheck.stateChanged.connect(self.set_trginv)
        self.shdelayValue.valueChanged.connect(self.set_shdelay)
        self.shtimeValue.valueChanged.connect(self.set_shtime)
        self.shinvCheck.stateChanged.connect(self.set_shinv)
        self.acqdelayValue.valueChanged.connect(self.set_acqdelay)
        self.samplesValue.valueChanged.connect(self.set_samples)
        self.pulsesValue.valueChanged.connect(self.set_pulses)
        self.xsizeValue.valueChanged.connect(self.set_xsize)
        self.ysizeValue.valueChanged.connect(self.set_ysize)

        # create timers
        self.startTimer = QTimer(self)
        self.startTimer.timeout.connect(self.timeout)
        self.meshTimer = QTimer(self)
        self.meshTimer.timeout.connect(self.update_mesh)
        # set default values
        self.periodValue.setValue(200.0)

    def start(self):
        if self.idle:
            self.connectButton.setEnabled(False)
            self.socket.connectToHost(self.addrValue.text(), 1001)
            self.startTimer.start(5000)
        else:
            self.stop()

    def stop(self):
        self.idle = True
        self.socket.abort()
        self.offset = 0
        self.connectButton.setText('Connect')
        self.connectButton.setEnabled(True)
        self.scanButton.setEnabled(True)

    def timeout(self):
        self.display_error('timeout')

    def connected(self):
        self.startTimer.stop()
        self.idle = False
        self.set_period(self.periodValue.value())
        self.set_trgtime(self.trgtimeValue.value())
        self.set_trginv(self.trginvCheck.checkState())
        self.set_shdelay(self.shdelayValue.value())
        self.set_shtime(self.shtimeValue.value())
        self.set_shinv(self.shinvCheck.checkState())
        self.set_acqdelay(self.acqdelayValue.value())
        self.set_samples(self.samplesValue.value())
        self.set_pulses(self.pulsesValue.value())
        # start pulse generators
        self.socket.write(struct.pack('<I', 11 << 28))
        self.connectButton.setText('Disconnect')
        self.connectButton.setEnabled(True)
        self.scanButton.setEnabled(True)

    def read_data(self):
        size = self.socket.bytesAvailable()
        if self.offset + size < 8 * self.size:
            self.buffer[self.offset:self.offset +
                        size] = self.socket.read(size)
            self.offset += size
#      plt.figure()
#      plt.plot(np.frombuffer(self.buffer,  np.int32)[0::2])
#      plt.show()
        else:
            self.meshTimer.stop()
            self.buffer[self.offset:8 *
                        self.size] = self.socket.read(8 * self.size -
                                                      self.offset)
            self.offset = 0
            self.update_mesh()
            plt.figure()
            plt.plot(self.data[0::2])
            plt.show()
            self.scanButton.setEnabled(True)

    def display_error(self, socketError):
        self.startTimer.stop()
        if socketError == 'timeout':
            QMessageBox.information(self, 'Scanner',
                                    'Error: connection timeout.')
        else:
            QMessageBox.information(self, 'Scanner',
                                    'Error: %s.' % self.socket.errorString())
        self.stop()

    def set_period(self, value):
        # set maximum delays and times to half period
        maximum = int(value * 5.0 + 0.5) / 10.0
        self.trgtimeValue.setMaximum(maximum)
        self.shdelayValue.setMaximum(maximum)
        self.shtimeValue.setMaximum(maximum)
        self.acqdelayValue.setMaximum(maximum)
        # set maximum number of samples per pulse
        maximum = int(value * 500.0 + 0.5) / 10.0
        if maximum > 256.0: maximum = 256.0
        self.samplesValue.setMaximum(maximum)
        shdelay = value * 0.25
        samples = value * 0.5
        if self.idle: return
        self.socket.write(struct.pack('<I', 0 << 28 | int(value * self.freq)))

    def set_trgtime(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 1 << 28 | int(value * self.freq)))

    def set_trginv(self, checked):
        if self.idle: return
        self.socket.write(
            struct.pack('<I', 2 << 28 | int(checked == Qt.Checked)))

    def set_shdelay(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 3 << 28 | int(value * self.freq)))

    def set_shtime(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 4 << 28 | int(value * self.freq)))

    def set_shinv(self, checked):
        if self.idle: return
        self.socket.write(
            struct.pack('<I', 5 << 28 | int(checked == Qt.Checked)))

    def set_acqdelay(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 6 << 28 | int(value * self.freq)))

    def set_samples(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 7 << 28 | int(value)))

    def set_pulses(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 8 << 28 | int(value)))

    def set_xsize(self, value):
        self.xsize = value
        self.size = self.xsize * self.ysize
        self.y = np.arange(self.xsize)
        self.change_scan_size()

    def set_ysize(self, value):
        self.ysize = value
        self.size = self.xsize * self.ysize
        self.y = np.arange(self.ysize)
        self.change_scan_size()

    def change_scan_size(self):
        self.x = np.arange(self.xsize)  #X array for plotting
        self.y = np.arange(self.ysize)  #Y array for plotting

        # buffer and offset for the incoming samples
        self.buffer = bytearray(8 * self.xsize * self.ysize)
        self.offset = 0
        self.data = np.frombuffer(self.buffer, np.int32)
        # create figure
        self.axes.axis((0.0, self.ysize, 0.0, self.xsize))
        x, y = np.meshgrid(np.linspace(0.0, self.ysize, self.ysize + 1),
                           np.linspace(0.0, self.xsize, self.xsize + 1))
        z = x / self.xsize + y * 0.0
        self.mesh = self.axes.pcolormesh(x, y, z, cmap=cm.gray, vmin=0, vmax=1)
        # create navigation toolbar
        self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
        # remove subplots action
        actions = self.toolbar.actions()
        if int(matplotlib.__version__[0]) < 2:
            self.toolbar.removeAction(actions[7])
        else:
            self.toolbar.removeAction(actions[6])
        self.canvas.draw()


#  def set_coordinates(self):
#    if self.idle: return
#    self.socket.write(struct.pack('<I', 9<<28))
#    for i in range(self.xsize):
#      for j in range(self.ysize):
#        value = (i + 0 << 18) | (j << 4)
#        self.socket.write(struct.pack('<I', 10<<28 | int(value)))

    def set_coordinates(self):
        if self.idle: return
        self.socket.write(struct.pack('<I', 9 << 28))
        for i in range(self.xco.size):
            value = (self.xco_prop[i] + 0 << 18) | (self.yco_prop[i] << 4)
            self.socket.write(struct.pack('<I', 10 << 28 | int(value)))

    def scan(self):
        if self.idle: return
        print('start scanning')
        self.scanButton.setEnabled(False)
        scan_name = self.comboBoxScan.currentText()
        xco, yco = spc.LoadScanPattern(scan_name, self.xsize, self.ysize)
        #Change the coordinate such that we scan the full fov
        self.propx = int(np.ceil(512 / (self.xsize)))
        self.propy = int(np.ceil(512 / (self.ysize)))
        self.xco = xco
        self.yco = yco
        self.xco_prop = self.propx * self.xco
        self.yco_prop = self.propy * self.yco
        self.data[:] = np.zeros(2 * self.xsize * self.ysize, np.int32)
        self.update_mesh()
        self.set_coordinates()
        self.socket.write(struct.pack('<I', 12 << 28))
        self.meshTimer.start(500)

    def update_mesh(self):
        result = self.data[0::2] / (self.samplesValue.value() *
                                    self.pulsesValue.value() * 8192.0)
        result = result - np.min(result)
        result = result.reshape(self.xsize, self.ysize)
        result = result[self.x[self.xco], self.y[self.yco]]
        self.mesh.set_array(result.reshape(self.xsize * self.ysize))
        self.mesh.set_clim(vmin=result.min(), vmax=result.max())
        self.canvas.draw()
Exemple #7
0
class Client(QDialog):
    def __init__(self, parent=None):
        super(Client, self).__init__(parent)

        self.networkSession = None
        self.blockSize = 0
        self.currentFortune = ''

        hostLabel = QLabel("&Server name:")
        portLabel = QLabel("S&erver port:")

        self.hostCombo = QComboBox()
        self.hostCombo.setEditable(True)

        name = QHostInfo.localHostName()
        if name != '':
            self.hostCombo.addItem(name)

            domain = QHostInfo.localDomainName()
            if domain != '':
                self.hostCombo.addItem(name + '.' + domain)

        if name != 'localhost':
            self.hostCombo.addItem('localhost')

        ipAddressesList = QNetworkInterface.allAddresses()

        for ipAddress in ipAddressesList:
            if not ipAddress.isLoopback():
                self.hostCombo.addItem(ipAddress.toString())

        for ipAddress in ipAddressesList:
            if ipAddress.isLoopback():
                self.hostCombo.addItem(ipAddress.toString())

        self.portLineEdit = QLineEdit()
        self.portLineEdit.setValidator(QIntValidator(1, 65535, self))

        hostLabel.setBuddy(self.hostCombo)
        portLabel.setBuddy(self.portLineEdit)

        self.statusLabel = QLabel("This examples requires that you run "
                                  "the Fortune Server example as well.")

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)
        self.getFortuneButton.setEnabled(False)

        quitButton = QPushButton("Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.tcpSocket = QTcpSocket(self)

        self.hostCombo.editTextChanged.connect(self.enableGetFortuneButton)
        self.portLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.tcpSocket.readyRead.connect(self.readFortune)
        self.tcpSocket.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostCombo, 0, 1)
        mainLayout.addWidget(portLabel, 1, 0)
        mainLayout.addWidget(self.portLineEdit, 1, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Fortune Client")
        self.portLineEdit.setFocus()

        manager = QNetworkConfigurationManager()
        if manager.capabilities(
        ) & QNetworkConfigurationManager.NetworkSessionRequired:
            settings = QSettings(QSettings.UserScope, 'QtProject')
            settings.beginGroup('QtNetwork')
            id = settings.value('DefaultNetworkConfiguration')
            settings.endGroup()

            config = manager.configurationFromIdentifier(id)
            if config.state() & QNetworkConfiguration.Discovered == 0:
                config = manager.defaultConfiguration()

            self.networkSession = QNetworkSession(config, self)
            self.networkSession.opened.connect(self.sessionOpened)

            self.getFortuneButton.setEnabled(False)
            self.statusLabel.setText("Opening network session.")
            self.networkSession.open()

    def requestNewFortune(self):
        self.getFortuneButton.setEnabled(False)
        self.blockSize = 0
        self.tcpSocket.abort()
        self.tcpSocket.connectToHost(self.hostCombo.currentText(),
                                     int(self.portLineEdit.text()))

    def readFortune(self):
        instr = QDataStream(self.tcpSocket)
        instr.setVersion(QDataStream.Qt_4_0)

        if self.blockSize == 0:
            if self.tcpSocket.bytesAvailable() < 2:
                return

            self.blockSize = instr.readUInt16()

        if self.tcpSocket.bytesAvailable() < self.blockSize:
            return

        nextFortune = instr.readQString()
        if nextFortune == self.currentFortune:
            QTimer.singleShot(0, self.requestNewFortune)
            return

        self.currentFortune = nextFortune
        self.statusLabel.setText(self.currentFortune)
        self.getFortuneButton.setEnabled(True)

    def displayError(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        elif socketError == QAbstractSocket.HostNotFoundError:
            QMessageBox.information(
                self, "Fortune Client",
                "The host was not found. Please check the host name and "
                "port settings.")
        elif socketError == QAbstractSocket.ConnectionRefusedError:
            QMessageBox.information(
                self, "Fortune Client",
                "The connection was refused by the peer. Make sure the "
                "fortune server is running, and check that the host name "
                "and port settings are correct.")
        else:
            QMessageBox.information(
                self, "Fortune Client", "The following error occurred: %s." %
                self.tcpSocket.errorString())

        self.getFortuneButton.setEnabled(True)

    def enableGetFortuneButton(self):
        self.getFortuneButton.setEnabled(
            (self.networkSession is None or self.networkSession.isOpen())
            and self.hostCombo.currentText() != ''
            and self.portLineEdit.text() != '')

    def sessionOpened(self):
        config = self.networkSession.configuration()

        if config.type() == QNetworkConfiguration.UserChoice:
            id = self.networkSession.sessionProperty('UserChoiceConfiguration')
        else:
            id = config.identifier()

        settings = QSettings(QSettings.UserScope, 'QtProject')
        settings.beginGroup('QtNetwork')
        settings.setValue('DefaultNetworkConfiguration', id)
        settings.endGroup()

        self.statusLabel.setText("This examples requires that you run the "
                                 "Fortune Server example as well.")

        self.enableGetFortuneButton()
class Client(QDialog):
    def __init__(self, parent=None):
        super(Client, self).__init__(parent)

        self.networkSession = None
        self.blockSize = 0
        self.currentFortune = ""

        hostLabel = QLabel("&Server name:")
        portLabel = QLabel("S&erver port:")

        self.hostCombo = QComboBox()
        self.hostCombo.setEditable(True)

        name = QHostInfo.localHostName()
        if name != "":
            self.hostCombo.addItem(name)

            domain = QHostInfo.localDomainName()
            if domain != "":
                self.hostCombo.addItem(name + "." + domain)

        if name != "localhost":
            self.hostCombo.addItem("localhost")

        ipAddressesList = QNetworkInterface.allAddresses()

        for ipAddress in ipAddressesList:
            if not ipAddress.isLoopback():
                self.hostCombo.addItem(ipAddress.toString())

        for ipAddress in ipAddressesList:
            if ipAddress.isLoopback():
                self.hostCombo.addItem(ipAddress.toString())

        self.portLineEdit = QLineEdit()
        self.portLineEdit.setValidator(QIntValidator(1, 65535, self))

        hostLabel.setBuddy(self.hostCombo)
        portLabel.setBuddy(self.portLineEdit)

        self.statusLabel = QLabel("This examples requires that you run " "the Fortune Server example as well.")

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)
        self.getFortuneButton.setEnabled(False)

        quitButton = QPushButton("Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.tcpSocket = QTcpSocket(self)

        self.hostCombo.editTextChanged.connect(self.enableGetFortuneButton)
        self.portLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.tcpSocket.readyRead.connect(self.readFortune)
        self.tcpSocket.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostCombo, 0, 1)
        mainLayout.addWidget(portLabel, 1, 0)
        mainLayout.addWidget(self.portLineEdit, 1, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Fortune Client")
        self.portLineEdit.setFocus()

        manager = QNetworkConfigurationManager()
        if manager.capabilities() & QNetworkConfigurationManager.NetworkSessionRequired:
            settings = QSettings(QSettings.UserScope, "QtProject")
            settings.beginGroup("QtNetwork")
            id = settings.value("DefaultNetworkConfiguration")
            settings.endGroup()

            config = manager.configurationFromIdentifier(id)
            if config.state() & QNetworkConfiguration.Discovered == 0:
                config = manager.defaultConfiguration()

            self.networkSession = QNetworkSession(config, self)
            self.networkSession.opened.connect(self.sessionOpened)

            self.getFortuneButton.setEnabled(False)
            self.statusLabel.setText("Opening network session.")
            self.networkSession.open()

    def requestNewFortune(self):
        self.getFortuneButton.setEnabled(False)
        self.blockSize = 0
        self.tcpSocket.abort()
        self.tcpSocket.connectToHost(self.hostCombo.currentText(), int(self.portLineEdit.text()))

    def readFortune(self):
        instr = QDataStream(self.tcpSocket)
        instr.setVersion(QDataStream.Qt_4_0)

        if self.blockSize == 0:
            if self.tcpSocket.bytesAvailable() < 2:
                return

            self.blockSize = instr.readUInt16()

        if self.tcpSocket.bytesAvailable() < self.blockSize:
            return

        nextFortune = instr.readQString()
        if nextFortune == self.currentFortune:
            QTimer.singleShot(0, self.requestNewFortune)
            return

        self.currentFortune = nextFortune
        self.statusLabel.setText(self.currentFortune)
        self.getFortuneButton.setEnabled(True)

    def displayError(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        elif socketError == QAbstractSocket.HostNotFoundError:
            QMessageBox.information(
                self, "Fortune Client", "The host was not found. Please check the host name and " "port settings."
            )
        elif socketError == QAbstractSocket.ConnectionRefusedError:
            QMessageBox.information(
                self,
                "Fortune Client",
                "The connection was refused by the peer. Make sure the "
                "fortune server is running, and check that the host name "
                "and port settings are correct.",
            )
        else:
            QMessageBox.information(
                self, "Fortune Client", "The following error occurred: %s." % self.tcpSocket.errorString()
            )

        self.getFortuneButton.setEnabled(True)

    def enableGetFortuneButton(self):
        self.getFortuneButton.setEnabled(
            (self.networkSession is None or self.networkSession.isOpen())
            and self.hostCombo.currentText() != ""
            and self.portLineEdit.text() != ""
        )

    def sessionOpened(self):
        config = self.networkSession.configuration()

        if config.type() == QNetworkConfiguration.UserChoice:
            id = self.networkSession.sessionProperty("UserChoiceConfiguration")
        else:
            id = config.identifier()

        settings = QSettings(QSettings.UserScope, "QtProject")
        settings.beginGroup("QtNetwork")
        settings.setValue("DefaultNetworkConfiguration", id)
        settings.endGroup()

        self.statusLabel.setText("This examples requires that you run the " "Fortune Server example as well.")

        self.enableGetFortuneButton()
Exemple #9
0
class Main(QMainWindow):
    def __init__(self, *args):
        super(Main, self).__init__(*args)

        loadUi('mainwindow.ui', self)

        self.host.setText("localhost")
        self.port.setText("11010")
        self.prompt.setText("M114")

        self.conn = QTcpSocket(self)
        self.conn.readyRead.connect(self.readSocket)
        self.conn.error.connect(self.socketError)
        self.conn.connected.connect(self.socketConnect)
        self.conn.disconnected.connect(self.socketDisconnect)

        self.connected = False

        self.actionSave.triggered.connect(self.save)

        self.prompt.setFocus()

        self.do_connect()

    def append(self, text):
        self.text.append(text)

        if self.autoscroll.isChecked():
            c = self.text.textCursor()
            c.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
            self.text.setTextCursor(c)

    def readSocket(self):
        r = self.conn.readAll()
        if r:
            r = str(r).strip()
            for chunk in r.splitlines():
                if chunk:
                    if chunk[0] == '<':
                        self.text.setTextColor(QColor(200, 0, 0))
                    elif chunk[0] == '>':
                        self.text.setTextColor(QColor(0, 200, 0))
                    else:
                        self.text.setTextColor(QColor(0, 0, 200))

                    self.append(chunk)

    def info(self, errtext):
        self.text.setTextColor(QColor(20, 20, 20))
        self.append(errtext)

    def err(self, errtext):
        self.text.setTextColor(QColor(100, 0, 0))
        self.append(errtext)

    def socketDisconnect(self):
        self.connected = False
        self.err("Disconnected")

    def socketConnect(self):
        self.connected = True
        self.info("Connected")

    def socketError(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        elif socketError == QAbstractSocket.HostNotFoundError:
            self.err("The host was not found. Please check the host name and "
                     "port settings.")

        elif socketError == QAbstractSocket.ConnectionRefusedError:
            self.err("The connection was refused by the peer. Make sure the "
                     "server is running, and check that the host name "
                     "and port settings are correct.")
        else:
            self.err("The following error occurred: {0}"
                     .format(self.conn.errorString()))

    def save(self):
        fname, sel = QFileDialog.getSaveFileName(
            self,
            'Save Log',)
            #'/path/to/default/directory', FIXME: lastused
            #selectedFilter='*.txt')

        if fname:
            with open(fname, 'w+') as f:
                f.write(self.text.toPlainText())

    def do_connect(self):
        self.conn.abort()
        self.conn.connectToHost(self.host.text(),
                                int(self.port.text()))

    @pyqtSlot()
    def on_connect_clicked(self):
        self.do_connect()
        self.prompt.setFocus()

    @pyqtSlot()
    def on_send_clicked(self):
        if not self.connected:
            self.err("Not connected")
            return
        out = (self.prompt.text() + '\n').encode('ascii')
        self.conn.write(out)

    @pyqtSlot()
    def on_right_on_clicked(self):
        self.action("e1")
class MuoScope(QMainWindow, Ui_MuoScope):
    def __init__(self):
        super(MuoScope, self).__init__()
        self.setupUi(self)
        # IP address validator
        rx = QRegExp(
            '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
        )
        self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
        # state variables
        self.idle = True
        self.reading = False
        # buffer and offset for the incoming samples
        self.buffer = bytearray(84)
        self.offset = 0
        self.data = np.frombuffer(self.buffer, np.float32)
        # configure widgets
        self.discValue = {}
        self.discFeedback = {}
        self.monoValue = {}
        self.monoFeedback = {}
        self.dlyValue = {}
        for i in range(0, 8):
            label = QLabel('CH' + str(i))
            label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
            self.discLayout.addWidget(label, (i // 4) * 3 + 0, i % 4)
            self.discValue[i] = QSpinBox()
            self.discValue[i].setMaximum(511)
            self.discValue[i].valueChanged.connect(partial(self.set_disc, i))
            self.discLayout.addWidget(self.discValue[i], (i // 4) * 3 + 1,
                                      i % 4)
            self.discFeedback[i] = QLineEdit()
            self.discFeedback[i].setReadOnly(True)
            self.discLayout.addWidget(self.discFeedback[i], (i // 4) * 3 + 2,
                                      i % 4)
        for i in range(0, 8):
            label = QLabel('CH' + str(i))
            label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
            self.monoLayout.addWidget(label, (i // 4) * 3 + 0, i % 4)
            self.monoValue[i] = QSpinBox()
            self.monoValue[i].setMaximum(1023)
            self.monoValue[i].valueChanged.connect(partial(self.set_mono, i))
            self.monoLayout.addWidget(self.monoValue[i], (i // 4) * 3 + 1,
                                      i % 4)
            self.monoFeedback[i] = QLineEdit()
            self.monoFeedback[i].setReadOnly(True)
            self.monoLayout.addWidget(self.monoFeedback[i], (i // 4) * 3 + 2,
                                      i % 4)
        for i in range(0, 4):
            label = QLabel(chr(ord('A') + i))
            label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
            self.dlyLayout.addWidget(label, 0, i)
            self.dlyValue[i] = QSpinBox()
            self.dlyValue[i].setMaximum(15)
            self.dlyValue[i].valueChanged.connect(partial(self.set_dly, i))
            self.dlyLayout.addWidget(self.dlyValue[i], 1, i)
        self.voltageValue.valueChanged.connect(partial(self.set_hv, 0))
        self.currentValue.valueChanged.connect(partial(self.set_hv, 1))
        self.stateValue.stateChanged.connect(self.set_state)
        self.wndValue.valueChanged.connect(self.set_wnd)
        self.cutValue.valueChanged.connect(self.set_cut)
        # read settings
        settings = QSettings('muoscope.ini', QSettings.IniFormat)
        self.read_cfg_settings(settings)
        # create TCP socket
        self.socket = QTcpSocket(self)
        self.socket.connected.connect(self.connected)
        self.socket.readyRead.connect(self.read_data)
        self.socket.error.connect(self.display_error)
        # connect signals from widgets
        self.connectButton.clicked.connect(self.start)
        self.writeButton.clicked.connect(self.write_cfg)
        self.readButton.clicked.connect(self.read_cfg)
        # create timers
        self.startTimer = QTimer(self)
        self.startTimer.timeout.connect(self.timeout)
        self.adcTimer = QTimer(self)
        self.adcTimer.timeout.connect(self.get_adc)

    def start(self):
        if self.idle:
            self.connectButton.setEnabled(False)
            self.socket.connectToHost(self.addrValue.text(), 1001)
            self.startTimer.start(5000)
        else:
            self.stop()

    def stop(self):
        self.adcTimer.stop()
        self.idle = True
        self.socket.abort()
        self.connectButton.setText('Connect')
        self.connectButton.setEnabled(True)

    def timeout(self):
        self.display_error('timeout')

    def connected(self):
        self.startTimer.stop()
        self.idle = False
        self.connectButton.setText('Disconnect')
        self.connectButton.setEnabled(True)
        for i, item in self.discValue.items():
            self.set_disc(i, item.value())
        for i, item in self.monoValue.items():
            self.set_mono(i, item.value())
        self.set_hv(0, self.voltageValue.value())
        self.set_hv(1, self.currentValue.value())
        self.set_state(self.stateValue.isChecked())
        self.set_dly(0)
        self.set_wnd(self.wndValue.value())
        self.set_cut(self.cutValue.value())
        self.adcTimer.start(200)

    def timeout(self):
        self.display_error('timeout')

    def display_error(self, socketError):
        self.startTimer.stop()
        if socketError == 'timeout':
            QMessageBox.information(self, 'MuoScope',
                                    'Error: connection timeout.')
        else:
            QMessageBox.information(self, 'MuoScope',
                                    'Error: %s.' % self.socket.errorString())
        self.stop()

    def read_data(self):
        while (self.socket.bytesAvailable() > 0):
            if not self.reading:
                self.socket.readAll()
                return
            size = self.socket.bytesAvailable()
            limit = 84
            if self.offset + size < limit:
                self.buffer[self.offset:self.offset +
                            size] = self.socket.read(size)
                self.offset += size
            else:
                self.buffer[self.offset:limit] = self.socket.read(limit -
                                                                  self.offset)
                self.reading = False
                for i, item in self.discFeedback.items():
                    item.setText('%.3f' % self.data[i + i // 2 * 2 + 0])
                for i, item in self.monoFeedback.items():
                    item.setText('%.3f' % self.data[i + i // 2 * 2 + 2])
                self.voltageFeedback.setText('%.3f' % self.data[17])
                self.currentFeedback.setText('%.3f' % self.data[16])
                self.stateFeedback.setText('%.0f' % self.data[20])

    def get_adc(self):
        if self.idle: return
        self.reading = True
        self.socket.write(struct.pack('<I', 0 << 24))

    def set_disc(self, channel, value):
        if self.idle: return
        self.socket.write(
            struct.pack(
                '<I', 1 << 24 | int(channel + channel // 2 * 2 + 0) << 16
                | int(value)))

    def set_mono(self, channel, value):
        if self.idle: return
        self.socket.write(
            struct.pack(
                '<I', 1 << 24 | int(channel + channel // 2 * 2 + 2) << 16
                | int(value)))

    def set_hv(self, channel, value):
        if self.idle: return
        self.socket.write(
            struct.pack('<I', 2 << 24 | int(channel) << 16 | int(value)))

    def set_state(self, state):
        if self.idle: return
        self.socket.write(
            struct.pack('<I', 3 << 24 | int(self.stateValue.isChecked())))

    def set_dly(self, value):
        if self.idle: return
        value = self.dlyValue[3].value() << 12 | self.dlyValue[2].value(
        ) << 8 | self.dlyValue[1].value() << 4 | self.dlyValue[0].value()
        self.socket.write(struct.pack('<I', 4 << 24 | int(value)))

    def set_wnd(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 5 << 24 | int(value)))

    def set_cut(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 6 << 24 | int(value)))

    def write_cfg(self):
        dialog = QFileDialog(self, 'Write configuration settings', '.',
                             '*.ini')
        dialog.setDefaultSuffix('ini')
        dialog.selectFile('muoscope.ini')
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        dialog.setOptions(QFileDialog.DontConfirmOverwrite)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.selectedFiles()
            settings = QSettings(name[0], QSettings.IniFormat)
            self.write_cfg_settings(settings)

    def read_cfg(self):
        dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
        dialog.setDefaultSuffix('ini')
        dialog.selectFile('muoscope.ini')
        dialog.setAcceptMode(QFileDialog.AcceptOpen)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.selectedFiles()
            settings = QSettings(name[0], QSettings.IniFormat)
            self.read_cfg_settings(settings)

    def write_cfg_settings(self, settings):
        settings.setValue('addr', self.addrValue.text())
        for i, item in self.discValue.items():
            settings.setValue('disc_%d' % i, item.value())
        for i, item in self.monoValue.items():
            settings.setValue('mono_%d' % i, item.value())
        for i, item in self.dlyValue.items():
            settings.setValue('dly_%d' % i, item.value())
        settings.setValue('voltage', self.voltageValue.value())
        settings.setValue('current', self.currentValue.value())
        settings.setValue('cut', self.cutValue.value())
        settings.setValue('wnd', self.wndValue.value())

    def read_cfg_settings(self, settings):
        self.addrValue.setText(settings.value('addr', '192.168.42.1'))
        for i, item in self.discValue.items():
            item.setValue(settings.value('disc_%d' % i, 100, type=int))
        for i, item in self.monoValue.items():
            item.setValue(settings.value('mono_%d' % i, 100, type=int))
        for i, item in self.dlyValue.items():
            item.setValue(settings.value('dly_%d' % i, 0, type=int))
        self.voltageValue.setValue(settings.value('voltage', 0, type=int))
        self.currentValue.setValue(settings.value('current', 4095, type=int))
        self.cutValue.setValue(settings.value('cut', 1, type=int))
        self.wndValue.setValue(settings.value('wnd', 3, type=int))
Exemple #11
0
class Main(QMainWindow):
    def __init__(self, *args):
        super(Main, self).__init__(*args)

        loadUi('mainwindow.ui', self)

        self.host.setText("localhost")
        self.port.setText("11010")
        self.prompt.setText("M114")

        self.conn = QTcpSocket(self)
        self.conn.readyRead.connect(self.readSocket)
        self.conn.error.connect(self.socketError)
        self.conn.connected.connect(self.socketConnect)
        self.conn.disconnected.connect(self.socketDisconnect)

        self.connected = False

        self.actionSave.triggered.connect(self.save)

        self.prompt.setFocus()

        self.do_connect()

    def append(self, text):
        self.text.append(text)

        if self.autoscroll.isChecked():
            c = self.text.textCursor()
            c.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
            self.text.setTextCursor(c)

    def readSocket(self):
        r = self.conn.readAll()
        if r:
            r = str(r).strip()
            for chunk in r.splitlines():
                if chunk:
                    if chunk[0] == '<':
                        self.text.setTextColor(QColor(200, 0, 0))
                    elif chunk[0] == '>':
                        self.text.setTextColor(QColor(0, 200, 0))
                    else:
                        self.text.setTextColor(QColor(0, 0, 200))

                    self.append(chunk)

    def info(self, errtext):
        self.text.setTextColor(QColor(20, 20, 20))
        self.append(errtext)

    def err(self, errtext):
        self.text.setTextColor(QColor(100, 0, 0))
        self.append(errtext)

    def socketDisconnect(self):
        self.connected = False
        self.err("Disconnected")

    def socketConnect(self):
        self.connected = True
        self.info("Connected")

    def socketError(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        elif socketError == QAbstractSocket.HostNotFoundError:
            self.err("The host was not found. Please check the host name and "
                     "port settings.")

        elif socketError == QAbstractSocket.ConnectionRefusedError:
            self.err("The connection was refused by the peer. Make sure the "
                     "server is running, and check that the host name "
                     "and port settings are correct.")
        else:
            self.err("The following error occurred: {0}".format(
                self.conn.errorString()))

    def save(self):
        fname, sel = QFileDialog.getSaveFileName(
            self,
            'Save Log',
        )
        #'/path/to/default/directory', FIXME: lastused
        #selectedFilter='*.txt')

        if fname:
            with open(fname, 'w+') as f:
                f.write(self.text.toPlainText())

    def do_connect(self):
        self.conn.abort()
        self.conn.connectToHost(self.host.text(), int(self.port.text()))

    @pyqtSlot()
    def on_connect_clicked(self):
        self.do_connect()
        self.prompt.setFocus()

    @pyqtSlot()
    def on_send_clicked(self):
        if not self.connected:
            self.err("Not connected")
            return
        out = (self.prompt.text() + '\n').encode('ascii')
        self.conn.write(out)

    @pyqtSlot()
    def on_right_on_clicked(self):
        self.action("e1")
Exemple #12
0
class Crossing(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Výroba ovládacích prvků
        self.connectButton = QPushButton(self, text="Start")
        self.connectButton.clicked.connect(self.connect)

        self.disconnectButton = QPushButton(self, text="Stop")
        self.disconnectButton.clicked.connect(self.disconnect)

        self.backButton = QPushButton(self, text="Return", enabled=False)
        self.backButton.clicked.connect(self.sendBack)

        self.presentObjects = QComboBox(self)

        self.backAllButton = QPushButton(self, text="Return All")
        self.backAllButton.clicked.connect(self.sendBackAll)

        self.messageLabel = QLabel(self)
        self.statusLabel = QLabel(self)
        self.statusLabel.setText('Disconnected')
        self.statLabel = QLabel(self)

        # Rozložení ovládacích prvků
        self.layout = QVBoxLayout(self)

        self.startLayout = QHBoxLayout()
        self.startLayout.addWidget(self.connectButton)
        self.startLayout.addWidget(self.disconnectButton)
        self.layout.addLayout(self.startLayout)

        self.backLayout = QHBoxLayout()
        self.backLayout.addWidget(self.presentObjects)
        self.backLayout.addWidget(self.backButton)
        self.backLayout.addWidget(self.backAllButton)
        self.layout.addLayout(self.backLayout)

        self.layout.addWidget(self.messageLabel)
        self.layout.addWidget(self.statusLabel)
        self.layout.addWidget(self.statLabel)

        # Příprava TCP socketu
        self.socket = QTcpSocket(self)
        self.socket.readyRead.connect(self.read)
        self.socket.connected.connect(self.connected)
        self.readBuffer = bytearray()
        self.disconnecting = False

        # Zobrazení
        self.setLayout(self.layout)
        self.show()

    def disconnect(self):
        self.socket.write("BYE\n".encode())
        self.disconnecting = True
        self.read()

    def softDisconnect(self):
        # Odpojí se od servru
        self.socket.disconnectFromHost()
        self.statusLabel.setText('Disconnected')

    def connect(self):
        # Nejdřív se odpoj, pokud už
        # spojení běží
        self.socket.abort()

        # A znovu se připoj
        self.socket.connectToHost("ksp.mff.cuni.cz", 48888)
        self.statusLabel.setText("Connecting")

    def connected(self):
        # Pozdravíme server
        self.socket.write("HELLO\n".encode())
        self.statusLabel.setText("Connected")
        self.disconnecting = False

    def read(self):
        # Přečteme všechno, co jsme dostali
        while self.socket.bytesAvailable() > 0:
            self.readBuffer += self.socket.read(128)

        # Rozdělíme na řádky
        lines = self.readBuffer.split(b"\n")

        # Zbytek uložíme na příště
        self.readBuffer = lines.pop()

        # Zpracujeme řádky, které dorazily
        for l in lines:
            text = l.decode().rstrip()
            if "STAT" not in text:
                self.backButton.setEnabled(True)
                self.presentObjects.addItem(text)
                self.messageLabel.setText(text)
            else:
                self.statLabel.setText(text)
                if self.disconnecting:
                    self.softDisconnect()

    def sendBack(self):
        text = self.presentObjects.currentText() + "\n"
        if not text == "":
            index = self.presentObjects.currentIndex()
            self.socket.write(text.encode())
            self.presentObjects.removeItem(index)

            if self.presentObjects.currentText() == "":
                self.backButton.setEnabled(False)

    def sendBackAll(self):
        allItems = [
            self.presentObjects.itemText(i)
            for i in range(self.presentObjects.count())
        ]
        for item in allItems:
            text = item + "\n"
            self.socket.write(text.encode())
        self.presentObjects.clear()
Exemple #13
0
class TcpC(QDialog, Ui_TcpClient):
    """
    Tcp客户端
    """
    def __init__(self, parent=None):
        """
        一些初始设置
        """
        super(TcpC, self).__init__(parent)
        self.setupUi(self)
        self.TotalBytes = 0
        self.bytesReceive = 0
        self.fileNameSize = 0
        self.bytesToReceive = 0
        self.fileName = ""
        self.tcpClient = QTcpSocket(self)
        self.tcpPort = 7788
        self.time = QTime()

        self.tcpClient.readyRead.connect(self.readMessage)
        # 每当新数据可用于从设备的当前读取通道读取时,readyRead信号就会发出一次。

        self.tcpClient.error.connect(self.displayError)
        # 当网络连接出现问题时调用displayError()函数。

    def setHostAddress(self, address):
        """
        设置服务器地址
        """
        self.hostAddress = address
        self.newConnect()
        # 设置服务器地址,同时调用newConnect()函数。

    def setFileName(self, file):
        """
        待接收文件的文件名
        """
        self.localFile = QFile(file)
        # 设置待接收文件的文件名,这个函数是放在主程序里面调用的。

    def closeEvent(self, event):
        """
        关闭事件
        """
        self.on_tcpClientCloseBtn_clicked()

    def newConnect(self):
        """
        连接服务器并开始计时
        """
        self.tcpClient.abort()
        self.tcpClient.connectToHost(self.hostAddress, self.tcpPort)
        self.time.start()
        # abort()中止当前连接并重置套接字。与disconnectFromHost()不同,此函数立即关闭套接字,丢弃写缓冲区中的任何挂起数据。
        # connectToHost()尝试与self.hostAddress的self.tcpPort端口建立连接。

    def readMessage(self):
        """
        读取文件数据
        """
        receiver = QDataStream(self.tcpClient)
        receiver.setVersion(QDataStream.Qt_5_4)

        if self.bytesReceive <= 2:
            if self.tcpClient.bytesAvailable() >= 2 and self.fileNameSize == 0:
                self.TotalBytes = receiver.readInt64()
                self.fileNameSize = receiver.readInt64()
                self.bytesReceive += 2
        # 当接收的字节数小于等2,同时套接字返回等待读取的传入字节数大于2而文件名大小不确定时,传输的总大小receiver.readInt64(),文件名大小是receiver.readInt64()。

            if self.tcpClient.bytesAvailable() >= self.fileNameSize and self.fileNameSize != 0:
                self.fileName = receiver.readQString()
                self.bytesReceive += self.fileNameSize
                # 当我们接收的字节数一定后,我们读取文件名receiver.readQString(),自然收到的字节数要加上文件名大小。
                if not(self.localFile.open(QFile.WriteOnly)):
                    QMessageBox.warning(self, "应用程序", "无法读取文件 {}:\n {}".format(self.fileName, self.localFile.errorString()))
                    return
                    # 要是写文件存在问题就报错。
            else:
                return

        if self.bytesReceive < self.TotalBytes:
            self.bytesReceive += self.tcpClient.bytesAvailable()
            inBlock = self.tcpClient.readAll()
            self.localFile.write(inBlock)
            inBlock.resize(0)

        useTime = self.time.elapsed() / 1000
        
        bytesReceived = self.bytesReceive / (1024*1024)
        speed = bytesReceived / useTime
        total = self.TotalBytes / (1024*1024)
        left = (total - bytesReceived) / speed

        if bytesReceived < 0.01:
            # 要是我们收到的文件太小了,我们设定成KB为单位
            bytesReceived = self.bytesReceive / 1024
            speed = bytesReceived / useTime / 1024
            total = self.TotalBytes / 1024
            if left > 0:
                msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left)
            else:
                msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime)

        else:
            # 要是文件比较大,我们设定成MB为单位
            if left > 0:
                msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left)
            else:
                msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime)

        self.progressBar.setMaximum(total)
        self.progressBar.setValue(bytesReceived)

        self.tcpClientStatuslabel.setText(msg)
        
        if self.bytesReceive == self.TotalBytes:
            self.localFile.close()
            self.tcpClient.close()
            self.tcpClientStatuslabel.setText("接收文件{}完毕".format(self.fileName))
            self.tcpClientBtn.setEnabled(False)
        # 当我们接收的大小和文件总大小一致时,关闭网络连接、文件,提示接收完毕。


    def displayError(self, socketError):
        """
        显示错误
        """
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        else:
            errorMsg = self.tcpClient.errorString()
            QMessageBox.warning(self, "应用程序", errorMsg)
            return
        # 网络错误的处理。

    @pyqtSlot()
    def on_tcpClientBtn_clicked(self):
        """
        取消接收
        """
        self.tcpClient.abort()
        if self.localFile.isOpen():
            self.localFile.close()
        
        self.tcpClientBtn.setEnabled(False)
        # 点击取消时传输终止
    
    @pyqtSlot()
    def on_tcpClientCloseBtn_clicked(self):
        """
        关闭
        """
        self.tcpClient.abort()
        if self.localFile.isOpen():
            self.localFile.close()
        self.close()
        self.tcpClientBtn.setEnabled(True)
        # 关闭网络连接,相关设置复位。
Exemple #14
0
class VNA(QMainWindow, Ui_VNA):
  graphs = ['open', 'short', 'load', 'dut', 'smith', 'imp', 'swr', 'gamma', 'rl', 'gain_short', 'gain_open']

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variables
    self.idle = True
    self.reading = False
    self.auto = False
    # sweep parameters
    self.sweep_start = 10
    self.sweep_stop = 60000
    self.sweep_size = 6000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(16 * 32768)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    # create measurements
    self.open = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.short = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.load = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.dut = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.mode = 'open'
    # create figures
    self.tabs = {}
    for i in range(len(self.graphs)):
      layout = getattr(self, '%sLayout' % self.graphs[i])
      self.tabs[i] = FigureTab(layout, self)
    # configure widgets
    self.rateValue.addItems(['10000', '5000', '1000', '500', '100', '50', '10', '5', '1'])
    self.rateValue.lineEdit().setReadOnly(True)
    self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
    for i in range(self.rateValue.count()):
      self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
    self.set_enabled(False)
    self.stopSweep.setEnabled(False)
    # read settings
    settings = QSettings('vna.ini', QSettings.IniFormat)
    self.read_cfg_settings(settings)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from widgets
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(partial(self.sweep, 'open'))
    self.shortSweep.clicked.connect(partial(self.sweep, 'short'))
    self.loadSweep.clicked.connect(partial(self.sweep, 'load'))
    self.singleSweep.clicked.connect(partial(self.sweep, 'dut'))
    self.autoSweep.clicked.connect(self.sweep_auto)
    self.stopSweep.clicked.connect(self.cancel)
    self.csvButton.clicked.connect(self.write_csv)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.s2pshortButton.clicked.connect(self.write_s2p_short)
    self.s2popenButton.clicked.connect(self.write_s2p_open)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    self.corrValue.valueChanged.connect(self.set_corr)
    self.phase1Value.valueChanged.connect(self.set_phase1)
    self.phase2Value.valueChanged.connect(self.set_phase2)
    self.level1Value.valueChanged.connect(self.set_level1)
    self.level2Value.valueChanged.connect(self.set_level2)
    self.tabWidget.currentChanged.connect(self.update_tab)
    # create timers
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)
    self.sweepTimer = QTimer(self)
    self.sweepTimer.timeout.connect(self.sweep_timeout)

  def set_enabled(self, enabled):
    widgets = [self.rateValue, self.level1Value, self.level2Value, self.corrValue, self.phase1Value, self.phase2Value, self.startValue, self.stopValue, self.sizeValue, self.openSweep, self.shortSweep, self.loadSweep, self.singleSweep, self.autoSweep]
    for entry in widgets:
      entry.setEnabled(enabled)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.cancel()
    self.socket.abort()
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.set_enabled(False)
    self.stopSweep.setEnabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_rate(self.rateValue.currentIndex())
    self.set_corr(self.corrValue.value())
    self.set_phase1(self.phase1Value.value())
    self.set_phase2(self.phase2Value.value())
    self.set_level1(self.level1Value.value())
    self.set_level2(self.level2Value.value())
    self.set_gpio(1)
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.set_enabled(True)
    self.stopSweep.setEnabled(True)

  def read_data(self):
    while(self.socket.bytesAvailable() > 0):
      if not self.reading:
        self.socket.readAll()
        return
      size = self.socket.bytesAvailable()
      self.progressBar.setValue((self.offset + size) / 16)
      limit = 16 * self.sweep_size
      if self.offset + size < limit:
        self.buffer[self.offset:self.offset + size] = self.socket.read(size)
        self.offset += size
      else:
        self.buffer[self.offset:limit] = self.socket.read(limit - self.offset)
        adc1 = self.data[0::2]
        adc2 = self.data[1::2]
        attr = getattr(self, self.mode)
        start = self.sweep_start
        stop = self.sweep_stop
        size = self.sweep_size
        attr.freq = np.linspace(start, stop, size)
        attr.data = adc1[0:size].copy()
        self.update_tab()
        self.reading = False
        if not self.auto:
          self.progressBar.setValue(0)
          self.set_enabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value

  def set_stop(self, value):
    self.sweep_stop = value

  def set_size(self, value):
    self.sweep_size = value

  def set_rate(self, value):
    if self.idle: return
    rate = [5, 10, 50, 100, 500, 1000, 5000, 10000, 50000][value]
    self.socket.write(struct.pack('<I', 3<<28 | int(rate)))

  def set_corr(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value)))

  def set_phase1(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(value)))

  def set_phase2(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 6<<28 | int(value)))

  def set_level1(self, value):
    if self.idle: return
    data = 0 if value == -90 else int(32766 * np.power(10.0, value / 20.0))
    self.socket.write(struct.pack('<I', 7<<28 | int(data)))

  def set_level2(self, value):
    if self.idle: return
    data = 0 if value == -90 else int(32766 * np.power(10.0, value / 20.0))
    self.socket.write(struct.pack('<I', 8<<28 | int(data)))

  def set_gpio(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 9<<28 | int(value)))

  def sweep(self, mode):
    if self.idle: return
    self.set_enabled(False)
    self.mode = mode
    self.offset = 0
    self.reading = True
    self.socket.write(struct.pack('<I', 0<<28 | int(self.sweep_start * 1000)))
    self.socket.write(struct.pack('<I', 1<<28 | int(self.sweep_stop * 1000)))
    self.socket.write(struct.pack('<I', 2<<28 | int(self.sweep_size)))
    self.socket.write(struct.pack('<I', 10<<28))
    self.progressBar.setMinimum(0)
    self.progressBar.setMaximum(self.sweep_size)
    self.progressBar.setValue(0)

  def cancel(self):
    self.sweepTimer.stop()
    self.auto = False
    self.reading = False
    self.socket.write(struct.pack('<I', 11<<28))
    self.progressBar.setValue(0)
    self.set_enabled(True)

  def sweep_auto(self):
    self.auto = True
    self.sweepTimer.start(100)

  def sweep_timeout(self):
    if not self.reading:
      self.sweep('dut')

  def update_tab(self):
    index = self.tabWidget.currentIndex()
    self.tabs[index].update(self.graphs[index])

  def interp(self, freq, meas):
    real = np.interp(freq, meas.freq, meas.data.real, period = meas.period)
    imag = np.interp(freq, meas.freq, meas.data.imag, period = meas.period)
    return real + 1j * imag

  def gain_short(self, freq):
    short = self.interp(freq, self.short)
    dut = self.interp(freq, self.dut)
    return np.divide(dut, short)

  def gain_open(self, freq):
    open = self.interp(freq, self.open)
    dut = self.interp(freq, self.dut)
    return np.divide(dut, open)

  def impedance(self, freq):
    open = self.interp(freq, self.open)
    short = self.interp(freq, self.short)
    load = self.interp(freq, self.load)
    dut = self.interp(freq, self.dut)
    z = np.divide(50.0 * (open - load) * (dut - short), (load - short) * (open - dut))
    z = np.asarray(z)
    z.real[z.real < 1.0e-2] = 9.99e-3
    return z

  def gamma(self, freq):
    z = self.impedance(freq)
    return np.divide(z - 50.0, z + 50.0)

  def swr(self, freq):
    magnitude = np.absolute(self.gamma(freq))
    swr = np.divide(1.0 + magnitude, 1.0 - magnitude)
    return np.clip(swr, 1.0, 99.99)

  def write_cfg(self):
    dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.selectFile('vna.ini')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.write_cfg_settings(settings)

  def read_cfg(self):
    dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.selectFile('vna.ini')
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.read_cfg_settings(settings)
      window.update_tab()

  def write_cfg_settings(self, settings):
    settings.setValue('addr', self.addrValue.text())
    settings.setValue('rate', self.rateValue.currentIndex())
    settings.setValue('corr', self.corrValue.value())
    settings.setValue('phase_1', self.phase1Value.value())
    settings.setValue('phase_2', self.phase2Value.value())
    settings.setValue('level_1', self.level1Value.value())
    settings.setValue('level_2', self.level2Value.value())
    settings.setValue('open_start', int(self.open.freq[0]))
    settings.setValue('open_stop', int(self.open.freq[-1]))
    settings.setValue('open_size', self.open.freq.size)
    settings.setValue('short_start', int(self.short.freq[0]))
    settings.setValue('short_stop', int(self.short.freq[-1]))
    settings.setValue('short_size', self.short.freq.size)
    settings.setValue('load_start', int(self.load.freq[0]))
    settings.setValue('load_stop', int(self.load.freq[-1]))
    settings.setValue('load_size', self.load.freq.size)
    settings.setValue('dut_start', int(self.dut.freq[0]))
    settings.setValue('dut_stop', int(self.dut.freq[-1]))
    settings.setValue('dut_size', self.dut.freq.size)
    for i in range(len(FigureTab.cursors)):
      settings.setValue('cursor_%d' % i, FigureTab.cursors[i])
    data = self.open.data
    for i in range(self.open.freq.size):
      settings.setValue('open_real_%d' % i, float(data.real[i]))
      settings.setValue('open_imag_%d' % i, float(data.imag[i]))
    data = self.short.data
    for i in range(self.short.freq.size):
      settings.setValue('short_real_%d' % i, float(data.real[i]))
      settings.setValue('short_imag_%d' % i, float(data.imag[i]))
    data = self.load.data
    for i in range(self.load.freq.size):
      settings.setValue('load_real_%d' % i, float(data.real[i]))
      settings.setValue('load_imag_%d' % i, float(data.imag[i]))
    data = self.dut.data
    for i in range(self.dut.freq.size):
      settings.setValue('dut_real_%d' % i, float(data.real[i]))
      settings.setValue('dut_imag_%d' % i, float(data.imag[i]))

  def read_cfg_settings(self, settings):
    self.addrValue.setText(settings.value('addr', '192.168.1.100'))
    self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int))
    self.corrValue.setValue(settings.value('corr', 0, type = int))
    self.phase1Value.setValue(settings.value('phase_1', 0, type = int))
    self.phase2Value.setValue(settings.value('phase_2', 0, type = int))
    self.level1Value.setValue(settings.value('level_1', 0, type = int))
    self.level2Value.setValue(settings.value('level_2', -90, type = int))
    open_start = settings.value('open_start', 10, type = int)
    open_stop = settings.value('open_stop', 60000, type = int)
    open_size = settings.value('open_size', 6000, type = int)
    short_start = settings.value('short_start', 10, type = int)
    short_stop = settings.value('short_stop', 60000, type = int)
    short_size = settings.value('short_size', 6000, type = int)
    load_start = settings.value('load_start', 10, type = int)
    load_stop = settings.value('load_stop', 60000, type = int)
    load_size = settings.value('load_size', 6000, type = int)
    dut_start = settings.value('dut_start', 10, type = int)
    dut_stop = settings.value('dut_stop', 60000, type = int)
    dut_size = settings.value('dut_size', 6000, type = int)
    self.startValue.setValue(dut_start)
    self.stopValue.setValue(dut_stop)
    self.sizeValue.setValue(dut_size)
    for i in range(len(FigureTab.cursors)):
      FigureTab.cursors[i] = settings.value('cursor_%d' % i, FigureTab.cursors[i], type = int)
    self.open.freq = np.linspace(open_start, open_stop, open_size)
    self.open.data = np.zeros(open_size, np.complex64)
    for i in range(open_size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open.data[i] = real + 1.0j * imag
    self.short.freq = np.linspace(short_start, short_stop, short_size)
    self.short.data = np.zeros(short_size, np.complex64)
    for i in range(short_size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short.data[i] = real + 1.0j * imag
    self.load.freq = np.linspace(load_start, load_stop, load_size)
    self.load.data = np.zeros(load_size, np.complex64)
    for i in range(load_size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load.data[i] = real + 1.0j * imag
    self.dut.freq = np.linspace(dut_start, dut_stop, dut_size)
    self.dut.data = np.zeros(dut_size, np.complex64)
    for i in range(dut_size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut.data[i] = real + 1.0j * imag

  def write_csv(self):
    dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
    dialog.setDefaultSuffix('csv')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      f = self.dut.freq
      o = self.interp(f, self.open)
      s = self.interp(f, self.short)
      l = self.interp(f, self.load)
      d = self.dut.data
      fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n')
      for i in range(f.size):
        fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (f[i] * 1000, o.real[i], o.imag[i], s.real[i], s.imag[i], l.real[i], l.imag[i], d.real[i], d.imag[i]))
      fh.close()

  def write_s1p(self):
    dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
    dialog.setDefaultSuffix('s1p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      freq = self.dut.freq
      gamma = self.gamma(freq)
      fh.write('# GHz S MA R 50\n')
      for i in range(freq.size):
        fh.write('0.0%.8d   %8.6f %7.2f\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
      fh.close()

  def write_s2p(self, gain):
    dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
    dialog.setDefaultSuffix('s2p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      freq = self.dut.freq
      gamma = self.gamma(freq)
      fh.write('# GHz S MA R 50\n')
      for i in range(freq.size):
        fh.write('0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True)))
      fh.close()

  def write_s2p_short(self):
    self.write_s2p(self.gain_short(self.dut.freq))

  def write_s2p_open(self):
    self.write_s2p(self.gain_open(self.dut.freq))
class Scanner(QMainWindow, Ui_Scanner):
  def __init__(self):
    super(Scanner, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variable
    self.idle = True
    # number of samples to show on the plot
    self.size = 512 * 512
    self.freq = 143.0
    # buffer and offset for the incoming samples
    self.buffer = bytearray(8 * self.size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.int32)
    # create figure
    figure = Figure()
    figure.set_facecolor('none')
    self.axes = figure.add_subplot(111)
    self.canvas = FigureCanvas(figure)
    self.plotLayout.addWidget(self.canvas)
    self.axes.axis((0.0, 512.0, 0.0, 512.0))
    x, y = np.meshgrid(np.linspace(0.0, 512.0, 513), np.linspace(0.0, 512.0, 513))
    z = x / 512.0 + y * 0.0
    self.mesh = self.axes.pcolormesh(x, y, z, cmap = cm.plasma)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # remove subplots action
    actions = self.toolbar.actions()
    if int(matplotlib.__version__[0]) < 2:
      self.toolbar.removeAction(actions[7])
    else:
      self.toolbar.removeAction(actions[6])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.connectButton.clicked.connect(self.start)
    self.scanButton.clicked.connect(self.scan)
    self.periodValue.valueChanged.connect(self.set_period)
    self.trgtimeValue.valueChanged.connect(self.set_trgtime)
    self.trginvCheck.stateChanged.connect(self.set_trginv)
    self.shdelayValue.valueChanged.connect(self.set_shdelay)
    self.shtimeValue.valueChanged.connect(self.set_shtime)
    self.shinvCheck.stateChanged.connect(self.set_shinv)
    self.acqdelayValue.valueChanged.connect(self.set_acqdelay)
    self.samplesValue.valueChanged.connect(self.set_samples)
    self.pulsesValue.valueChanged.connect(self.set_pulses)
    # create timers
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)
    self.meshTimer = QTimer(self)
    self.meshTimer.timeout.connect(self.update_mesh)
    # set default values
    self.periodValue.setValue(200.0)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.socket.abort()
    self.offset = 0
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.scanButton.setEnabled(True)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_period(self.periodValue.value())
    self.set_trgtime(self.trgtimeValue.value())
    self.set_trginv(self.trginvCheck.checkState())
    self.set_shdelay(self.shdelayValue.value())
    self.set_shtime(self.shtimeValue.value())
    self.set_shinv(self.shinvCheck.checkState())
    self.set_acqdelay(self.acqdelayValue.value())
    self.set_samples(self.samplesValue.value())
    self.set_pulses(self.pulsesValue.value())
    # start pulse generators
    self.socket.write(struct.pack('<I', 9<<28))
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.scanButton.setEnabled(True)

  def read_data(self):
    size = self.socket.bytesAvailable()
    if self.offset + size < 8 * self.size:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.meshTimer.stop()
      self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset)
      self.offset = 0
      self.update_mesh()
      self.scanButton.setEnabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'Scanner', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'Scanner', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_period(self, value):
    # set maximum delays and times to half period
    maximum = int(value * 5.0 + 0.5) / 10.0
    self.trgtimeValue.setMaximum(maximum)
    self.shdelayValue.setMaximum(maximum)
    self.shtimeValue.setMaximum(maximum)
    self.acqdelayValue.setMaximum(maximum)
    # set maximum number of samples per pulse
    maximum = int(value * 500.0 + 0.5) / 10.0
    if maximum > 256.0: maximum = 256.0
    self.samplesValue.setMaximum(maximum)
    shdelay = value * 0.25
    samples = value * 0.5
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(value * self.freq)))

  def set_trgtime(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | int(value * self.freq)))

  def set_trginv(self, checked):
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(checked == Qt.Checked)))

  def set_shdelay(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 3<<28 | int(value * self.freq)))

  def set_shtime(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value * self.freq)))

  def set_shinv(self, checked):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(checked == Qt.Checked)))

  def set_acqdelay(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 6<<28 | int(value * self.freq)))

  def set_samples(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 7<<28 | int(value)))

  def set_pulses(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 8<<28 | int(value)))

  def scan(self):
    if self.idle: return
    self.scanButton.setEnabled(False)
    self.data[:] = np.zeros(2 * 512 * 512, np.int32)
    self.update_mesh()
    self.socket.write(struct.pack('<I', 10<<28))
    self.meshTimer.start(1000)

  def update_mesh(self):
    self.mesh.set_array(self.data[0::2]/(self.samplesValue.value() * self.pulsesValue.value() * 8192.0))
    self.canvas.draw()
Exemple #16
0
class Scanner(QMainWindow, Ui_Scanner):
    def __init__(self):
        super(Scanner, self).__init__()
        self.setupUi(self)
        # IP address validator
        rx = QRegExp(
            '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
        )
        self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
        # state variable
        self.idle = True
        # number of samples to show on the plot
        self.size = 512 * 512
        self.freq = 143.0
        # buffer and offset for the incoming samples
        self.buffer = bytearray(8 * self.size)
        self.offset = 0
        self.data = np.frombuffer(self.buffer, np.int32)
        # create figure
        figure = Figure()
        figure.set_facecolor('none')
        self.axes = figure.add_subplot(111)
        self.canvas = FigureCanvas(figure)
        self.plotLayout.addWidget(self.canvas)
        self.axes.axis((0.0, 512.0, 0.0, 512.0))
        x, y = np.meshgrid(np.linspace(0.0, 512.0, 513),
                           np.linspace(0.0, 512.0, 513))
        z = x / 512.0 + y * 0.0
        self.mesh = self.axes.pcolormesh(x, y, z, cmap=cm.plasma)
        # create navigation toolbar
        self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
        # remove subplots action
        actions = self.toolbar.actions()
        if int(matplotlib.__version__[0]) < 2:
            self.toolbar.removeAction(actions[7])
        else:
            self.toolbar.removeAction(actions[6])
        self.plotLayout.addWidget(self.toolbar)
        # create TCP socket
        self.socket = QTcpSocket(self)
        self.socket.connected.connect(self.connected)
        self.socket.readyRead.connect(self.read_data)
        self.socket.error.connect(self.display_error)
        # connect signals from buttons and boxes
        self.connectButton.clicked.connect(self.start)
        self.scanButton.clicked.connect(self.scan)
        self.periodValue.valueChanged.connect(self.set_period)
        self.trgtimeValue.valueChanged.connect(self.set_trgtime)
        self.trginvCheck.stateChanged.connect(self.set_trginv)
        self.shdelayValue.valueChanged.connect(self.set_shdelay)
        self.shtimeValue.valueChanged.connect(self.set_shtime)
        self.shinvCheck.stateChanged.connect(self.set_shinv)
        self.acqdelayValue.valueChanged.connect(self.set_acqdelay)
        self.samplesValue.valueChanged.connect(self.set_samples)
        self.pulsesValue.valueChanged.connect(self.set_pulses)
        # create timers
        self.startTimer = QTimer(self)
        self.startTimer.timeout.connect(self.timeout)
        self.meshTimer = QTimer(self)
        self.meshTimer.timeout.connect(self.update_mesh)
        # set default values
        self.periodValue.setValue(200.0)

    def start(self):
        if self.idle:
            self.connectButton.setEnabled(False)
            self.socket.connectToHost(self.addrValue.text(), 1001)
            self.startTimer.start(5000)
        else:
            self.stop()

    def stop(self):
        self.idle = True
        self.socket.abort()
        self.offset = 0
        self.connectButton.setText('Connect')
        self.connectButton.setEnabled(True)
        self.scanButton.setEnabled(True)

    def timeout(self):
        self.display_error('timeout')

    def connected(self):
        self.startTimer.stop()
        self.idle = False
        self.set_period(self.periodValue.value())
        self.set_trgtime(self.trgtimeValue.value())
        self.set_trginv(self.trginvCheck.checkState())
        self.set_shdelay(self.shdelayValue.value())
        self.set_shtime(self.shtimeValue.value())
        self.set_shinv(self.shinvCheck.checkState())
        self.set_acqdelay(self.acqdelayValue.value())
        self.set_samples(self.samplesValue.value())
        self.set_pulses(self.pulsesValue.value())
        # start pulse generators
        self.socket.write(struct.pack('<I', 9 << 28))
        self.connectButton.setText('Disconnect')
        self.connectButton.setEnabled(True)
        self.scanButton.setEnabled(True)

    def read_data(self):
        size = self.socket.bytesAvailable()
        if self.offset + size < 8 * self.size:
            self.buffer[self.offset:self.offset +
                        size] = self.socket.read(size)
            self.offset += size
        else:
            self.meshTimer.stop()
            self.buffer[self.offset:8 *
                        self.size] = self.socket.read(8 * self.size -
                                                      self.offset)
            self.offset = 0
            self.update_mesh()
            self.scanButton.setEnabled(True)

    def display_error(self, socketError):
        self.startTimer.stop()
        if socketError == 'timeout':
            QMessageBox.information(self, 'Scanner',
                                    'Error: connection timeout.')
        else:
            QMessageBox.information(self, 'Scanner',
                                    'Error: %s.' % self.socket.errorString())
        self.stop()

    def set_period(self, value):
        # set maximum delays and times to half period
        maximum = int(value * 5.0 + 0.5) / 10.0
        self.trgtimeValue.setMaximum(maximum)
        self.shdelayValue.setMaximum(maximum)
        self.shtimeValue.setMaximum(maximum)
        self.acqdelayValue.setMaximum(maximum)
        # set maximum number of samples per pulse
        maximum = int(value * 500.0 + 0.5) / 10.0
        if maximum > 256.0: maximum = 256.0
        self.samplesValue.setMaximum(maximum)
        shdelay = value * 0.25
        samples = value * 0.5
        if self.idle: return
        self.socket.write(struct.pack('<I', 0 << 28 | int(value * self.freq)))

    def set_trgtime(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 1 << 28 | int(value * self.freq)))

    def set_trginv(self, checked):
        if self.idle: return
        self.socket.write(
            struct.pack('<I', 2 << 28 | int(checked == Qt.Checked)))

    def set_shdelay(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 3 << 28 | int(value * self.freq)))

    def set_shtime(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 4 << 28 | int(value * self.freq)))

    def set_shinv(self, checked):
        if self.idle: return
        self.socket.write(
            struct.pack('<I', 5 << 28 | int(checked == Qt.Checked)))

    def set_acqdelay(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 6 << 28 | int(value * self.freq)))

    def set_samples(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 7 << 28 | int(value)))

    def set_pulses(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 8 << 28 | int(value)))

    def scan(self):
        if self.idle: return
        self.scanButton.setEnabled(False)
        self.data[:] = np.zeros(2 * 512 * 512, np.int32)
        self.update_mesh()
        self.socket.write(struct.pack('<I', 10 << 28))
        self.meshTimer.start(1000)

    def update_mesh(self):
        self.mesh.set_array(
            self.data[0::2] /
            (self.samplesValue.value() * self.pulsesValue.value() * 8192.0))
        self.canvas.draw()
Exemple #17
0
class PulsedNMR(QMainWindow, Ui_PulsedNMR):
  rates = {0:25.0e3, 1:50.0e3, 2:125.0e3, 3:250.0e3, 4:500.0e3, 5:1250.0e3}
  def __init__(self):
    super(PulsedNMR, self).__init__()
    self.setupUi(self)
    self.rateValue.addItems(['25', '50', '125', '250', '500', '1250'])
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|rp-[0-9A-Fa-f]{6}\.local$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variable
    self.idle = True
    # number of samples to show on the plot
    self.size = 50000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(16 * self.size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.int32)
    # create figure
    figure = Figure()
    figure.set_facecolor('none')
    self.axes = figure.add_subplot(111)
    self.canvas = FigureCanvas(figure)
    self.plotLayout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # remove subplots action
    actions = self.toolbar.actions()
    if int(matplotlib.__version__[0]) < 2:
      self.toolbar.removeAction(actions[7])
    else:
      self.toolbar.removeAction(actions[6])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.startButton.clicked.connect(self.start)
    self.freqValue.valueChanged.connect(self.set_freq)
    self.deltaValue.valueChanged.connect(self.set_delta)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    # set rate
    self.rateValue.setCurrentIndex(3)
    # create timer for the repetitions
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)
    self.timer = QTimer(self)
    self.timer.timeout.connect(self.start_sequence)

  def start(self):
    if self.idle:
      self.startButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.timer.stop()
    self.socket.abort()
    self.offset = 0
    self.startButton.setText('Start')
    self.startButton.setEnabled(True)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_freq(self.freqValue.value())
    self.set_rate(self.rateValue.currentIndex())
    self.start_sequence()
    self.timer.start(self.deltaValue.value())
    self.startButton.setText('Stop')
    self.startButton.setEnabled(True)

  def read_data(self):
    size = self.socket.bytesAvailable()
    if self.offset + size < 16 * self.size:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.buffer[self.offset:16 * self.size] = self.socket.read(16 * self.size - self.offset)
      self.offset = 0
      # plot the signal envelope
      self.curve.set_ydata(np.abs(self.data.astype(np.float32).view(np.complex64)[0::2] / (1 << 30)))
      self.canvas.draw()

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'PulsedNMR', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'PulsedNMR', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_freq(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<Q', 0<<60 | int(1.0e6 * value)))
    self.socket.write(struct.pack('<Q', 1<<60 | int(1.0e6 * value)))

  def set_rate(self, index):
    # time axis
    rate = float(PulsedNMR.rates[index])
    time = np.linspace(0.0, (self.size - 1) * 1000.0 / rate, self.size)
    # reset toolbar
    self.toolbar.home()
    self.toolbar.update()
    # reset plot
    self.axes.clear()
    self.axes.grid()
    # plot zeros and get store the returned Line2D object
    self.curve, = self.axes.plot(time, np.zeros(self.size))
    x1, x2, y1, y2 = self.axes.axis()
    # set y axis limits
    self.axes.axis((x1, x2, -0.1, 1.1))
    self.axes.set_xlabel('time, ms')
    self.canvas.draw()
    if self.idle: return
    self.socket.write(struct.pack('<Q', 2<<60 | int(125.0e6 / rate / 2)))

  def set_delta(self, value):
    if self.idle: return
    self.timer.stop()
    self.timer.start(value)

  def clear_pulses(self):
    if self.idle: return
    self.socket.write(struct.pack('<Q', 7<<60))

  def add_delay(self, width):
    if self.idle: return
    self.socket.write(struct.pack('<Q', 8<<60 | int(width - 4)))

  def add_pulse(self, level, phase, width):
    if self.idle: return
    self.socket.write(struct.pack('<Q', 8<<60 | int(width)))
    self.socket.write(struct.pack('<Q', 9<<60 | int(phase << 16 | level)))

  def start_sequence(self):
    if self.idle: return
    awidth = 125 * self.awidthValue.value()
    bwidth = 125 * self.bwidthValue.value()
    delay = 125 * self.delayValue.value()
    size = self.size
    self.clear_pulses()
    self.add_pulse(32766, 0, awidth)
    self.add_delay(delay)
    self.add_pulse(32766, 0, bwidth)
    self.socket.write(struct.pack('<Q', 10<<60 | int(size)))
Exemple #18
0
class TcpS(QDialog, Ui_TcpServer):
    """
    文件传输服务器
    """

    sendFileName = pyqtSignal(str)

    def __init__(self, parent=None):
        """
        一些初始设置
        """
        super(TcpS, self).__init__(parent)
        self.setupUi(self)
        self.payloadSize = 64 * 1024
        # 读取数据64KB

        self.totalBytes = 0
        # 总大小

        self.bytesWritten = 0
        # 保存的数据

        self.bytesToWrite = 0
        # 每次减少连接写的数据量大小

        self.theFileName = ""
        # 文件名(不含路径)

        self.fileName = ""
        # 文件全名

        self.localFile = QFile()
        self.outBlock = QByteArray()
        # QByteArray()的对象,即字节数组

        self.time = QTime()
        self.initServer()

    def initServer(self):
        """
        网络设置初始化
        """
        self.tcpPort = 7788
        # 指定了TCP端口为7788

        self.tcpServer = QTcpServer(self)
        self.clientConnection = QTcpSocket(self)
        # 创建一个Tcp服务器和一个Tcp套接字

        self.tcpServer.newConnection.connect(self.sendMessage)
        # 当有新的连接来的时候发出newConnection信号,我们连接到sendMessage()函数。

        self.serverStatuslabel.setText("请选择要传送的文件")
        self.progressBar.reset()
        self.serverOpenBtn.setEnabled(True)
        self.serverSendBtn.setEnabled(False)
        self.tcpServer.close()
        # 显示我们开始创建的对话框,打开按钮是可用的,发送按钮是不可用的,进度条复位,先关闭服务器。

    def refused(self):
        """
        对端拒绝接收文件,主程序会调用服务器的refused()函数,关闭服务器。
        """
        self.tcpServer.close()
        self.serverStatuslabel.setText("对方拒绝接收")

    def closeEvent(self, event):
        """
        关闭事件
        """
        self.on_serverCloseBtn_clicked()
        # 产生关闭事件,直接调用关闭窗口按钮函数。

    def sendMessage(self):
        """
        发送文件
        """
        self.serverSendBtn.setEnabled(False)
        # 发送按钮不可用

        self.clientConnection = self.tcpServer.nextPendingConnection()
        # self.clientConnection作为连接的QTcpSocket对象返回下一个挂起的连接。

        self.clientConnection.bytesWritten.connect(self.updateClientProgress)
        # 当连接中每次将数据有效载荷写入设备的当前写通道时,都会发出此信号。在此有效负载中写入的数据量为字节数。

        self.serverStatuslabel.setText("开始传送文件 {} !".format(self.theFileName))

        self.localFile = QFile(self.fileName)
        if not (self.localFile.open(QFile.ReadOnly)):
            errorMsg = "无法读取文件 {}:\n {}".format(self.fileName,
                                                self.localFile.errorString())
            QMessageBox.warning(self, "应用程序", errorMsg)
            return
        # 尝试打开文件,要是存在问题就报错。

        self.serverCloseBtn.setText("取消")

        self.totalBytes = self.localFile.size()
        # 记录一下需要传输的文件大小。单位:字节

        sendOut = QDataStream(self.outBlock, QIODevice.WriteOnly)
        # 这里的self.outBlock是QByteArray()的对象,即字节数组;QIODevice的模式为WriteOnly

        sendOut.setVersion(QDataStream.Qt_5_4)
        # 设定QDataStream的版本为Qt_5_4

        self.time.start()
        # 开始计时

        currentFile = self.fileName.split("/")[-1]
        # 传输的文件名

        sendOut.writeInt64(0)
        sendOut.writeInt64(0)
        sendOut.writeQString(currentFile)
        self.totalBytes += self.outBlock.size()
        # 在sendOut中写入文件名以及文件名和文件的大小,大小都是以字节为单位的。

        sendOut.device().seek(0)
        sendOut.writeInt64(self.totalBytes)
        sendOut.writeInt64(self.outBlock.size() - 2)
        # QIODevice读写位置移动到0。然后分别写入总的大小和文件名大小。

        self.bytesToWrite = self.totalBytes - self.clientConnection.write(
            self.outBlock)
        # 待传输文件的大小。

        self.outBlock.resize(0)
        # outBlock清零。

    def updateClientProgress(self, numBytes):
        """
        发送进度显示
        """
        qApp.processEvents()
        # 长时间工作用,以免窗口假死

        self.bytesWritten += numBytes
        if self.bytesWritten > 0:
            self.block = self.localFile.read(
                min(self.bytesToWrite, self.payloadSize))
            self.bytesToWrite -= self.clientConnection.write(self.block)
        else:
            self.localFile.close()
        # 当我们待写入的字节数大于0时,我们每次读取的数据都是小于等于self.payloadSize的,这个self.payloadSize我们定义是64KB。
        # self.bytesToWrite每次减少连接写的数据量大小。
        # 要是待写入的字节数小于等于0,则关闭文件。

        byteSent = self.bytesWritten / (1024 * 1024)
        # 已经写了多少文件
        useTime = self.time.elapsed() / 1000
        # 传输用了多长时间
        speed = self.bytesWritten / useTime / (1024 * 1024)
        # 传输速度
        total = self.totalBytes / (1024 * 1024)
        # 总大小
        left = (total - byteSent) / speed
        # 表示剩余时间

        if byteSent < 0.01:
            byteSent = self.bytesWritten / 1024
            speed = self.bytesWritten / useTime / 1024
            total = self.totalBytes / 1024
            if left > 0:
                sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format(
                    byteSent, speed, total, useTime, left)
            else:
                sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 用时:{3:.1f}秒\n".format(
                    byteSent, speed, total, useTime)
        else:
            if left > 0:
                sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format(
                    byteSent, speed, total, useTime, left)
            else:
                sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 用时:{3:.1f}秒\n".format(
                    byteSent, speed, total, useTime)

        self.progressBar.setMaximum(total)
        self.progressBar.setValue(byteSent)

        if self.bytesWritten == self.totalBytes:
            self.serverCloseBtn.setText("关闭")
        # 进度条显示的方式,以及当传输的字节数等于总的字节数的时候,按钮就显示关闭。

        self.serverStatuslabel.setText(sendInfo)

    @pyqtSlot()
    def on_serverOpenBtn_clicked(self):
        """
        打开文件准备发送
        """
        self.fileName = QFileDialog.getOpenFileName(self, '打开文件', './')[0]
        if self.fileName:
            self.theFileName = self.fileName.split("/")[-1]
            self.serverStatuslabel.setText("要传送的文件为:{}".format(
                self.theFileName))
            self.serverSendBtn.setEnabled(True)
            self.serverOpenBtn.setEnabled(False)

    @pyqtSlot()
    def on_serverSendBtn_clicked(self):
        """
        发送文件,等待接收
        """
        if not (self.tcpServer.listen(QHostAddress.Any, self.tcpPort)):
            errorMsg = self.tcpServer.errorString()
            QMessageBox.warning(self, "错误", "发送失败:\n {}".format(errorMsg))
            self.TcpServer.close()
            return

        self.serverStatuslabel.setText("等待对方接收... ...")
        self.serverSendBtn.setEnabled(False)
        self.sendFileName.emit(self.theFileName)

    @pyqtSlot()
    def on_serverCloseBtn_clicked(self):
        """
        取消或者关闭
        """
        if self.tcpServer.isListening():
            self.tcpServer.close()
            if self.localFile.isOpen():
                self.localFile.close()
            self.clientConnection.abort()

        if self.serverCloseBtn.text() == "取消":
            self.serverCloseBtn.setText("关闭")
        else:
            self.close()
            self.serverOpenBtn.setEnabled(True)
            self.serverSendBtn.setEnabled(False)
            self.progressBar.reset()
            self.totalBytes = 0
            self.bytesWritten = 0
            self.bytesToWrite = 0
            self.serverStatuslabel.setText("请选择要传送的文件")
Exemple #19
0
class Crossing(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Výroba ovládacích prvků
        self.connectButton = QPushButton(self, text="Start")
        self.connectButton.clicked.connect(self.connect)

        self.disconnectButton = QPushButton(self, text="Stop")
        self.disconnectButton.clicked.connect(self.disconnect)

        # Rozložení ovládacích prvků
        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.connectButton)
        self.layout.addWidget(self.disconnectButton)

        # Příprava TCP socketu
        self.socket = QTcpSocket(self)
        self.socket.readyRead.connect(self.read)
        self.socket.connected.connect(self.connected)
        self.readBuffer = bytearray()

        self.travellers = {}

        # Zobrazení
        self.setLayout(self.layout)
        self.show()

    def disconnect(self):
        self.socket.write("BYE\n".encode())

    def connect(self):
        # Nejdřív se odpoj,
        # pokud už spojení běží
        self.socket.abort()

        # A znovu se připoj
        self.socket.connectToHost("ksp.mff.cuni.cz", 48888)

    def connected(self):
        # Pozdravíme server
        self.socket.write("HELLO\n".encode())

    def read(self):
        # Přečteme všechno, co jsme dostali
        while self.socket.bytesAvailable() > 0:
            self.readBuffer += self.socket.read(128)

        # Rozdělíme na řádky
        lines = self.readBuffer.split(b"\n")

        # Zbytek uložíme na příště
        self.readBuffer = lines.pop()

        # Zpracujeme řádky, které dorazily
        for l in lines:
            stripped = l.decode().rstrip()
            args = stripped.split(" ")
            travellerType = args.pop(0)
            argmap = dict(map(lambda x: x.split("="), args))

            if travellerType == "CAR":
                self.addTraveller(Car(**argmap))
            elif travellerType == "PEDESTRIAN":
                self.addTraveller(Pedestrian(**argmap))

    def addTraveller(self, traveller):
        # Uložíme si cestovatele
        self.travellers[traveller.id] = traveller

        # Nechť cestovatel vstoupí do oblasti
        traveller.start(self)

    def sendBack(self, traveller):
        # Cestovatel opouští sledovanou oblast
        self.travellers[traveller.id] = None

        # Vrátíme cestovatele serveru
        text = str(traveller) + "\n"
        self.socket.write(text.encode())
Exemple #20
0
class VNA(QMainWindow, Ui_VNA):
  graphs = ['open', 'short', 'load', 'dut', 'smith', 'imp', 'swr', 'gamma', 'rl', 'gain_short', 'gain_open']

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variables
    self.idle = True
    self.reading = False
    self.auto = False
    # sweep parameters
    self.sweep_start = 10
    self.sweep_stop = 60000
    self.sweep_size = 6000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(16 * 32768)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    # create measurements
    self.open = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.short = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.load = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.dut = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.mode = 'open'
    # create figures
    self.tabs = {}
    for i in range(len(self.graphs)):
      layout = getattr(self, '%sLayout' % self.graphs[i])
      self.tabs[i] = FigureTab(layout, self.open, self.short, self.load, self.dut)
    # configure widgets
    self.rateValue.addItems(['10000', '5000', '1000', '500', '100', '50', '10', '5', '1'])
    self.rateValue.lineEdit().setReadOnly(True)
    self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
    for i in range(self.rateValue.count()):
      self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
    self.set_enabled(False)
    # read settings
    settings = QSettings('vna.ini', QSettings.IniFormat)
    self.read_cfg_settings(settings)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from widgets
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(partial(self.sweep, 'open'))
    self.shortSweep.clicked.connect(partial(self.sweep, 'short'))
    self.loadSweep.clicked.connect(partial(self.sweep, 'load'))
    self.singleSweep.clicked.connect(partial(self.sweep, 'dut'))
    self.autoSweep.clicked.connect(self.sweep_auto)
    self.stopSweep.clicked.connect(self.cancel)
    self.csvButton.clicked.connect(self.write_csv)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.s2pshortButton.clicked.connect(self.write_s2p_short)
    self.s2popenButton.clicked.connect(self.write_s2p_open)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    self.corrValue.valueChanged.connect(self.set_corr)
    self.levelValue.valueChanged.connect(self.set_level)
    self.tabWidget.currentChanged.connect(self.update_tab)
    # create timers
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)
    self.sweepTimer = QTimer(self)
    self.sweepTimer.timeout.connect(self.sweep_timeout)

  def set_enabled(self, enabled):
    widgets = [self.corrValue, self.rateValue, self.levelValue, self.sizeValue, self.stopValue, self.startValue, self.openSweep, self.shortSweep, self.loadSweep, self.singleSweep, self.autoSweep]
    for entry in widgets:
      entry.setEnabled(enabled)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.cancel()
    self.socket.abort()
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.set_enabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_rate(self.rateValue.currentIndex())
    self.set_corr(self.corrValue.value())
    self.set_level(self.levelValue.value())
    self.set_gpio(1)
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.set_enabled(True)

  def read_data(self):
    while(self.socket.bytesAvailable() > 0):
      if not self.reading:
        self.socket.readAll()
        return
      size = self.socket.bytesAvailable()
      self.progressBar.setValue((self.offset + size) / 16)
      limit = 16 * self.sweep_size
      if self.offset + size < limit:
        self.buffer[self.offset:self.offset + size] = self.socket.read(size)
        self.offset += size
      else:
        self.buffer[self.offset:limit] = self.socket.read(limit - self.offset)
        adc1 = self.data[0::2]
        adc2 = self.data[1::2]
        attr = getattr(self, self.mode)
        start = self.sweep_start
        stop = self.sweep_stop
        size = self.sweep_size
        attr.freq = np.linspace(start, stop, size)
        attr.data = adc1[0:size].copy()
        self.update_tab()
        self.reading = False
        if not self.auto:
          self.progressBar.setValue(0)
          self.set_enabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value

  def set_stop(self, value):
    self.sweep_stop = value

  def set_size(self, value):
    self.sweep_size = value

  def set_rate(self, value):
    if self.idle: return
    rate = [5, 10, 50, 100, 500, 1000, 5000, 10000, 50000][value]
    self.socket.write(struct.pack('<I', 3<<28 | int(rate)))

  def set_corr(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value)))

  def set_level(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(32766 * np.power(10.0, value / 20.0))))
    self.socket.write(struct.pack('<I', 6<<28 | int(0)))

  def set_gpio(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 7<<28 | int(value)))

  def sweep(self, mode):
    if self.idle: return
    self.set_enabled(False)
    self.mode = mode
    self.offset = 0
    self.reading = True
    self.socket.write(struct.pack('<I', 0<<28 | int(self.sweep_start * 1000)))
    self.socket.write(struct.pack('<I', 1<<28 | int(self.sweep_stop * 1000)))
    self.socket.write(struct.pack('<I', 2<<28 | int(self.sweep_size)))
    self.socket.write(struct.pack('<I', 8<<28))
    self.progressBar.setMinimum(0)
    self.progressBar.setMaximum(self.sweep_size)
    self.progressBar.setValue(0)

  def cancel(self):
    self.sweepTimer.stop()
    self.auto = False
    self.reading = False
    self.socket.write(struct.pack('<I', 9<<28))
    self.progressBar.setValue(0)
    self.set_enabled(True)

  def sweep_auto(self):
    self.auto = True
    self.sweepTimer.start(100)

  def sweep_timeout(self):
    if not self.reading:
      self.sweep('dut')

  def update_tab(self):
    index = self.tabWidget.currentIndex()
    self.tabs[index].update(self.graphs[index])

  def write_cfg(self):
    dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.selectFile('vna.ini')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.write_cfg_settings(settings)

  def read_cfg(self):
    dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.selectFile('vna.ini')
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.read_cfg_settings(settings)
      window.update_tab()

  def write_cfg_settings(self, settings):
    settings.setValue('addr', self.addrValue.text())
    settings.setValue('rate', self.rateValue.currentIndex())
    settings.setValue('corr', self.corrValue.value())
    settings.setValue('level', self.levelValue.value())
    settings.setValue('open_start', int(self.open.freq[0]))
    settings.setValue('open_stop', int(self.open.freq[-1]))
    settings.setValue('open_size', self.open.freq.size)
    settings.setValue('short_start', int(self.short.freq[0]))
    settings.setValue('short_stop', int(self.short.freq[-1]))
    settings.setValue('short_size', self.short.freq.size)
    settings.setValue('load_start', int(self.load.freq[0]))
    settings.setValue('load_stop', int(self.load.freq[-1]))
    settings.setValue('load_size', self.load.freq.size)
    settings.setValue('dut_start', int(self.dut.freq[0]))
    settings.setValue('dut_stop', int(self.dut.freq[-1]))
    settings.setValue('dut_size', self.dut.freq.size)
    for i in range(len(FigureTab.cursors)):
      settings.setValue('cursor_%d' % i, FigureTab.cursors[i])
    data = self.open.data
    for i in range(self.open.freq.size):
      settings.setValue('open_real_%d' % i, float(data.real[i]))
      settings.setValue('open_imag_%d' % i, float(data.imag[i]))
    data = self.short.data
    for i in range(self.short.freq.size):
      settings.setValue('short_real_%d' % i, float(data.real[i]))
      settings.setValue('short_imag_%d' % i, float(data.imag[i]))
    data = self.load.data
    for i in range(self.load.freq.size):
      settings.setValue('load_real_%d' % i, float(data.real[i]))
      settings.setValue('load_imag_%d' % i, float(data.imag[i]))
    data = self.dut.data
    for i in range(self.dut.freq.size):
      settings.setValue('dut_real_%d' % i, float(data.real[i]))
      settings.setValue('dut_imag_%d' % i, float(data.imag[i]))

  def read_cfg_settings(self, settings):
    self.addrValue.setText(settings.value('addr', '192.168.1.100'))
    self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int))
    self.corrValue.setValue(settings.value('corr', 0, type = int))
    self.levelValue.setValue(settings.value('level', 0, type = int))
    open_start = settings.value('open_start', 10, type = int)
    open_stop = settings.value('open_stop', 60000, type = int)
    open_size = settings.value('open_size', 6000, type = int)
    short_start = settings.value('short_start', 10, type = int)
    short_stop = settings.value('short_stop', 60000, type = int)
    short_size = settings.value('short_size', 6000, type = int)
    load_start = settings.value('load_start', 10, type = int)
    load_stop = settings.value('load_stop', 60000, type = int)
    load_size = settings.value('load_size', 6000, type = int)
    dut_start = settings.value('dut_start', 10, type = int)
    dut_stop = settings.value('dut_stop', 60000, type = int)
    dut_size = settings.value('dut_size', 6000, type = int)
    self.startValue.setValue(dut_start)
    self.stopValue.setValue(dut_stop)
    self.sizeValue.setValue(dut_size)
    for i in range(len(FigureTab.cursors)):
      FigureTab.cursors[i] = settings.value('cursor_%d' % i, FigureTab.cursors[i], type = int)
    self.open.freq = np.linspace(open_start, open_stop, open_size)
    self.open.data = np.zeros(open_size, np.complex64)
    for i in range(open_size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open.data[i] = real + 1.0j * imag
    self.short.freq = np.linspace(short_start, short_stop, short_size)
    self.short.data = np.zeros(short_size, np.complex64)
    for i in range(short_size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short.data[i] = real + 1.0j * imag
    self.load.freq = np.linspace(load_start, load_stop, load_size)
    self.load.data = np.zeros(load_size, np.complex64)
    for i in range(load_size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load.data[i] = real + 1.0j * imag
    self.dut.freq = np.linspace(dut_start, dut_stop, dut_size)
    self.dut.data = np.zeros(dut_size, np.complex64)
    for i in range(dut_size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut.data[i] = real + 1.0j * imag

  def write_csv(self):
    dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
    dialog.setDefaultSuffix('csv')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      f = self.dut.freq
      o = np.interp(f, self.open.freq, self.open.data, period = self.open.period)
      s = np.interp(f, self.short.freq, self.short.data, period = self.short.period)
      l = np.interp(f, self.load.freq, self.load.data, period = self.load.period)
      d = self.dut.data
      fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n')
      for i in range(f.size):
        fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (f[i] * 1000, o.real[i], o.imag[i], s.real[i], s.imag[i], l.real[i], l.imag[i], d.real[i], d.imag[i]))
      fh.close()

  def write_s1p(self):
    dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
    dialog.setDefaultSuffix('s1p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      freq = self.dut.freq
      gamma = self.gamma(freq)
      fh.write('# GHz S MA R 50\n')
      for i in range(freq.size):
        fh.write('0.0%.8d   %8.6f %7.2f\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
      fh.close()

  def write_s2p(self, gain):
    dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
    dialog.setDefaultSuffix('s2p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      freq = self.dut.freq
      gamma = self.gamma(freq)
      fh.write('# GHz S MA R 50\n')
      for i in range(freq.size):
        fh.write('0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True)))
      fh.close()

  def write_s2p_short(self):
    self.write_s2p(self.gain_short(self.dut.freq))

  def write_s2p_open(self):
    self.write_s2p(self.gain_open(self.dut.freq))
class Scanner_module():
    def __init__(self):
        self.xsize = 512
        self.ysize = 512
        self.size = self.xsize * self.ysize
        self.freq = 125.0
        self.period = 200
        self.trgtime = 100
        self.trginv = 0
        self.shdelay = 1.5
        self.shtime = 0.1
        self.shinv = 0
        self.acqdelay = 10
        self.samples = 32
        self.pulses = 2
        self.idle = True
        self.socket = QTcpSocket()
        self.socket.connected.connect(self.connected)
        self.socket.readyRead.connect(self.read_data)
        # self.socket.error.connect(self.display_error)

        X, Y = np.meshgrid(np.arange(self.xsize),np.arange(self.ysize))
        self.xco = X
        self.yco = Y
        self.buffer = bytearray(8 * self.xsize*self.ysize)
        self.data = np.frombuffer(self.buffer, np.int32)

    def ConnectIPAdress(self, ip):
        if self.idle:
            self.socket.connectToHost(ip, 1001)
            if self.socket.waitForConnected(1000):
                print ("Connected!")

        else:
            self.stop()

    def stop(self):
        self.idle = True
        self.socket.abort()
        self.offset = 0

    def connected(self):
        self.idle = False
        self.send_period(self.period)
        self.send_trgtime(self.trgtime)
        self.send_trginv(self.trginv)
        self.send_shdelay(self.shdelay)
        self.send_shtime(self.shtime)
        self.send_shinv(self.shinv)
        self.send_acqdelay(self.acqdelay)
        self.send_samples(self.samples)
        self.send_pulses(self.pulses)
        # start pulse generators
        self.socket.write(struct.pack('<I', 11 << 28))

    def set_coordinates(self):
        x = self.xco.flatten()
        y = self.yco.flatten()

        if self.idle: return
        self.socket.write(struct.pack('<I', 9 << 28))
        for i in range(x.size):
                xco = x[i]
                yco = y[i]
                value = (xco << 18) | (yco << 4)
                self.socket.write(struct.pack('<I', 10 << 28 | int(value)))

    def scan(self):
        if self.idle: return
        self.data[:] = np.zeros(2 * 512 * 512, np.int32)
        self.set_coordinates()
        self.socket.write(struct.pack('<I', 12 << 28))
        print('scan send')

    def read_data(self):
        size = self.socket.bytesAvailable()
        if self.offset + size < 8 * self.size:
            self.buffer[self.offset:self.offset + size] = self.socket.read(size)
            self.offset += size
        else:
            self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset)
            self.offset = 0

    def send_period(self, value):
        # value = self.period
        if self.idle: return
        self.socket.write(struct.pack('<I', 0 << 28 | int(value * self.freq)))
        print('period send')

    def send_trgtime(self, value):
        # value = self.trgtime
        if self.idle: return
        self.socket.write(struct.pack('<I', 1 << 28 | int(value * self.freq)))

    def send_trginv(self, checked):
        # checked = self.trginv
        if self.idle: return
        self.socket.write(struct.pack('<I', 2 << 28 | int(checked)))

    def send_shdelay(self, value):
        # value = self.shdelay
        if self.idle: return
        self.socket.write(struct.pack('<I', 3 << 28 | int(value * self.freq)))

    def send_shtime(self, value):
        # value = self.shtime
        if self.idle: return
        self.socket.write(struct.pack('<I', 4 << 28 | int(value * self.freq)))

    def send_shinv(self, checked):
        # checked = self.shinv
        if self.idle: return
        self.socket.write(struct.pack('<I', 5 << 28 | int(checked)))

    def send_acqdelay(self, value):
        # value = self.acqdelay
        if self.idle: return
        self.socket.write(struct.pack('<I', 6 << 28 | int(value * self.freq)))

    def send_samples(self, value):
        # value = self.samples
        if self.idle: return
        self.socket.write(struct.pack('<I', 7 << 28 | int(value)))

    def send_pulses(self, value):
        # value = self.pulses
        if self.idle: return
        self.socket.write(struct.pack('<I', 8 << 28 | int(value)))