0

I'm trying to connect three separate ultrasonic sensors (HC-SR04) to my Raspberry Pi that's running Ubuntu Mate. The goal is to read the input from the sensors and to send it to a LAMP powered server. The system works fine with one sensor but I'm not sure how to connect multiple sensors to the system. At the moment the code I'm using is the following:

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()

Right now this code does run in terminal but it doesn't work. It works fine with one sensor but after I changed the code to include two Echos and Distances it stopped working. This is my first time using python and I know this code probably has several errors. I would really appreciate if anybody could tell me if I'm on the right track and how to continue from here!

1 Answers1

1

You have too much duplicated code. If you want to change your code so that multiple distances can be checked, you should make a generic distance function that takes as argument a sensor and checks it.

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

Then you can call this function multiple times for all your sensors:

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()

When programming, you should never copy and paste code multiple times when you want to do something multiple times. There are programming constructs for that called loops. Here, we use a for loop:

for sensor in sensors_to_test:
    dist = distance(sensor)

Always encapsulate your logic into functions that takes arguments, and use them instead of copying code!


PS: In python we never use if __name__ == '__main__': more than once in a file, and we use it only at the end of an executable python script. It is NOT a main function as in C or Java. It's just a clever trick so that the code in a python script is executed when you call it from command line. Check out this question if you want to know more : What does if __name__ == "__main__": do?

Zoé Martin
  • 1,887
  • 1
  • 16
  • 28