Проблема синхронизации последовательного порта Windows или неправильный код? [Python]

#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() , затем предоставьте образец вашего вывода с сообщением об ошибке. Ваша макет-программа постоянно записывает данные в последовательный порт. По моему опыту, оборудование может не делать то же самое.