J'ai besoin de gérer les données de graphe à un débit élevé. J'ai besoin d'interroger en permanence le port série pour récupérer les données quand elles sont disponibles. Les données modifient ensuite les variables d'instance que je représente. Je représente graphiquement 4 lignes différentes sur deux sous-tracés, donc 8 lignes au total. Je reçois 12 variables différentes, mais seulement le graphique 8. J'ai besoin que le processus ne s'éteigne pas après l'exécution de la fonction une fois de cette façon, je peux continuer à recevoir de nouvelles données. Je veux que le tracé soit fait dans un autre processus afin qu'il ne bloque pas la lecture du port série. J'ai trouvé des exemples et j'ai obtenu de l'aide pour y parvenir si toutes les données sont déjà disponibles mais pas si je reçois continuellement de nouvelles données et si je suis novice en multiprocessing/threading, il est difficile de comprendre comment les lire en continu. à partir du port série. Je peux accomplir ce que j'ai besoin à un taux de 10Hz mais j'ai besoin d'échantillonner à 20Hz et il semble que le seul moyen serait le multiprocessing/threading à moins que je manque quelque chose qui optimiserait le temps de lecture ou graphique. Voici une fenêtre Tkinter qui interrogera le port série lorsque le bouton de validation est pressé et graphique:Utilisation de multiprocessing/threading pour lire le port série et les données de graphe en temps réel avec Tkinter
import Tkinter
import serial
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from collections import deque
import random
import time
class App:
def __init__(self, master):
self.t = 0
self.arduinoData = serial.Serial('com5', 250000, timeout=None)
frame = Tkinter.Frame(master)
self.running = False
self.ani = None
self.run = Tkinter.LabelFrame(frame, text="Testing", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10)
self.run.grid(row=0, column=0, padx=20, pady=20)
self.run_respiration = Tkinter.Button(self.run, text="RUN",bd=10, height=5, width=10, command=self.getData)
self.run_respiration.grid(row=0, column=0, padx=5, pady=5)
self.test_options = Tkinter.LabelFrame(frame, text="Test Options", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10)
self.test_options.grid(row=0, column=1, padx=20, pady=20)
self.stop = Tkinter.Button(self.test_options, text="STOP", bd=10, height=5, width=10, command=self.stopTest)
self.stop.grid(row=0, column=0, padx=5, pady=5)
self.fig = plt.Figure()
self.ax1 = self.fig.add_subplot(211)
self.line0, = self.ax1.plot([], [], lw=2)
self.line1, = self.ax1.plot([], [], lw=2)
self.line2, = self.ax1.plot([], [], lw=2)
self.line3, = self.ax1.plot([], [], lw=2)
self.ax2 = self.fig.add_subplot(212)
self.line4, = self.ax2.plot([], [], lw=2)
self.line5, = self.ax2.plot([], [], lw=2)
self.line6, = self.ax2.plot([], [], lw=2)
self.line7, = self.ax2.plot([], [], lw=2)
self.canvas = FigureCanvasTkAgg(self.fig,master=master)
self.canvas.show()
self.canvas.get_tk_widget().grid(row=0, column=4, padx=20, pady=20)
frame.grid(row=0, column=0, padx=20, pady=20)
def getData(self):
if self.ani is None:
self.k = 0
self.arduinoData.flushInput()
self.arduinoData.write("<L>")
return self.start()
else:
self.arduinoData.write("<L>")
self.arduinoData.flushInput()
self.ani.event_source.start()
self.running = not self.running
def stopTest(self):
self.arduinoData.write("<H>")
if self.running:
self.ani.event_source.stop()
self.running = not self.running
def start(self):
self.xdata = []
self.pressure1 = []
self.displacement1 = []
self.cycle1 = []
self.pressure2 = []
self.displacement2 = []
self.cycle2 = []
self.pressure3 = []
self.displacement3 = []
self.cycle3 = []
self.pressure4 = []
self.displacement4 = []
self.cycle4 = []
self.k = 0
self.limit = 300
self.arduinoData.flushInput()
self.ani = animation.FuncAnimation(
self.fig,
self.update_graph,
interval=1,
repeat=True)
self.arduinoData.write("<L>")
self.running = True
self.ani._start()
def update_graph(self, i):
if (self.arduinoData.inWaiting()>0):
self.xdata.append(self.k)
x = self.arduinoData.readline()
self.setData(x)
strip_data = x.strip()
split_data = x.split("|")
actuator1 = split_data[0].split(".")
actuator2 = split_data[1].split(".")
actuator3 = split_data[2].split(".")
actuator4 = split_data[3].split(".")
self.pressure1.append(int(actuator1[0]))
self.displacement1.append(int(actuator1[1]))
self.cycle1 = int(actuator1[2])
self.pressure2.append(int(actuator2[0]))
self.displacement2.append(int(actuator2[1]))
self.cycle2 = int(actuator2[2])
self.pressure3.append(int(actuator3[0]))
self.displacement3.append(int(actuator3[1]))
self.cycle3 = int(actuator3[2])
self.pressure4.append(int(actuator4[0]))
self.displacement4.append(int(actuator4[1]))
self.cycle4 = int(actuator4[2])
self.line0.set_data(self.xdata, self.pressure1)
self.line1.set_data(self.xdata, self.pressure2)
self.line2.set_data(self.xdata, self.pressure3)
self.line3.set_data(self.xdata, self.pressure4)
self.line4.set_data(self.xdata, self.displacement1)
self.line5.set_data(self.xdata, self.displacement2)
self.line6.set_data(self.xdata, self.displacement3)
self.line7.set_data(self.xdata, self.displacement4)
if self.k < 49:
self.ax1.set_ylim(min(self.pressure1)-1, max(self.pressure4) + 1)
self.ax1.set_xlim(0, self.k+1)
self.ax2.set_ylim(min(self.displacement1)-1, max(self.displacement4) + 1)
self.ax2.set_xlim(0, self.k+1)
elif self.k >= 49:
self.ax1.set_ylim(min(self.pressure1[self.k-49:self.k])-1, max(self.pressure4[self.k-49:self.k]) + 1)
self.ax1.set_xlim(self.xdata[self.k-49], self.xdata[self.k-1])
self.ax2.set_ylim(min(self.displacement1[self.k-49:self.k])-1, max(self.displacement4[self.k-49:self.k]) + 1)
self.ax2.set_xlim(self.xdata[self.k-49], self.xdata[self.k-1])
if self.cycle1 >= self.limit:
self.running = False
self.ani = None
self.ani.event_source.stop()
self.running = not self.running
self.k += 1
root = Tkinter.Tk()
app = App(root)
root.mainloop()
Si quelqu'un peut aider avec ma compréhension de multitraitement ou de fournir un exemple qui serait génial. Merci
Vous pouvez simplement définir une minuterie pour répéter la fonction après tant de ticks. Si vous voulez simplement exécuter cette fonction en permanence, vous pouvez le faire avec '.after()'. 'self.function_to_get_data.after (100, lambda: self.function_to_get_data())' –
La fonction get data que j'utilise est appelée par la fonction d'animation comment serais-je capable d'utiliser après pour qu'ils soient à la fois appelés et gagnés? t bloquer l'exécution des autres – emg184
est la fonction d'animation appelée plus d'une fois? –