#python #window
#python #окно
Вопрос:
Я пишу приложение для цифровых лабораторных весов, которые подключаются по последовательному каналу. Чтобы создать приложение, я настроил мост COM-порта и написал программу для имитации баланса на моей машине (баланс был в использовании). Я покажу вам самую последнюю версию программы моделирования баланса:
import serial, random, time
s = serial.Serial('COM2')
#Initially we will just push a random float
#After the data the scale sends a carraige return line feed
def pushData():
data = f'{round(random.uniform(10, 100), 2)}rn'.encode()
print(f'Sending Data: {data}')
s.write(data)
try:
while True:
pushData()
time.sleep(10)
except:
print('Something went wrong.')
Этот код вместе с моим приложением баланса работает, как и ожидалось, на моей машине. Но когда я пытаюсь использовать свою программу балансировки с реальным устройством, она не получает всех последовательных данных, если она вообще работает. Мне интересно, нужна ли мне какая-то многопоточность, если это проблема со временем или что-то в этом роде. Я знаю, что баланс работает, потому что я могу контролировать COM-порт.
Я опубликую здесь свою самую последнюю программу балансировки:
# !/usr/bin/python3
################ Imports
import serial, pyperclip
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from datetime import datetime, time
from tkinter import *
################ Declarations
GUI = Tk()
s = serial.Serial('COM5', timeout=1)
wgtList = [0,0,0,0,0]
wgtDict = {'Lab':[],
'Weight':[]}
newL = 'rn'
tareWgt = 0
newWgt = 0 #Trying to get past program not working when no data is pushed
################ Functions
def thisAfter():
"""Updates scale feed and updates the scale feed."""
try:
global newWgt
newWgt = float(s.readline().decode().rstrip('rn')) - tareWgt
except ValueError:
#print('ValueError thisAfter(): NO DATA OR COULD NOT CONVERT SERIAL DATA TO FLOAT')
print('ValueError thisAfter(): ' str(newWgt))
print('wgtList: ' str(wgtList))
wgtList.append(newWgt)
if newWgt not in wgtList[0:5]:
text.insert(INSERT,str(newWgt) newL)
if len(wgtList) > 5:
del wgtList[0]
GUI.after(50, thisAfter)
text.see(END)
def labCallback():
"""Saves data to file, iterates the entry field."""
num = labEntry.get()
csvStr = datetime.today().strftime("%Y/%m/%d") ',' datetime.now().strftime("%H:%M:%S") ',' num ',' str(wgtList[-1]) ',' var1.get() ',' str(tareWgt) newL
with open('data.csv', 'a ', newline = '') as file:
if file.readline() == None:
file.write('Date, Time, Lab, Weight, Type' newL)
file.write(csvStr)
#print(csvStr) #Just checking
labEntry.delete(0,END)
labEntry.insert(0, int(num) 1)
csvArr = csvStr.split(',')
wgtDict['Lab'].append(int(csvArr[2]))
wgtDict['Weight'].append(float(csvArr[3]))
text2.insert(INSERT, ',t'.join(csvArr))
text2.see(END)
#print(str(wgtDict) 'n')
def tareCallback():
global tareWgt
tareWgt = wgtList[-1]
print(tareWgt)
text3.insert(INSERT,newL str(tareWgt))
text3.see(END)
def copyData():
global newWgt
pyperclip.copy(newWgt)
def close():
s.close()
def start():
global s
try:
s = serial.Serial('COM5', timeout=1)
thisAfter()
except:
print('Serial port closed')
################ Frames/Panes
frame1 = LabelFrame(GUI, text = 'Lab Label Entry Field')
frame1.pack(side = TOP)
frame6 = LabelFrame(frame1, text = 'Tare')
frame6.pack(side = BOTTOM)
frame2 = LabelFrame(GUI, text = 'Scale Feed')
frame2.pack(side = BOTTOM)
frame3 = LabelFrame(GUI, text = 'Saved Feed')
frame3.pack(side = BOTTOM)
frame4 = LabelFrame(GUI, text = 'Plot')
frame4.pack(side = TOP)
frame5 = LabelFrame(frame1, text = 'Type Select')
frame5.pack(side = BOTTOM)
################ Lab Label Entry Field Type Select
labLabel = Label(frame1, bd = 5, text = 'Lab#')
labLabel.pack(side = LEFT)
tareLabel = Label(frame6, bd = 5, text = 'Tare')
tareLabel.pack(side = LEFT)
text3 = Text(frame6, height = 1, width = 20)
text3.pack(side = RIGHT)
closeButton = Button(frame1, text = 'Close', command = close)
closeButton.pack(side = RIGHT)
startButton = Button(frame1, text = 'Start', command = start)
startButton.pack(side = RIGHT)
tareButton = Button(frame1, text = 'Tare', command = tareCallback)
tareButton.pack(side = RIGHT)
undoButton = Button(frame1, text = 'Undo')
undoButton.pack(side = RIGHT)
labButton = Button(frame1, text = 'Save', command = labCallback)
labButton.pack(side = RIGHT)
copyButton = Button(frame1, text = 'Copy', command = copyData)
copyButton.pack(side = RIGHT)
labEntry = Entry(frame1)
labEntry.pack(side = RIGHT)
var1 = StringVar()
r1 = Radiobutton(frame5, text = 'pH', variable= var1, value = 'pH')
r1.pack(anchor = 's')
r2 = Radiobutton(frame5, text = 'pH-Tray', variable= var1, value = 'pH-Tray')
r2.pack(anchor = 's')
r3 = Radiobutton(frame5, text = 'Mehlich', variable= var1, value = 'Mehlich')
r3.pack(anchor = 's')
r4 = Radiobutton(frame5, text = 'Nitrate', variable= var1, value = 'Nitrate')
r4.pack(anchor = 's')
r5 = Radiobutton(frame5, text = 'Excel', variable= var1, value = 'Excel')
r5.pack(anchor = 's')
r6 = Radiobutton(frame5, text = 'Excel-Tray', variable= var1, value = 'Excel-Tray', state=DISABLED)
r6.pack(anchor = 's')
r1.select()
r2.deselect()
r3.deselect()
r4.deselect()
r5.deselect()
r6.deselect()
################ Scale Feed
scrollbar = Scrollbar(frame2)
scrollbar.pack(side = RIGHT, fill = Y)
text = Text(frame2, yscrollcommand = scrollbar.set, height = 10)
text.pack()
text.bind('<ButtonPress>', lambda e: 'break')
scrollbar.config(command = text.yview)
#thisAfter()
################ Saved Feed
scrollbar = Scrollbar(frame3)
scrollbar.pack(side = RIGHT, fill = Y)
text2 = Text(frame3, yscrollcommand = scrollbar.set, height = 10)
text2.pack()
scrollbar.config(command = text.yview)
################ Plot
f = plt.Figure(dpi=50, figsize=(13, 4))
plt.xkcd()
a = f.add_subplot(111)
def animate(i):
xL = wgtDict['Lab']
yL = wgtDict['Weight']
a.clear()
a.plot(xL, yL)
canvas = FigureCanvasTkAgg(f, frame4)
canvas.get_tk_widget().pack(side = LEFT, fill = BOTH)
ani = animation.FuncAnimation(f, animate, interval=1000)
# This is some kind of 'while true' loop fyi
GUI.mainloop()
Комментарии:
1. Возможно, сначала создайте простое приложение на основе консоли, которое печатает последовательные данные. Ваш код, по крайней мере для меня, слишком длинный, чтобы получить хорошее представление о том, что происходит
2. Добавьте инструкцию print для отображения s.readline() , затем предоставьте образец вашего вывода с сообщением об ошибке. Ваша макет-программа постоянно записывает данные в последовательный порт. По моему опыту, оборудование может не делать то же самое.