Solved Help with qlcd connection
-
Hi everyone. New pi and qt user and brand new to this forum. I've been here many times learning from past questions and answers but I'm stuck now and hoping someone might be able to explain what I'm doing wrong.
The short story is that I have put together a python/qt program that reads pi input pin voltages and is currently displaying the voltage in the pi terminal, just to test. What I am trying to do is display that voltage in my gui on a qlcdnumber. When I run the program, everything works with the exception of the lcd. I'm not sure what I'm doing wrong and would like to learn this. If anyone could have a look and maybe point me in the right direction, I would be grateful. The full code is below. Please let me know if you need any further information. Thank you very much.
import sys import RPi.GPIO as GPIO import time import re from PyQt4 import QtGui, uic, QtCore import spidev GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) o2zero = 26 o2span = 19 cozero = 13 cospan = 6 co2zero = 5 co2span = 21 status = "nil" o2_channel = 0 o2_temp_channel = 1 co_channel = 2 co_temp_channel = 3 co2_channel = 4 co2_temp_channel = 5 spi = spidev.SpiDev() spi.open(0,0) class MyWindow(QtGui.QMainWindow): def __init__(self): super(MyWindow, self).__init__() uic.loadUi('mainwindow.ui', self) self.o2_zero_up.clicked.connect(self.o2zeroup) self.o2_zero_down.clicked.connect(self.o2zerodown) self.o2_span_up.clicked.connect(self.o2spanup) self.o2_span_down.clicked.connect(self.o2spandown) self.co_zero_up.clicked.connect(self.cozeroup) self.co_zero_down.clicked.connect(self.cozerodown) self.co_span_up.clicked.connect(self.cospanup) self.co_span_down.clicked.connect(self.cospandown) self.co2_zero_up.clicked.connect(self.co2zeroup) self.co2_zero_down.clicked.connect(self.co2zerodown) self.co2_span_up.clicked.connect(self.co2spanup) self.co2_span_down.clicked.connect(self.co2spandown) self.close_button.clicked.connect(self.gpiocleanup) self.thread = O2_Channel() self.thread.o2_concentration.connect(self.o2_voltage) self.thread.start() self.show() def o2_voltage(self, values): o2_volts = values def o2_temperature(self, values): o2_temp = values def co_voltage(self, values): co_volts = values def co_temperature(self, values): co_temp = values def co2_voltage(self, values): co2_volts = values def co2_temperature(self, values): co2_temp = values def o2zeroup(self): GPIO.setup(o2zero, GPIO.OUT) GPIO.output(o2zero, 1) def o2zerodown(self): GPIO.setup(o2zero, GPIO.OUT) GPIO.output(o2zero, 0) def o2spanup(self): GPIO.setup(o2span, GPIO.OUT) GPIO.output(o2span, 1) def o2spandown(self): GPIO.setup(o2span, GPIO.OUT) GPIO.output(o2span, 0) def cozeroup(self): GPIO.setup(cozero, GPIO.OUT) GPIO.output(cozero, 1) def cozerodown(self): GPIO.setup(cozero, GPIO.OUT) GPIO.output(cozero, 0) def cospanup(self): GPIO.setup(cospan, GPIO.OUT) GPIO.output(cospan, 1) def cospandown(self): GPIO.setup(cospan, GPIO.OUT) GPIO.output(cospan, 0) def co2zeroup(self): GPIO.setup(co2zero, GPIO.OUT) GPIO.output(co2zero, 1) def co2zerodown(self): GPIO.setup(co2zero, GPIO.OUT) GPIO.output(co2zero, 0) def co2spanup(self): GPIO.setup(co2span, GPIO.OUT) GPIO.output(co2span, 1) def co2spandown(self): GPIO.setup(co2span, GPIO.OUT) GPIO.output(co2span, 0) def gpiocleanup(self): GPIO.cleanup() def closeEvent(self, event): self.thread.stop() self.thread.quit() self.thread.wait() self.thread.deleteLater() print ("GPIO CleanUP") GPIO.cleanup() event.accept() def ReadChannel(channel): adc = spi.xfer2([1,(8+channel)<<4,0]) data = ((adc[1]&3) << 8) + adc[2] return data def ConvertVolts(data, places): volts = (data * 3.3) / float(1023) volts = round(volts,places) return volts def ConvertTemp(data, places): temp = ((data * 330)/float(1023))-50 temp = round(temp,places) return temp class O2_Channel(QtCore.QThread): o2_concentration = QtCore.pyqtSignal(int) def __init__(self): QtCore.QThread.__init__(self) self.mRunning = True def run(self): while self.mRunning: o2_concentration_channel = 0 o2_volt_level = ReadChannel(o2_concentration_channel) o2_volts = ConvertVolts(o2_volt_level,2) o2_temp_channel = 1 o2_temp_level = ReadChannel(o2_temp_channel) o2_temp_volts = ConvertVolts(o2_temp_level,2) o2_temp = ConvertTemp(o2_temp_level,2) print("{}".format(o2_volts)) self.o2_concentration.emit((o2_volts)) delay = .2 time.sleep(delay) def stop(self): self.mRunning = False if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = MyWindow() sys.exit(app.exec_())
-
Hi and welcome to devnet,
Where are you doing anything with your QLcdNumber objects ?
-
Your question shows that I am very confused about this. After I posted, I realized I actually had no lcd anywhere in the code. I have since added it as best I know how but still to no success. I'm reading everything I can but nothing yet. You can see I added the lcd in a couple of different places trying to make it work. The lcd label is o2_concentration_lcd. I am running a while loop in a thread to get constant voltage readings and am wondering if that is what is confusing me. Anyway, I reposted the code and I've added some stuff since the first post and thought it might be easier just to repost the entire code again. Thanks for even having a look.
import sys import RPi.GPIO as GPIO import time import re from PyQt4.QtCore import QThread from PyQt4 import QtGui, uic, QtCore import spidev GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) o2zero = 26 o2span = 19 cozero = 13 cospan = 6 co2zero = 5 co2span = 21 status = "nil" o2_concentration_channel = 0 o2_temp_channel = 1 co_concentration_channel = 2 co_temp_channel = 3 co2_concentration_channel = 4 co2_temp_channel = 5 spi = spidev.SpiDev() spi.open(0,0) class MyWindow(QtGui.QMainWindow): def __init__(self): super(MyWindow, self).__init__() uic.loadUi('mainwindow.ui', self) self.o2_zero_up.clicked.connect(self.o2zeroup) self.o2_zero_down.clicked.connect(self.o2zerodown) self.o2_span_up.clicked.connect(self.o2spanup) self.o2_span_down.clicked.connect(self.o2spandown) self.co_zero_up.clicked.connect(self.cozeroup) self.co_zero_down.clicked.connect(self.cozerodown) self.co_span_up.clicked.connect(self.cospanup) self.co_span_down.clicked.connect(self.cospandown) self.co2_zero_up.clicked.connect(self.co2zeroup) self.co2_zero_down.clicked.connect(self.co2zerodown) self.co2_span_up.clicked.connect(self.co2spanup) self.co2_span_down.clicked.connect(self.co2spandown) self.close_button.clicked.connect(self.gpiocleanup) self.thread = Concentrations_Temps() self.thread.changedValue.connect(self.onChangeValue) self.thread.start() self.show() def onChangeValue(self, values): o2_volts = values def o2_temperature(self, values): o2_temp = values(int) def co_voltage(self, values): co_volts = values def co_temperature(self, values): co_temp = values def co2_voltage(self, values): co2_volts = values def co2_temperature(self, values): co2_temp = values def o2zeroup(self): GPIO.setup(o2zero, GPIO.OUT) GPIO.output(o2zero, 1) def o2zerodown(self): GPIO.setup(o2zero, GPIO.OUT) GPIO.output(o2zero, 0) def o2spanup(self): GPIO.setup(o2span, GPIO.OUT) GPIO.output(o2span, 1) def o2spandown(self): GPIO.setup(o2span, GPIO.OUT) GPIO.output(o2span, 0) def cozeroup(self): GPIO.setup(cozero, GPIO.OUT) GPIO.output(cozero, 1) def cozerodown(self): GPIO.setup(cozero, GPIO.OUT) GPIO.output(cozero, 0) def cospanup(self): GPIO.setup(cospan, GPIO.OUT) GPIO.output(cospan, 1) def cospandown(self): GPIO.setup(cospan, GPIO.OUT) GPIO.output(cospan, 0) def co2zeroup(self): GPIO.setup(co2zero, GPIO.OUT) GPIO.output(co2zero, 1) def co2zerodown(self): GPIO.setup(co2zero, GPIO.OUT) GPIO.output(co2zero, 0) def co2spanup(self): GPIO.setup(co2span, GPIO.OUT) GPIO.output(co2span, 1) def co2spandown(self): GPIO.setup(co2span, GPIO.OUT) GPIO.output(co2span, 0) def gpiocleanup(self): GPIO.cleanup() def closeEvent(self, event): self.thread.stop() self.thread.quit() self.thread.wait() self.thread.deleteLater() print ("GPIO Cleanup") GPIO.cleanup() event.accept() def ReadChannel(channel): adc = spi.xfer2([1,(8+channel)<<4,0]) data = ((adc[1]&3) << 8) + adc[2] return data def ConvertVolts(data, places): volts = (data * 3.3) / float(1023) volts = round(volts,places) return volts def ConvertTemp(data, places): temp = ((data * 330)/float(1023))-50 temp = round(temp,places) return temp class Concentrations_Temps(QtCore.QThread): changedValue = QtCore.pyqtSignal(int) def __init__(self): QtCore.QThread.__init__(self) self.mRunning = True def o2_voltage(self, values): o2_volts = values def o2_concentration_lcd(self): self.o2_concentration_lcd.display(o2_volts) def run(self): while self.mRunning: o2_concentration_channel = 0 o2_volt_level = ReadChannel(o2_concentration_channel) o2_volts = ConvertVolts(o2_volt_level,2) o2_temp_channel = 1 o2_temp_level = ReadChannel(o2_temp_channel) o2_temp_volts = ConvertVolts(o2_temp_level,2) o2_temp = ConvertTemp(o2_temp_level,2) co_concentration_channel = 2 co_volt_level = ReadChannel(co_concentration_channel) co_volts = ConvertVolts(co_volt_level,2) co_temp_channel = 3 co_temp_level = ReadChannel(co_temp_channel) co_temp_volts = ConvertVolts(co_temp_level,2) co_temp = ConvertTemp(co_temp_level,2) co2_concentration_channel = 4 co2_volt_level = ReadChannel(co2_concentration_channel) co2_volts = ConvertVolts(co2_volt_level,2) co2_temp_channel = 5 co2_temp_level = ReadChannel(co2_temp_channel) co2_temp_volts = ConvertVolts(co2_temp_level,2) co2_temp = ConvertTemp(co2_temp_level,2) print("{}".format(o2_volts)) self.changedValue.emit((o2_volts)) delay = .2 time.sleep(delay) def stop(self): self.mRunning = False if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = MyWindow() sys.exit(app.exec_())
-
@0220kj Never change the UI in a different thread!
I don't understand this code:class Concentrations_Temps(QtCore.QThread): ... def o2_concentration_lcd(self): self.o2_concentration_lcd.display(o2_volts)
o2_concentration_lcd is a method in Concentrations_Temps and then you do
self.o2_concentration_lcd.display(o2_volts)
what is this line supposed to do?
All you need to do is to emit a signal in Concentrations_Temps every time you get new temperature and pass the temperature as signal parameter. Then you connect a slot in your MainWindow class and change your LCD there (again: do not change GUI in non GUI threads!).
-
jsulm, thanks for that explanation and I understand now about changing the GUI in a non-GUI thread and I fixed that.
If I understand the rest of your explanation:
I have my signal emit in the Concentrations_Temps thread:
class Concentrations_Temps(QtCore.QThread): self.changedValue.emit((o2_volts))
The signal is passed (again inside the Concentrations_Temps thread) here:
class Concentrations_Temps(QtCore.QThread): ... changedValue = QtCore.pyqtSignal(int)
The slot is connected in the MainWindow here:
class MyWindow(QtGui.QMainWindow): ... self.thread.changedValue.connect(self.onChangeValue)
Then the next part is what's confusing me. What is the method to connect to the LCD?
Is it similar to a button or other widget inside the MainWindow, correct? Such as:self.o2_concentration_lcd.display(changedValue)
o2_concentration_lcd is the name I've given the QLCDNumber widget in my GUI.
I would say the answer is no because I'm getting an error when trying it:
File "Analyzer_GUI_4.py", line 51, in init
self.o2_concentration_lcd.display(changedValue)
NameError: global name 'changedValue' is not definedAs I said, I'm new at this so thanks for your patience.
-
The
onChangedValue
value slot (which is basically just function from your class) should have a paremeter (e.g.changedValue
or justvalue
) and you callself.o2_concentration_lcd.display(changedValue)
in the body of ònChangedValue`. -
So like this?
self.thread.changedValue.connect(self.onChangeValue) ... def onChangeValue(self, changedValue): o2_volts = changedValue self.o2_concentration_lcd.display(changedValue)
If so, it runs without error and prints to the terminal, but not to the QLCDNumber. It remains at zero.
Thanks.
-
You shouild print the value of
valueChanged
to check what it contains. -
With your help from your first reply and the suggestion to print valueChanged, it works!
Mode for the Qlcd was set to Hex, not Dec but that was easy enough to find and fix.
Anyways, thank you SGaist and thanks to jsulm. Every little piece of advise is a learning experience.