python - 在 Ubuntu Mate (Raspberry Pi 3) 和 python 中使用多个超声波传感器

标签 python ubuntu raspberry-pi3

我正在尝试将三个独立的超声波传感器 (HC-SR04) 连接到运行 Ubuntu Mate 的 Raspberry Pi。目标是从传感器读取输入并将其发送到 LAMP 供电的服务器。该系统与一个传感器一起工作正常,但我不确定如何将多个传感器连接到系统。目前我使用的代码如下:

import RPi.GPIO as GPIO
import time

#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)

#set GPIO Pins
GPIO_TRIGGER = 16
GPIO_ECHO = 21
GPIO_ECHO2 = 24

#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
GPIO.setup(GPIO_ECHO2, GPIO.IN)


#MySQL
import MySQLdb

dbConn = MySQLdb.connect("127.0.0.1","root","","test") or die ("could not connect to db")
cursor = dbConn.cursor()

def distance1():
    # set Trigger to HIGH
    GPIO.output(GPIO_TRIGGER, True)

    # set Trigger after 0.01ms to LOW
    time.sleep(0.00001)
    GPIO.output(GPIO_TRIGGER, False)

    StartTime = time.time()
    StopTime = time.time()

    # save StartTime
    while GPIO.input(GPIO_ECHO) == 0:
        StartTime = time.time()

    # save time of arrival
    while GPIO.input(GPIO_ECHO) == 1:
        StopTime = time.time()

    # time difference between start and arrival
    TimeElapsed = StopTime - StartTime
    # multiply with the sonic speed (34300 cm/s)
    # and divide by 2, because there and back
    distance = (TimeElapsed * 34300) / 2

    return distance1

    def distance2():
            # set Trigger to HIGH
            GPIO.output(GPIO_TRIGGER, True)

            # set Trigger after 0.01ms to LOW
            time.sleep(0.00001)
            GPIO.output(GPIO_TRIGGER, False)

            StartTime = time.time()
            StopTime = time.time()

            # save StartTime
            while GPIO.input(GPIO_ECHO2) == 0:
                StartTime = time.time()

            # save time of arrival
            while GPIO.input(GPIO_ECHO2) == 1:
                StopTime = time.time()

            # time difference between start and arrival
            TimeElapsed = StopTime - StartTime
            # multiply with the sonic speed (34300 cm/s)
            # and divide by 2, because there and back
            distance = (TimeElapsed * 34300) / 2

            return distance2



    if __name__ == '__main__':
            try:
                while True:
                    dist = distance1()
                    if distance1()  < 20:
                        print ("1")
                        cursor.execute("INSERT INTO TILA (anturi, status) values (1, 0)")
                        dbConn.commit()
                    else:
                        print ("0")
                        cursor.execute("INSERT INTO TILA (anturi, status) values (1, 1)")
                        dbConn.commit()
                    time.sleep(1)
                        # Reset by pressing CTRL + C
            except KeyboardInterrupt:
                    print("Measurement stopped by User")
                    cursor.close()
                    GPIO.cleanup()


                    if __name__ == '__main__':
                        try:
                            while True:
                                dist = distance2()
                                if distance2()  < 20:
                                    print ("1")
                                    cursor.execute("INSERT INTO TILA (anturi, status) values (1, 0)")
                                    dbConn.commit()
                                else:
                                    print ("0")
                                    cursor.execute("INSERT INTO TILA (anturi, status) values (1, 1)")
                                    dbConn.commit()
                                time.sleep(1)

                # Reset by pressing CTRL + C
                        except KeyboardInterrupt:
                                print("Measurement stopped by User")
                                cursor.close()
                                GPIO.cleanup()

现在这段代码确实在终端中运行,但它不起作用。它适用于一个传感器,但在我更改代码以包含两个回声和距离后,它停止工作。这是我第一次使用 python,我知道这段代码可能有几个错误。如果有人能告诉我我是否走在正确的轨道上以及如何从这里继续,我将不胜感激!

最佳答案

你有太多重复的代码。
如果你想改变你的代码以便可以检查多个距离,你应该做一个通用的 distance将传感器作为参数并检查它的函数。

def distance(gpio_echo):
    # set Trigger to HIGH
    GPIO.output(GPIO_TRIGGER, True)

    # set Trigger after 0.01ms to LOW
    time.sleep(0.00001)
    GPIO.output(GPIO_TRIGGER, False)

    StartTime = time.time()
    StopTime = time.time()

    # save StartTime
    while GPIO.input(gpio_echo) == 0:
        StartTime = time.time()

    # save time of arrival
    while GPIO.input(gpio_echo) == 1:
        StopTime = time.time()

    # time difference between start and arrival
    TimeElapsed = StopTime - StartTime
    # multiply with the sonic speed (34300 cm/s)
    # and divide by 2, because there and back
    dist = (TimeElapsed * 34300) / 2

    return dist

然后,您可以为所有传感器多次调用此函数:
if __name__ == '__main__':

    sensors_to_test = [GPIO_ECHO, GPIO_ECHO2]

    try:
        while True:
            for sensor in sensors_to_test:
                dist = distance(sensor)
                if dist < 20:
                    print ("1")
                    cursor.execute("INSERT INTO TILA (anturi, status) values (1, 0)")
                    dbConn.commit()
                else:
                    print ("0")
                    cursor.execute("INSERT INTO TILA (anturi, status) values (1, 1)")
                    dbConn.commit()
            time.sleep(1)

    except KeyboardInterrupt:
        # Reset by pressing CTRL + C
        print("Measurement stopped by User")
        cursor.close()
        GPIO.cleanup()

编程时,当你想多次做某事时,你不应该多次复制和粘贴代码。有一些称为循环的编程结构。在这里,我们使用了一个 for 循环:
for sensor in sensors_to_test:
    dist = distance(sensor)

始终将您的逻辑封装到带有参数的函数中,并使用它们而不是复制代码!

PS:在python中我们从不使用if __name__ == '__main__':在一个文件中不止一次,我们只在可执行 python 脚本的末尾使用它。
它不是 C 或 Java 中的 main 函数。这只是一个聪明的技巧,这样当你从命令行调用它时,python 脚本中的代码就会被执行。
如果您想了解更多信息,请查看此问题:What does if __name__ == "__main__": do?

关于python - 在 Ubuntu Mate (Raspberry Pi 3) 和 python 中使用多个超声波传感器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47508939/

相关文章:

raspberry-pi - 使用 Raspberry PI 检测 HDMI 输入当前是否为电视的选定源

raspberry-pi - 树莓派 VNC 连接失败

python - 使用 Python click 命令调用带有可变参数的类方法

python - 为 Pandas 中的一组列设置新值

ubuntu - gruntjs 的基本安装问题 - 与 Bootstrap 一起使用

java - Jboss6.1抛出UnsupportedClassVersionError 51但jar是由Jdk5编译的

linux - Raspberry Pi 3-除通过以太网外无互联网; WIFI上网但无法使用互联网

python - 当 Python 中的输入量很大时如何有效地找到一个范围内的完美平方

python - 如何动态代理类的方法?

Ubuntu 中的 OpenGL/SDL 问题