4

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

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

import sys, time
import serial
import cv
import os
from time import strftime

#Create window for Camera 0
cv.NamedWindow("Camera 0", cv.CV_WINDOW_AUTOSIZE)
capture0 = cv.CreateCameraCapture(2)
cv.ResizeWindow("Camera 1", 640, 480)
cv.MoveWindow("Camera 0", 0, 0)
#Create window for Camera 1
cv.NamedWindow("Camera 1", cv.CV_WINDOW_AUTOSIZE)
capture1 = cv.CreateCameraCapture(1)
cv.MoveWindow("Camera 1", 150, 150)

#Initialize connection to Arduino
arduino = serial.Serial('COM12', 9600)

connected = False

#Confirm that Arduino is connected and software is able to read inputs
while not connected:
    serin = arduino.readline()
    connected = True
    f = 'Sensor Connected'
    print f

'''#Dummy variables for testing
value1 = 145
value2 = 30'''

#Initialize video record on as false (0)
vid = 0

#Initialize counter
counter_vid = 0
counter = 0

Accel = 1

def Camera0():
    frame0=cv.QueryFrame(capture0)
    cv.WriteFrame(writer0,frame0)
    cv.ShowImage("Camera 0", frame0)

def Camera1():
    frame1=cv.QueryFrame(capture1)
    cv.WriteFrame(writer1,frame1)
    cv.ShowImage("Camera 1", frame1)

while True:
    status = arduino.readline()
    value1=int((status[6:10]))-1000
    value2=int((status[17:21]))-1000
    print(value1)
    print(value2)
    if value1>180 and value2>180 and vid==0:
        vid = 0
    elif value1>180 and value2>180 and vid==1:
        vid = 0
    elif value1<180 and vid==0 or value2<180 and vid==0:
        filename0 = strftime("OUTPUT\%Y_%m_%d %H_%M_%S") + " camera0.avi"
        writer0=cv.CreateVideoWriter(filename0, 1, 15.0, (640,480), is_color=1)
        filename1 = strftime("OUTPUT\%Y_%m_%d %H_%M_%S") + " camera1.avi"
        writer1=cv.CreateVideoWriter(filename1, 1, 15.0, (640,480), is_color=1)
        vid=1
        while counter_vid<25 and vid==1:
            Camera0()
            Camera1()
            counter_vid += 1
            print(counter_vid)
            cv.WaitKey(10)
    else:
        while counter_vid<25 and vid==1:
            Camera0()
            Camera1()
            counter_vid += 1
            print(counter_vid)
            cv.WaitKey(10)        

    cv.WaitKey(25)
    counter_vid = 0
    counter += 1
    print('End of Loop Counter')
    print(counter)
4

1 回答 1

2

你是对的缓冲区填满。您需要一种方法来始终从缓冲区中获取最新值。

我建议更换这个:

status = arduino.readline()

有了这个:

status = getLatestStatus()

然后通过您的相机功能进一步向上:

def getLatestStatus():
    while arduino.inWaiting() > 0:
        status = arduino.readline()
    return status

这个函数 getLatestStatus 每次调用都会遍历整个缓冲区,只返回最新的状态,忽略同时返回的所有状态。

您的另一个选择是修改您的 arduino 的“固件”以在每次收到命令时返回距离传感器值(例如“M\n”),这样您就不必担心缓冲区问题。这就是我为 arduino 供电的超声波测距设备所做的,我觉得它比“读取整个缓冲区”解决方案更清洁。不过,它会在您的距离测量中引入更多延迟。

于 2012-12-10T23:04:26.843 回答