【问题标题】:raspi SerialException: device reports readiness to read but returned no data. For automated RC carraspi SerialException:设备报告已准备好读取但未返回任何数据。用于自动遥控车
【发布时间】:2019-09-26 06:05:27
【问题描述】:

我一直在关注“使用 Raspberry Pi 和 Arduino 开始机器人学”一书,但遇到了代码问题。我对编程很陌生,并且正在使用这本书来熟悉 Pi、Arduino 和 Python。这本书有些含糊,没有提供解决问题的方法。

Traceback (most recent call last):
  File "/home/Danberry/Roject/pi_roamer_01.py", line 80, in <module>
    val = ser.readline().decode('utf-8')
  File "/home/Danberry/.local/lib/python2.7/site-packages/serial/serialposix.py", line 501, in read
    'device reports readiness to read but returned no data '
SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

我已确认一切都已正确连接并且可以单独工作。现在的问题是让树莓派读取它。

import serial
import time
import random

from Adafruit_MotorHAT import Adafruit_MotorHAT as amhat
from Adafruit_MotorHAT import Adafruit_DCMotor as adamo

# create motor objects
motHAT = amhat(addr=0x60)
mot1 = motHAT.getMotor(1)
mot2 = motHAT.getMotor(2)
mot3 = motHAT.getMotor(3)
mot4 = motHAT.getMotor(4)

# open serial port
ser = serial.Serial('/dev/ttyACM0', 115200)

# create variables
# sensors
distMid = 0.0
distLeft = 0.0
distRight = 0.0

# motor multipliers
m1Mult = 1.0
m2Mult = 1.0
m3Mult = 1.0
m4Mult = 1.0

# distance threshold
distThresh = 12.0
distCutOff = 30.0

# speeds
speedDef = 200
leftSpeed = speedDef
rightSpeed = speedDef
turnTime = 1.0
defTime = 0.1
driveTime = defTime

def driveMotors(leftChnl = speedDef, rightChnl = speedDef, duration = defTime):
    # determine the speed of each motor by multiplying
    # the channel by the motors multiplier
    m1Speed = leftChnl * m1Mult
    m2Speed = leftChnl * m2Mult
    m3Speed = rightChnl * m3Mult
    m4Speed = rightChnl * m4Mult

    # set each motor speed. Since the speed can be a
    # negative number, we take the absolute value
    mot1.setSpeed(abs(int(m1Speed)))
    mot2.setSpeed(abs(int(m2Speed)))
    mot3.setSpeed(abs(int(m3Speed)))
    mot4.setSpeed(abs(int(m4Speed)))

    # run the motors. if the channel is negative, run
    # reverse. else run forward
    if(leftChnl < 0):
        mot1.run(amhat.BACKWARD)
        mot2.run(amhat.BACKWARD)
    else:
        mot1.run(amhat.FORWARD)
        mot2.run(amhat.FORWARD)

    if (rightChnl > 0):
        mot3.run(amhat.BACKWARD)
        mot4.run(amhat.BACKWARD)
    else:
        mot3.run(amhat.FORWARD)
        mot4.run(amhat.FORWARD)

    # wait for duration
    time.sleep(duration)

try:
    while 1:
        # read the serial port
        val = ser.readline().decode('utf=8')
        print val

        # parse the serial string
        parsed = val.split(',')
        parsed = [x.rstrip() for x in parsed]

        # only assign new values if there are
        # three or more available
        if(len(parsed)>2):
            distMid = float(parsed[0] + str(0))
            distLeft = float(parsed[1] + str(0))
            distRight = float(parsed[2] + str(0))

        # apply cutoff distance
        if(distMid > distCutOff):
            distMid = distCutOff
        if(distLeft > distCutOff):
            distLeft = distCutOff
        if(distRight > distCutOff):
            distRight = distCutOff

        # reset driveTime
        driveTime = defTime

        # if obstacle to left, steer right by increasing
        # leftSpeed and running rightSpeed negative defSpeed
        # if obstacle to right, steer to left by increasing
        # rightSpeed and running leftSpeed negative
        if(distLeft <= distThresh):
            leftSpeed = speedDef
            rightSpeed = -speedDef
        elif (distRight <= distThresh):
            leftSpeed = -speedDef
            rightSpeed = speedDef
        else:
            leftSpeed = speedDef
            rightSpeed = speedDef

        # if obstacle dead ahead, stop then turn toward most
        # open direction. if both directions open, turn random
        if(distMid <= distThresh):
            # stop
            leftSpeed = 0
            rightSpeed = 0
            driveMotors(leftSpeed, rightSpeed, 1)
            time.sleep(1)
            leftSpeed = -150
            rightSpeed = -150
            driveMotors(leftSpeed, rightSpeed, 1)
            # determine preferred direction. if distLeft >
            # distRight, turn left. if distRight > distLeft,
            # turn right. if equal, turn random
            dirPref = distRight - distLeft
            if(dirPref == 0):
                dirPref = random.random()
            if(dirPref < 0):
                leftSpeed = -speedDef
                rightSpeed = speedDef
            elif(dirPref > 0):
                leftSpeed = speedDef
                rightSpeed = -speedDef
            driveTime = turnTime

        # drive the motors
        driveMotors(leftSpeed, rightSpeed, driveTime)
        ser.flushInput()

except KeyboardInterrupt:
    mot1.run(amhat.RELEASE)
    mot2.run(amhat.RELEASE)
    mot3.run(amhat.RELEASE)
    mot4.run(amhat.RELEASE)

也许是某个地方的缩进问题?我已经玩了几个小时的代码,但还没有真正到达任何地方。如果你们中的任何人能提供帮助,那就太棒了!

【问题讨论】:

    标签: python arduino raspberry-pi serial-port


    【解决方案1】:

    听起来可能应该通过串行提供数据的任何东西都没有为您的程序提供足够频繁的数据。我很想抓住这个错误,然后再试一次(也许先等一会儿)。所以不是

    try:
        while 1:
            # read the serial port
            val = ser.readline().decode('utf=8')
            print val
    

    from time import sleep
    ...
    try:
        while 1:
            # read the serial port
            try:
                val = ser.readline().decode('utf=8')
                print val
            except SerialException:
                sleep(0.01)  # Maybe don't do this, or mess around with the interval
                continue
    

    【讨论】:

    • 我实现了 try... except 没有睡眠的块(睡眠不断给出错误)并且它完全停止给我错误...问题是什么都没有发生。所以我们克服了错误,但仍然没有任何进展。
    • 你没有很明确地说出连续剧的另一面是什么,是 Arduino 吗?如果是这样,您可以尝试降低两端的串行速度,看看是否有帮助。当然,请仔细检查您在串行连接的一侧使用的设置是否与另一侧相同,并且您的 Arduino 实际上正在发送内容。您可以尝试在 Pi 上运行串行终端以确认您可以使用您选择的设置与 Arduino 通信吗?
    猜你喜欢
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    相关资源
    最近更新 更多