Python 串行通信的高延迟

Python 串行通信的高延迟,python,matplotlib,arduino,Python,Matplotlib,Arduino,我正在努力将2个Arduino组合在一起。第一个控制来自鼠标传感器的数据,第二个控制来自超声波传感器的数据,以及未来的伺服。我创建了一个简单的GUI来显示两个Arduinos的图形 我的问题是,来自鼠标的数据有一些延迟。如果我使用我的传感器5秒钟,在接下来的15秒钟内,我会收到来自这次的数据。那么,你知道这将如何顺利进行吗?我需要它是实时的,这样我才能计算速度和加速度。我试着在Arduino代码上更改延迟和波特率。同时,在Arduino系列监视器上,这是非常好的。 在我从Arduino发送dx、

我正在努力将2个Arduino组合在一起。第一个控制来自鼠标传感器的数据,第二个控制来自超声波传感器的数据,以及未来的伺服。我创建了一个简单的GUI来显示两个Arduinos的图形

我的问题是,来自鼠标的数据有一些延迟。如果我使用我的传感器5秒钟,在接下来的15秒钟内,我会收到来自这次的数据。那么,你知道这将如何顺利进行吗?我需要它是实时的,这样我才能计算速度和加速度。我试着在Arduino代码上更改延迟和波特率。同时,在Arduino系列监视器上,这是非常好的。 在我从Arduino发送dx、sumX、dy、sumY之前,只发送2个值并没有帮助

dx,dy-sumx/sumy轴上的位移

十、 Y-X,Y中的总位移

负责此部分的Python代码

def update_figure(self):
            t = time.time()
            reading=str(ser.readline().decode("utf-8"))
            dx,dy=reading.split(',')
            dx=float(dx) # displaycement in x axis
            dy=float(dy) # displaycement in y axis
            Y=outputdy[-1]  # this is very non pro method to gather sum of movement in Y axis, and below X axis.
            global YSum
            YSum=YSum+Y 
            plt.pause(0.000001)     
            if (len(outputdx)>75):
                outputdx.pop(0)
            if (len(outputdy)>75):
                outputdy.pop(0)         

            lcdx.display(XSum)
            lcdy.display(YSum)
            self.minor.plot(outputdy,  color="red", linewidth=0.5, linestyle="-", label = 'dy')
            self.minor.plot(outputdx,  color="blue", linewidth=0.5, linestyle="-",label='dx')
            self.minor.legend(fontsize=8,loc='upper left', shadow=True,)

            self.draw()
            elapsed = time.time() - t
            print(elapsed)
你可以看到我的应用程序是什么样子的。我打印每个循环中花费的时间 移动。更新图

Python代码

from __future__ import unicode_literals
import time
import sys
import os
import matplotlib
# Make sure that we are using QT5
matplotlib.use('Qt5Agg')
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import  QLCDNumber, QLabel
from numpy import arange, sin, pi
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import serial
progname = os.path.basename(sys.argv[0])
progversion = "0.1"
ser = serial.Serial('COM3',115200)
arduinoData=serial.Serial('COM4',115200)
output=[]
outputy=[]
outputx=[]
outputdx=[]
outputdy=[]
mean10=0
mean5=0
numbers10=0
X=0
XSum=0
Y=0
YSum=0
class MyMplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)


        self.minor=fig.add_subplot(111)
        self.compute_initial_figure()
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self,
        QtWidgets.QSizePolicy.Expanding,
        QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
    def compute_initial_figure(self):
        pass

class Mousemovement(MyMplCanvas):
    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)
        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.update_figure)
        timer.start(1)      

    def compute_initial_figure(self):
        self.minor.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r')
    def update_figure(self):
        t = time.time()
        reading=str(ser.readline().decode("utf-8"))
        dx,dy=reading.split(',')
        dx=float(dx) # displaycement in x axis
        dy=float(dy) # displaycement in y axis
        Y=outputdy[-1]  
        global YSum
        YSum=YSum+Y 
        plt.pause(0.000001)     
        if (len(outputdx)>75):
            outputdx.pop(0)
        if (len(outputdy)>75):
            outputdy.pop(0)         

        lcdx.display(XSum)
        lcdy.display(YSum)
        self.minor.plot(outputdy,  color="red", linewidth=0.5, linestyle="-", label = 'dy')
        self.minor.plot(outputdx,  color="blue", linewidth=0.5, linestyle="-",label='dx')
        self.minor.legend(fontsize=8,loc='upper left', shadow=True,)

        self.draw()
        elapsed = time.time() - t
        print(elapsed)

class MyDynamicMplCanvas(MyMplCanvas):
#"""A canvas that updates itself every second with a new plot."""
    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)
        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.update_figure)
        timer.start(1)
    def compute_initial_figure(self):
        self.minor.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r')
    def update_figure(self):
        arduinoString=arduinoData.readline()
        str_value = arduinoString.strip()
        if str_value:
            measurement = int(str_value)
        plt.pause(0.000001)     
        self.minor.cla()
        self.minor.set_ylim(0,20)
        output.append(measurement)
        numbers=output[-5:]
        mean5=sum(numbers)/5
        numbers10=output[-10:]
        mean10=sum(numbers10)/10

        if (len(output)>50):
            output.pop(0)
        self.minor.plot( output, color="blue", linewidth=0.5, linestyle="-")

        lcd5.display(mean5)
        lcd10.display(mean10)
        self.draw()

class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("application main window")
        self.file_menu = QtWidgets.QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.fileQuit,
        QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)
        self.help_menu = QtWidgets.QMenu('&Help', self)
        self.menuBar().addSeparator()
        self.menuBar().addMenu(self.help_menu)
        self.help_menu.addAction('&About', self.about)
        self.main_widget = QtWidgets.QWidget(self)
        label = QtWidgets.QLabel()
        label.setText("mean from 5 measurement")
        label.setAlignment(QtCore.Qt.AlignCenter)
        labelm10 = QtWidgets.QLabel()
        labelm10.setText("mean from 10 measurement")
        labelm10.setAlignment(QtCore.Qt.AlignCenter)
        posx=QtWidgets.QLabel()
        posx.setText("Position x in total")
        posx.setAlignment(QtCore.Qt.AlignCenter)
        posy=QtWidgets.QLabel()
        posy.setText("Position y in total")
        posy.setAlignment(QtCore.Qt.AlignCenter)
        global lcd5, lcd10 ,lcdx ,lcdy
        lcd5 =  QLCDNumber(self)
        lcd10 = QLCDNumber(self)
        lcdx=QLCDNumber(self)
        lcdy=QLCDNumber(self)
        l = QtWidgets.QGridLayout(self.main_widget)


        dc = Mousemovement(self.main_widget, width=6, height=5, dpi=100)
        se=MyDynamicMplCanvas(self.main_widget, width=6, height=5, dpi=100)

        l.addWidget(dc,0,1,1,4)
        l.addWidget(posx,1,0)
        l.addWidget(lcdx,1,1)
        l.addWidget(posy,1,2)
        l.addWidget(lcdy,1,3)
        l.addWidget(label,2,0)      
        l.addWidget(lcd5,2,1)
        l.addWidget(labelm10,2,2)
        l.addWidget(lcd10,2,3)
        l.addWidget(se,3,0,1,5)


        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)
        self.statusBar().showMessage("Program ", 2000)
    def fileQuit(self):
        self.close()
    def closeEvent(self, ce):
        self.fileQuit()
    def about(self):
        QtWidgets.QMessageBox.about(self, "About",
    """Program to control movement and velocity"""
    )
qApp = QtWidgets.QApplication(sys.argv)
aw = ApplicationWindow()
aw.setWindowTitle("%s" % progname)
aw.show()
sys.exit(qApp.exec_())
#qApp.exec_(
)

Arduino代码,如果您认为这有帮助的话

#include <hidboot.h>
#include <usbhub.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

class MouseRptParser : public MouseReportParser
{
protected:
 void OnMouseMove (MOUSEINFO *mi);
};

void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
{

    Serial.print(mi ->dX, DEC);
    Serial.print(",");
    Serial.println(mi ->dY, DEC);
    delay(20);
};

USB     Usb;
USBHub     Hub(&Usb);
HIDBoot<USB_HID_PROTOCOL_MOUSE>    HidMouse(&Usb);

MouseRptParser Prs;

void setup()
{
    Serial.begin( 115200 );
#if !defined(__MIPSEL__)
    while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
    //Serial.println("Start");
    if (Usb.Init() == -1)
        Serial.println("OSC did not start.");
    delay( 20 );
     HidMouse.SetReportParser(0, &Prs);
}

void loop()
{  
  Usb.Task();
  delay(20);
}
#包括
#包括
//满足IDE,IDE也需要在ino中看到include语句。
#ifdef dobogusinclude
#包括
#恩迪夫
#包括
类MouseRptParser:public mouserportparser
{
受保护的:
移动鼠标时无效(鼠标信息*mi);
};
void MouseRptParser::OnMouseMove(MOUSEINFO*mi)
{
串行打印(mi->dX,DEC);
连续打印(“,”);
串行打印LN(mi->dY,DEC);
延迟(20);
};
USB;
USBHub集线器(和Usb);
HIDBoot-HidMouse(&Usb);
鼠标器;
无效设置()
{
序列号开始(115200);
#如果!已定义(\uuu MIPSEL\uuuu)
while(!Serial);//等待串行端口连接-用于Leonardo、Teensy和其他内置USB CDC串行连接的主板
#恩迪夫
//Serial.println(“开始”);
如果(Usb.Init()==-1)
Serial.println(“OSC未启动”);
延迟(20);
SetReportParser(0和Prs);
}
void循环()
{  
任务();
延迟(20);
}

您能测试一下从Arduino草图中删除“延迟(20)”吗?我试过了,但没有改变输出。我不知道,也许我会尝试修改(在Arduino文件中)序列,所以我会发送一些包给程序,但我不知道它是否正确。