0

I am looking to use pyqt5 GUI to show live data from serial port and socketCAN port. I am new pyqt5 and GUI programming in general. I have done application reading that data in python script and recording data to file. Now I am looking to show that live data also in GUI.

I have tried to find good example of background worker sending data with QT signals to GUI, but have not found a good one.

My worker to read J1939 data to dict including spn and current value. I would like to pass signallist dictionary to pyqt5 gui. Dictionary includes two levels. First level is frame ID and under that is key - value pairs for EEC1 (frame) include engine_speed : value

import cantools
import can
import locale
import datetime
import csv
from pprint import pprint
from datetime import date
from datetime import datetime
from pathlib import Path
from time import sleep
from time import time
from threading import Timer




if __name__ == "__main__":

firstWritetime = 10
recordInterval = 1
recordLenght = 3600
fullMask = 0x1FFFFFFF
pgnMask = 0x00FFFF00
msgsToLog = [
    "EEC1",
    "ET",
    "LFE",
    "AMB",
    "EH",
    "DM1",
    "DPFC1",
]






canDB = cantools.database.load_file('/home/pi/source/PiCANlogger/StageVLogger.dbc')



J1939_filters = []
for x in msgsToLog:
    xMsg = canDB.get_message_by_name(x)
    J1939_filters.append({"can_id": xMsg.frame_id, "can_mask": fullMask})

#pprint(J1939_filters)    
J1939Bus = can.interface.Bus( bustype='socketcan', channel='can0', can_filters=J1939_filters)

while (True) :
    dt = datetime.today() 
    fileName = dt.strftime("%Y-%m-%d_%H:%M:%S")
    firstLineWrite = False
    currRecordLenght = 0
    startTime = time()
    lastRecordTime = startTime
    currentTime = time()
    signalList = {}
    timeStamp = {'TimeStamp': time()}
    signalList.update(timeStamp)
    #print("uloin")


    while (True) :
        #print("sisin")
        recvMsg = J1939Bus.recv(1)
        latestSigs = canDB.decode_message(recvMsg.arbitration_id, recvMsg.data)
        #pprint(latestSigs)
        signalList.update(latestSigs)
        signalList.update(timeStamp)
        pprint(signalList)
        if time() - startTime > firstWritetime and firstLineWrite == False :
            #firstLineWrite = True
        currentTime = time()
        currTimeStamp= {'TimeStamp': currentTime}
        signalList.update(currTimeStamp)
        if currentTime - lastRecordTime > recordInterval and firstLineWrite == True :
            #insertRowtoFile(signalList, fileName)
            lastRecordTime = currentTime
            currRecordLenght += 1
        if currRecordLenght >= recordLenght :
            break

My GUI includel only rpm Qlabel and some test widgets

import sys

from PyQt5.QtCore import QSize, Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDial, QGridLayout, QWidget, QLabel 
from PyQt5 import QtCore, QtGui, QtWidgets
from power_bar import PowerBar
from PyQt5.QtGui import QPalette, QColor

class Color(QWidget):

    def __init__(self, color):
        super(Color, self).__init__()
        self.setAutoFillBackground(True)

        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(color))
        self.setPalette(palette)
# Subclass QMainWindow to customize your application's main window
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")
        button = QPushButton("Press Me!")
        button.setFixedSize(100,100)
        volume = QDial()
        rpm = QLabel("RPM")
        
        layout = QGridLayout()

        layout.addWidget(rpm, 0, 0)
        layout.addWidget(rearWeight, 1, 0)
        layout.addWidget(button, 1, 1)
        

        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)
        self.setMinimumSize(QSize(700, 300))

        


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

What would be best way to pass for eg engine_speed data to GUI?

Antsu
  • 1
  • 1
  • 2
    Sorry, but StackOverflow is not a tutorial website. If you did attempt to do what you want to achieve, then please provide a [mre]. – musicamante Nov 08 '22 at 07:36
  • I am not going to spend time debugging your code. In any case I would have no way to test it. But scanning what you have written it looks like you are getting close. When I do this I use a serial thread (or async) that reads from the port and puts data into an in memory buffer. Add semaphores to protect that buffer and a then client async or thread that reads and manipulates that buffer. That way you don't have to teach the serial port how to parse the protocol. For sending the exact oposite is put in place. If there needs to be flow control then the send/receive threads can handle it. – Jay M Nov 08 '22 at 11:39

0 Answers0