【问题标题】:Raspberry Pi Python loop stop to workRaspberry Pi Python 循环停止工作
【发布时间】:2016-04-07 11:23:22
【问题描述】:

我操纵传感器:HC SR04 来捕捉距离。 我是 Python 和 RPI 的新手。我的代码工作,我在一段时间内捕捉距离,但有一刻脚本停止......

我的代码:

GPIO.setmode(GPIO.BCM)

GPIO_TRIGGER = 23
GPIO_ECHO = 24

GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)

def main():
    global state
    print("ultrasonic")
    while True:
        print "1s second refresh.."
        time.sleep(1)

        i = 0
        datas = []
        average = 0

        while i< 1:
            GPIO.output(GPIO_TRIGGER, False)

            time.sleep(C.time['count'])
            GPIO.output(GPIO_TRIGGER, True)
            time.sleep(0.00001)
            GPIO.output(GPIO_TRIGGER, False)

            while GPIO.input(GPIO_ECHO) == 0:
                start = time.time()

            while GPIO.input(GPIO_ECHO) == 1:
                stop = time.time()

            distance = (stop-start) * 17000

            print "Distance : %.1f" % distance

        average = F.getAverage(datas)
        print "Average: %.1f" % average

    GPIO.cleanup()

代码到此为止

while GPIO.input(GPIO_ECHO) == 0:
                start = time.time()

解决方案:示例超时:

now = time()

while GPIO.input(self.gpio_echo) == 0 and time()-now<waitTime:
    pass

【问题讨论】:

  • 这个问题太宽泛,无法提供帮助....但这里有一些可能的原因:获取万用表...在代码运行时测量引脚和接地,你明白了吗有任何波动吗?还是总是零? (While x==0) 似乎总是正确的。然后,查看专用于raspberry microprocessors 的 stackoverflow 论坛

标签: python while-loop raspberry-pi


【解决方案1】:

我也在纠结这个传感器。我的代码执行与您的类似,我不需要超时即可工作。 我能找到的一个区别是:

while i< 1:
        GPIO.output(GPIO_TRIGGER, False)

        time.sleep(C.time['count'])

我不知道这里的睡眠时间有多长,但这可能是导致问题的原因。如果它与我的相似,将触发器设置为 false 将直接在设置输入/输出引脚之后,然后等待两秒钟以消除噪音。你的等待时间可能会更短,我不知道。在发送脉冲之前,无需再次将触发器设置为 false,我不知道,但这可能会导致错误启动。我会将其更改为类似于我的工作,然后在 while 循环中将设置删除为 false。

GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
GPIO.output(GPIO_TRIGGER, False)
print("Waiting for sensor to settle\n")
time.sleep(2)

我不确定这是否会在不需要超时的情况下解决问题,但我似乎不需要。


我编写了一个用于制作传感器对象的模块,然后允许编写一些更具可读性的脚本。我对 python 也很陌生,根本不是一个有经验的程序员,所以有趣的错误可能存在于某处,但如果你想使用它或只是比较代码,它就在下面:

#! /usr/bin/python3

# dist.py this is a module for objectifying an ultrasonic distance sensor.

import RPi.GPIO as GPIO
import time


class Distancer(object):
    #init takes an input of one GPIO for trigger and one for echo and creates the object,
    #it searches for a calibration file in the working directory (name)Const.txt, if none
    #is found it will initiate a calibration
    def __init__(self, trig, cho, name):
        self.trigger = trig
        self.echo = cho
        self.name = name
        self.filename = self.name + 'Const.txt'
        GPIO.setup(self.trigger, GPIO.OUT)
        GPIO.setup(self.echo, GPIO.IN)
        GPIO.output(self.trigger, False)
        print("Waiting for sensor to calm down")
        time.sleep(2)

        try:
            with open(self.filename, "r") as inConst:
                self.theConst = int(inConst.read())
        except (OSError, IOError) as e:
            print("Not calibrated, initializing calibration")
            self.calibrate()
            with open(self.filename, "r") as inConst:
                self.theConst = int(inConst.read())


    #Returns the echo time
    def measureTime(self):
        GPIO.output(self.trigger, True)
        time.sleep(0.00001)
        GPIO.output(self.trigger, False)

        while GPIO.input(self.echo) == 0:
            pulse_start = time.time()
        while GPIO.input(self.echo) == 1:
            pulse_end = time.time()

        pulse_duration = pulse_end - pulse_start
        return pulse_duration


    #Returns a distance in cm        
    def measure(self):  
        return self.measureTime() * self.theConst


    #Makes you set up the sensor at 3 different distances in order to find the
    #relation between pulse time and distance, it creates the file (name)Const.txt
    #in the working directory and stores the constant there.
    def calibrate(self):

        ten = []
        thirty = []
        seventy = []

        print("Make distance 10 cm, enter when ready")
        input()
        for i in range(30):
            ten.append(10/self.measureTime())
            time.sleep(0.2)

        print("Make distance 30 cm, enter when ready")
        input()
        for i in range(30):
            thirty.append(30/self.measureTime())
            time.sleep(0.2)

        print("Make distance 70 cm, enter when ready")
        input()
        for i in range(30):
            seventy.append(70/self.measureTime())
            time.sleep(0.2)

        allTime = ten + thirty + seventy
        theOne = 0.0
        for i in range(90):
            theOne = theOne + allTime[i]
        theOne = theOne / 90

        with open(self.filename, "w") as inConst:
                inConst.write(str(round(theOne)))


    #Will continually check distance with a given interval until something reaches the
    #treshold (cm), takes an argument to set wether it should check for something being
    #nearer(near) or farther(far) than the treashold. Returns True when treshold is reached. 
    def distWarn(self, nearfar, treashold):
        if nearfar.lower() == "near":
            while True:
                if self.measure() < treashold:
                    return True
                    break
                time.sleep(0.2)

        if nearfar.lower() == "far":
            while True:
                if self.measure() > treashold:
                    return True
                    break
                time.sleep(0.2)             


    #Will measure with a second interval and print the distance
    def keepGoing(self):
        while True:
            try:
                print(str(round(self.measure())) + ' cm')
                time.sleep(1)
            except KeyboardInterrupt:
                print("Won't keep going")
                break

我已经用下面的代码运行它来测试它,一切似乎都正常。第一次运行时,它会提示您通过将传感器放置在与某物不同的距离来校准传感器。

#! /usr/bin/python3

import RPi.GPIO as GPIO
import time
import dist as distancer

GPIO.setmode(GPIO.BOARD)
TRIG = 16
ECHO = 18

dist = distancer.Distancer(TRIG, ECHO, 'dist')

def main():
    global dist
    print(str(round(dist.measureTime(),5)) + ' s')  
    print(str(round(dist.measure())) + ' cm')

    dist.distWarn('near', 10)
    print('Warning, something nearer than 10 cm at ' + time.asctime( time.localtime(time.time()) ))

    dist.distWarn('far', 10)
    print('Warning, something further than 10 cm at ' + time.asctime( time.localtime(time.time()) ))


    dist.keepGoing()
    GPIO.cleanup()
    print('Fin')


if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        GPIO.cleanup()
        print("Exiting")
        time.sleep(1)

【讨论】:

    【解决方案2】:

    我很确定你想要

    while GPIO.input(GPIO_ECHO)==GPIO.LOW:
        start = time.time()
    
    while GPIO.input(GPIO_ECHO) == GPIO.HIGH:
        stop = time.time()
    

    我不认为 GPIO.input 自然地返回零或一,不过你可以测试一下。

    【讨论】:

      【解决方案3】:

      不是真的,我认为我失去了信号,我会尝试超时

      while GPIO.input(GPIO_ECHO)==GPIO.LOW:
          start = time.time()
      

      我认为我的程序无限期地等待一个信号,但他一直停留在 0

      【讨论】:

        【解决方案4】:

        我知道这是一个老问题。这个问题https://raspberrypi.stackexchange.com/questions/41159/...

        中描述了问题的原因

        解决方案是像 OP 一样在 while 循环中添加一个超时,类似于:

        # If a reschedule occurs or the object is very close
        # the echo may already have been received in which case
        # the following will loop continuously.
        count=time.time()
        while GPIO.input(GPIO_ECHO)==0 and time.time()-count<0.1:
           start = time.time()
        

        ...

        # if an object is not detected some devices do not
        # lower the echo line in which case the following will
        # loop continuously.
        stop = time.time()
        count=time.time()
        while GPIO.input(GPIO_ECHO)==1 and time.time()-count<0.1:
           stop = time.time()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-12-05
          • 1970-01-01
          • 2015-12-08
          • 1970-01-01
          • 2023-01-03
          • 1970-01-01
          • 2021-01-10
          • 1970-01-01
          相关资源
          最近更新 更多