Add real time channel display to PyQt

2019-09-19 06:20发布

-----EDIT # 1 ----- In the code box is my attempt at making this work, but I am unable to get my labels and text boxes to show in window... perhaps my Qgridlayout is wrong??? any help or direction would be great! thanks! ----END EDIT #1 ----

What I would like is to display the channels read from channel 1 through 8 below the matplotlib graph. The graph was easy (presuming what I did works) to embed and it refreshes every 5 seconds displaying the last 5 minutes of data. So, what I would like to have two rows to display all eight channels... something like below:

Channel 1: (RAW VALUE) Channel2: (RAW VALUE) .....
Channel 5: (RAW VALUE) Channel6: (RAW VALUE) .....

I am unsure how to have PyQt 'refresh' or 'fetch' the new values every 5 seconds.

Below is my code for what it does now,

#matplotlib and read/write aquisition
import Queue
import datetime as DT
import collections
import matplotlib.pyplot as plt
import numpy as np
import multiprocessing as mp
import time
import datetime
import os
import matplotlib.dates as mdates
import matplotlib.animation as animation
#ADC
from ABE_DeltaSigmaPi import DeltaSigma 
from ABE_helpers import ABEHelpers
#PyQt
from PyQt4 import QtGui, QtCore 
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

#ADC INFO
import sys
i2c_helper = ABEHelpers() 
bus = i2c_helper.get_smbus() 
adc = DeltaSigma(bus, 0x68, 0x69, 18)

#Rename file to date
base_dir = '/home/pi/Desktop/DATA'
ts = time.time()
filename_time = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d')
filename_base = os.path.join(base_dir, filename_time)
filename = '%s.txt' % filename_base

# you will want to change read_delay to 5000
read_delay = int(5000)    # in milliseconds 
write_delay = read_delay/1000.0  # in seconds 
window_size = 60
nlines = 8
datenums = collections.deque(maxlen=window_size)
ys = [collections.deque(maxlen=window_size) for i in range(nlines)]

#PyQt window to display readings
class Window(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.figure = plt.show()
        self.canvas = FigureCanvas(self.figure)

        #Labels
        self.channel1 = QtGui.QLabel('Channel 1:')
        self.channel2 = QtGui.QLabel('Channel 2:')
        self.channel3 = QtGui.QLabel('Channel 3:')
        self.channel4 = QtGui.QLabel('Channel 4:')
        self.channel5 = QtGui.QLabel('Channel 5:')
        self.channel6 = QtGui.QLabel('Channel 6:')
        self.channel7 = QtGui.QLabel('Channel 7:')
        self.channel8 = QtGui.QLabel('Channel 8:')

        #textboxes
        self.textbox1 = QtGui.QLineEdit()
        self.textbox2 = QtGui.QlineEdit()
        self.textbox3 = QtGui.QlineEdit()
        self.textbox4 = QtGui.QlineEdit()
        self.textbox5 = QtGui.QlineEdit()
        self.textbox6 = QtGui.QlineEdit()
        self.textbox7 = QtGui.QlineEdit()
        self.textbox8 = QtGui.QlineEdit()

        #timer to refresh textboxes
        def refreshtext(self):
            self.textbox1.setText(enumerate(row[1]))
            self.textbox2.setText(enumerate(row[2]))
            self.textbox3.setText(enumerate(row[3]))
            self.textbox4.setText(enumerate(row[4]))
            self.textbox5.setText(enumerate(row[5]))
            self.textbox6.setText(enumerate(row[6]))
            self.textbox7.setText(enumerate(row[7]))
            self.textbox8.setText(enumerate(row[8]))

        #Layout
        layout = QtGui.QGridLayout()
        layout.setAlignment(QtCore.Qt.AlignCenter)
        layout.addWidget(self.canvas,0,0,1,4)
        layout.addWidget(self.channel1,1,0,1,1)
        layout.addWidget(self.channel2,1,1,1,1)
        layout.addWidget(self.channel3,1,2,1,1)
        layout.addWidget(self.channel4,1,3,1,1)
        layout.addWidget(self.textbox1,2,0,1,1)
        layout.addWidget(self.textbox2,2,1,1,1)
        layout.addWidget(self.textbox3,2,2,1,1)
        layout.addWidget(self.textbox4,2,3,1,1)
        layout.addWidget(self.channel5,3,0,1,1)
        layout.addWidget(self.channel6,3,1,1,1)
        layout.addWidget(self.channel7,3,2,1,1)
        layout.addWidget(self.channel8,3,3,1,1)
        layout.addWidget(self.textbox5,4,0,1,1)
        layout.addWidget(self.textbox6,4,1,1,1)
        layout.addWidget(self.textbox7,4,2,1,1)
        layout.addWidget(self.textbox8,4,3,1,1)
        self.setLayout(layout)

def animate(i, queue):
    try:
        row = queue.get_nowait()
    except Queue.Empty:
        return
    datenums.append(mdates.date2num(row[0]))
    for i, y in enumerate(row[1:]):
        ys[i].append(y)
    for i, y in enumerate(ys):
        lines[i].set_data(datenums, y)
    ymin = min(min(y) for y in ys)
    ymax = max(max(y) for y in ys)
    xmin = min(datenums)
    xmax = max(datenums)
    if xmin < xmax:
        ax.set_xlim(xmin, xmax)
    ax.set_ylim(ymin, ymax)
    fig.canvas.draw()

def write_data(filename, queue):
    while True:
        delay1 = DT.datetime.now()
        row = []
        for i in range(nlines):
            # read from adc channels and print to screen
            channel = adc.read_voltage(i)
            row.append(channel)

        queue.put([delay1]+row)

        #print voltage variables to local file
        with open(filename, 'a') as DAQrecording:
            time1 = delay1.strftime('%Y-%m-%d')
            time2 = delay1.strftime('%H:%M:%S')
            row = [time1, time2] + row
            row = map(str, row)
            DAQrecording.write('{}\n'.format(', '.join(row)))

        #Delay until next 5 second interval
        delay2 = DT.datetime.now()
        difference = (delay2 - delay1).total_seconds()
        time.sleep(write_delay - difference)

def main():    
    global fig, ax, lines
    queue = mp.Queue()
    proc = mp.Process(target=write_data, args=(filename, queue))
    # terminate proc when main process ends
    proc.daemon = True
    # spawn the writer in a separate process
    proc.start()

    fig, ax = plt.subplots()
    xfmt = mdates.DateFormatter('%H:%M:%S')
    ax.xaxis.set_major_formatter(xfmt)
    # make matplotlib treat x-axis as times
    ax.xaxis_date()

    fig.autofmt_xdate(rotation=25)

    lines = []
    for i in range(nlines):
        line, = ax.plot([], [])
        lines.append(line)

    ani = animation.FuncAnimation(fig, animate, interval=read_delay, fargs=(queue,))

    app = QtGui.QApplication(sys.argv)
    win = Window()
    win.setWindowTitle('Real Time Data Aquisition')
    win.show()

    timer = QtCore.QTimer()
    timer.timeout.connect(self.refreshtext)
    timer.start(5000)

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

0条回答
登录 后发表回答