Recently I was given a project to develop a GUI on RaspberryPi 2 to control a machine. I don't particularly have much experience with Qt GUIs and Qthreads so please bear with me.
I used Qt4 and Python to develop the GUI and the underlying program.
And the program was running fairly smoothly without any issues on my PCs. I used threads and had everything running fine until I tried it with the RaspberryPi2 which controls the machine.
It's got a Qthread which grabs a frame from a camera and displays it using a label. This works fine but does not update in real time (very slow update rate). I've got several buttons which controls the machine axis Movements, running in a Qthread and would also like to incorporate another Qthread with a program that has a specific set of instructions for the machine.
It all seem to work but the response from the machine is very slow (sometimes it takes up to 5 seconds to execute a single command when button is pressed). I have debugged it and traced it back to the GUI.
Also Note: The RaspberryPi 2 CPU usage while the program is running is about 30-35%.... So it's not maxing out the CPU.
Can someone please let me know what I'm doing wrong. I suspects its got something to do with the thread execution and Queuing.
I have attached a sample of the CODE below:
class IO_Worker(QtCore.QThread):
def MoveLeft(self):
print "MovingLeft"
RPIO.output(4,0) # this is pin 7 the direction switch (lowwest)
RPIO.output(15,0) # this is pin 10 the middle toggle switch
RPIO.output(18,0) # this is pin 12 the top toggle switchdirno=4
time.sleep(.05)
RPIO.output(23,1) # next three lines press blue Go button for x stage
time.sleep(0.2)
RPIO.output(23,0)
def MoveRight(self):
print "MovingRight"
RPIO.output(4,1) # this is pin 7 the direction switch (lowwest)
RPIO.output(15,0) # this is pin 10 the middle toggle switch
RPIO.output(18,0) # this is pin 12 the top toggle switchdirno=4
time.sleep(.05)
RPIO.output(23,1) # next three lines press blue Go button for x stage
time.sleep(0.2)
RPIO.output(23,0)
class frameGrabber(QtCore.QThread):
def __init__(self, cameraID=0):
QtCore.QThread.__init__(self)
self.cameraID = cameraID
def run(self):
cap = cv2.VideoCapture(self.cameraID)
cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,320)
cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,180)
while(True):
time.sleep(0.25)
ret, frame = cap.read()
height, width, depth = frame.shape
#print "H:",height,"W:",width
frame = QtGui.QImage(frame.tostring(),width,height, QtGui.QImage.Format_RGB888).rgbSwapped()
self.emit(QtCore.SIGNAL('webcam_frame(QImage)'), frame)
class Main(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
## Initialise IO (Raspberry Pi GPIO)
self.InitIO(self.ui)
## SetupSignals
self.SetupSignals()
class InitIO(QtCore.QThread):
def __init__(self,ui):
print "IO Initialised"
RPIO.setmode(RPIO.BCM)
RPIO.cleanup()
RPIO.setup(21,RPIO.OUT,initial=1)
RPIO.setup(20,RPIO.OUT,initial=0) # LSB
RPIO.setup(16,RPIO.OUT,initial=0)
RPIO.setup(12,RPIO.OUT,initial=0) #
RPIO.setup(7,RPIO.OUT,initial=0) # MSB
RPIO.setup(26,RPIO.IN,pull_up_down=RPIO.PUD_UP)
def RightAxisMovement(self):
print "Moving Up"
IO_WorkerThread = IO_Worker()
IO_WorkerThread.MoveRight()
def LeftAxisMovement(self):
IO_WorkerThread = IO_Worker()
IO_WorkerThread.MoveLeft()
def ProcessCamFrame(self,frame):
#print "Frame update", frame
pix = QtGui.QPixmap(frame)
pix = pix.scaled(self.ui.Video_Out.size())
self.ui.Video_Out.setPixmap(pix)
def SetupSignals(self):
##############################################################
## Start Camera Thread
##############################################################
camWorker = frameGrabber()
camWorker.start()
QtCore.QObject.connect(camWorker,QtCore.SIGNAL("webcam_frame(QImage)"),self.ProcessCamFrame)
IO_WorkerThread = IO_Worker()
IO_WorkerThread.start()
##############################################################
## Listen to Movement Button Class
##############################################################
self.ui.pButton_Left.clicked.connect(self.LeftAxisMovement)
self.ui.pButton_Right.clicked.connect(self.RightAxisMovement)
##---------------------------------------------------------------------
if __name__== "__main__":
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())