Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python脚本中只使用从Arduino读取的最新值,而不使用存储在缓冲区中的值?_Python_Serial Port_Buffer_Arduino_Readline - Fatal编程技术网

在python脚本中只使用从Arduino读取的最新值,而不使用存储在缓冲区中的值?

在python脚本中只使用从Arduino读取的最新值,而不使用存储在缓冲区中的值?,python,serial-port,buffer,arduino,readline,Python,Serial Port,Buffer,Arduino,Readline,我一直在做一个项目,使用Python从arduino读取值,然后控制摄像机。Arduino控制两个超声波传感器,并以厘米为单位报告距离。python脚本然后使用ser.readline()读取与Arduino的距离。当脚本读取范围之外的值时,一切正常。但是,如果进入循环的距离在要求的范围内,它会正常工作一次,然后从Arduino读取旧值,而不是当前的“活动”值,这会导致它继续记录循环,而不是退出循环。我该怎么做才能去掉缓冲区中的旧值,而只读取最新的值?我已经找到了几种方法并进行了测试,但到目前为

我一直在做一个项目,使用Python从arduino读取值,然后控制摄像机。Arduino控制两个超声波传感器,并以厘米为单位报告距离。python脚本然后使用ser.readline()读取与Arduino的距离。当脚本读取范围之外的值时,一切正常。但是,如果进入循环的距离在要求的范围内,它会正常工作一次,然后从Arduino读取旧值,而不是当前的“活动”值,这会导致它继续记录循环,而不是退出循环。我该怎么做才能去掉缓冲区中的旧值,而只读取最新的值?我已经找到了几种方法并进行了测试,但到目前为止没有成功

下面是我正在使用的代码(我知道它写得不好,但这是我第一次尝试使用python并在matlab之外编写代码)

导入系统,时间 导入序列号 导入cv 导入操作系统 从时间导入strftime #为摄影机0创建窗口 cv.NamedWindow(“摄影机0”,cv.cv\u窗口\u自动调整大小) capture0=cv.CreateCameraCapture(2) cv.调整窗口大小(“摄像机1”,640480) cv.MoveWindow(“摄影机0”,0,0) #为摄影机1创建窗口 cv.NamedWindow(“摄影机1”,cv.cv\u窗口\u自动调整大小) capture1=cv.CreateCameraCapture(1) cv.移动窗口(“摄像机1”,150,150) #初始化与Arduino的连接 arduino=serial.serial('COM12',9600) 已连接=错误 #确认Arduino已连接且软件能够读取输入 未连接时: serin=arduino.readline() 已连接=真 f='传感器已连接' 打印f ''测试用虚拟变量 值1=145 值2=30''' #将上的视频录制初始化为false(0) vid=0 #初始化计数器 计数器\u vid=0 计数器=0 加速度=1 def Camera0(): frame0=cv.QueryFrame(capture0) cv.WriteName(writer0,frame0) cv.ShowImage(“摄影机0”,帧0) def Camera1(): frame1=cv.QueryFrame(capture1) cv.WriteName(writer1,frame1) cv.ShowImage(“摄像机1”,第1帧) 尽管如此: status=arduino.readline() 值1=int((状态[6:10])-1000 value2=int((状态[17:21])-1000 打印(值1) 打印(值2) 如果值1>180和值2>180且vid==0: vid=0 elif值1>180和值2>180且vid==1: vid=0
elif value1关于缓冲区填充的说法是对的。您需要一种总是从缓冲区中获取最新值的方法

我建议更换这个:

status = arduino.readline()
为此:

status = getLatestStatus()
然后再向上靠近顶部,通过您的相机功能:

def getLatestStatus():
    while arduino.inWaiting() > 0:
        status = arduino.readline()
    return status
此函数getLatestStatus将在每次调用时遍历整个缓冲区,只返回最新状态,而不考虑同时返回的所有状态


您的另一个选择是修改arduino的“固件”,使其在每次收到命令时返回距离传感器值(例如“M\n”),这样您就不必担心缓冲区问题。这就是我为arduino动力超声波测距仪所做的,我觉得它比“读取整个缓冲区”解决方案更干净。不过,这会给你的距离测量带来更多的延迟。

大约88%的代码看起来与问题无关——我建议你尝试一些代码,省去所有相机的东西,也许会进行十几次以短暂延迟分隔的阅读,并用简短的代码及其结果修改问题。当我这样做时,它确实有效好的只是当所有的东西加在一起时,我才有问题。这就是为什么我认为这是一个缓冲问题,在处理所有数据所需的时间内,值存储在arduino缓冲区中,下一次迭代我得到缓冲区中的下一个值,但实际上,该值发生在x个时间之前,我实际上知道最新的值不是缓冲区中的第一个值。要查看相机处理延迟是否与问题有关,尝试使用不同延迟的非摄像头代码代替摄像头代码。Eg
导入时间;dt=0.05
(或
dt=0.25
等),然后将
time.sleep(dt)
语句替换摄像机代码。可能的
def getLatestStatus():
    while arduino.inWaiting() > 0:
        status = arduino.readline()
    return status