Python Forum
Controller Buzzer as Distance Decreases
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Controller Buzzer as Distance Decreases
#1
I have a raspberry pi and am trying to simulate something similar to backup sensors on a car. I have some ultrasonic sensors that turn on buzzer when value is between 100-50. I would like to make the buzzer beep faster as the distance value gets closer to 50. My problem is that since I'm trying to use multiple sensors and the code is running every .5 seconds that when it is in between my range the buzzer comes on as expected but it fires so many times that when your out of range it continues to fire because it is called so many time. Or at least that is what I think is happening. Pretty new to python and not a very good coder. Any help would be appreciated. Here is what I have so far.

#Libraries
import RPi.GPIO as GPIO
import time
from gpiozero import PWMLED
from time import sleep
from gpiozero import Buzzer

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

#Buzzer
GPIO_BEEP = Buzzer(18)


#set GPIO Pins
GPIO_TRIGGER = 23 #rx
GPIO_ECHO    = 24 #tx

#second sensor
GPIO2_TRIGGER = 25 #rx
GPIO2_ECHO = 8 #tx
 
#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
#second sensor
GPIO.setup(GPIO2_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO2_ECHO, GPIO.IN)

led = PWMLED(21) 
#led.value = 0    # off
#led.value = 0.2  # 20% brightness 
#led.value = 0.4  # 40% brightness 
#led.value = 0.6  # 60% brightness 
#led.value = 1    # full brightness


led2 = PWMLED(27) 
#led2.value = 0    # off
#led2.value = 0.2  # 20% brightness 
#led2.value = 0.4  # 40% brightness 
#led2.value = 0.6  # 60% brightness 
#led2.value = 1    # full brightness
#led.pulse()
#led2.pulse()
# led.blink(.1,.1)
# led2.blink(.1,.1)
# sleep(3)
# led.off()
# led2.off()
def distance():
    # 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 * 17150)
 
    return distance

def distance2():
    # set Trigger to HIGH
    GPIO.output(GPIO2_TRIGGER, True)
 
    # set Trigger after 0.01ms to LOW
    time.sleep(0.00001)
    GPIO.output(GPIO2_TRIGGER, False)
 
    StartTime = time.time()
    StopTime = time.time()
 
    # save StartTime
    while GPIO.input(GPIO2_ECHO) == 0:
        StartTime = time.time()
 
    # save time of arrival
    while GPIO.input(GPIO2_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
    distance2 = (TimeElapsed * 17150)
 
    return distance2

def ledbrightness(num):
    if num <= 60:
        brightness = 1
    elif num <= 200:
        brightness = .1
    else:
        brightness = 0
    return brightness

if __name__ == '__main__':
    try:
        while True:
            dist = "%.1f" % distance()
            led.value = ledbrightness(float(dist))
            if int(float(dist)) <= 100 and int(float(dist)) >= 50:
                speed = int(float(dist))/1000
                print("Speed:" + str(speed))
                GPIO_BEEP.beep(speed,speed)
            #print ("Measured Distance = %.1f cm" % dist)
            dist2 = "%.1f" % distance2()
            led2.value = ledbrightness(float(dist2))
            print(dist + " : " + dist2)
            time.sleep(.5)
 
        # Reset by pressing CTRL + C
    except KeyboardInterrupt:
        print("Measurement stopped by User")
        #GPIO.cleanup()
Reply
#2
The first thing that jumps out at me is that there is a lot of duplication in the functions distance and distance2 of which the names also give it away.
The only things that differ between them are trigger and echo so these can be passed into a single function.
def get_distance(trigger, echo):
    # set Trigger to HIGH
    GPIO.output(trigger, True)
  
    # set Trigger after 0.01ms to LOW
    time.sleep(0.00001)
    GPIO.output(trigger, False)
  
    StartTime = time.time()
    StopTime = time.time()
  
    # save StartTime
    while GPIO.input(echo) == 0:
        StartTime = time.time()
  
    # save time of arrival
    while GPIO.input(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 * 17150)
  
    return distance
then call it as follows
distance1 = get_distance(GPIO_TRIGGER, GPIO_ECHO)
distance2 = get_distance(GPIO2_TRIGGER, GPIO2_ECHO)
Reply
#3
thank you, that cleaned that up. Any ideas as to how I can prevent this beep code to get fired so much that it keeps going even after this statement is no longer true?

if int(float(dist)) <= 100 and int(float(dist)) >= 50:
                speed = int(float(dist))/1000
                print("Speed:" + str(speed))
                GPIO_BEEP.beep(speed,speed)
Reply
#4
Set a different beep speed when the distance is not inside that range.
I'm guessing you might want it to beep constantly when the distance is less than 50 and to not beep at all when greater than 100.
Reply
#5
Stopping turning the buzzer on does not turn it off. You need to stop the buzzer.

Why are dist and dist2 strings? You never use them as a string, so why convert a nice float to a string only to have to convert it back to a float whenever you use it? And why convert the float to an int? You never need the value as an int.

Use function arguments instead of duplicate code. distance and distance2 are the same function.
from time import sleep, time
import RPi.GPIO as GPIO
from gpiozero import PWMLED, Buzzer
 
GPIO.setmode(GPIO.BCM)
GPIO_BEEP = Buzzer(18)
GPIO_TRIGGER = 23 #rx
GPIO_ECHO = 24 #tx
GPIO2_TRIGGER = 25 #rx
GPIO2_ECHO = 8 #tx
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
GPIO.setup(GPIO2_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO2_ECHO, GPIO.IN)
 
led = PWMLED(21) 
led2 = PWMLED(27) 

def distance(trigger, echo):
    GPIO.output(trigger, True)
    sleep(0.00001)
    GPIO.output(trigger, False)
  
    while GPIO.input(echo) == 0:
        pass
    start_time = time()
  
    while GPIO.input(echo) == 1:
        pass
    return (time() - start_time) * 17150

def ledbrightness(num):
    if num <= 60:
        brightness = 1
    elif num <= 200:
        brightness = .1
    else:
        brightness = 0
    return brightness
 
if __name__ == '__main__':
    try:
        while True:
            dist = distance(GPIO_TRIGGER, GPIO_ECHO)
            led.value = ledbrightness(dist)
            
            if 50 < dist < 100: 
                speed = dist/1000
                print("Speed:", speed)
                GPIO_BEEP.beep(speed, speed)

            dist2 = distance(GPIO2_TRIGGER, GPIO2_ECHO)
            led2.value = ledbrightness(dist2)

            print(dist, " : ", dist2)
            time.sleep(0.5)
    except KeyboardInterrupt:
        print("Measurement stopped by User")
        #GPIO.cleanup()
Maybe the buzzer logic should be:
if dist < 100: 
    speed = max(0.5, dist/1000)
    GPIO_BEEP.beep(speed, speed)
else:
    GPIO_BEEP.off()
Reply
#6
Thanks, yeah I just took code from some some example and worked with it and being a crappy programmer I didn't even think about the int & string thing. I will give that a try.

(Oct-29-2021, 04:05 PM)deanhystad Wrote: Stopping turning the buzzer on does not turn it off. You need to stop the buzzer.

Why are dist and dist2 strings? You never use them as a string, so why convert a nice float to a string only to have to convert it back to a float whenever you use it? And why convert the float to an int? You never need the value as an int.

Use function arguments instead of duplicate code. distance and distance2 are the same function.
from time import sleep, time
import RPi.GPIO as GPIO
from gpiozero import PWMLED, Buzzer
 
GPIO.setmode(GPIO.BCM)
GPIO_BEEP = Buzzer(18)
GPIO_TRIGGER = 23 #rx
GPIO_ECHO = 24 #tx
GPIO2_TRIGGER = 25 #rx
GPIO2_ECHO = 8 #tx
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
GPIO.setup(GPIO2_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO2_ECHO, GPIO.IN)
 
led = PWMLED(21) 
led2 = PWMLED(27) 

def distance(trigger, echo):
    GPIO.output(trigger, True)
    sleep(0.00001)
    GPIO.output(trigger, False)
  
    while GPIO.input(echo) == 0:
        pass
    start_time = time()
  
    while GPIO.input(echo) == 1:
        pass
    return (time() - start_time) * 17150

def ledbrightness(num):
    if num <= 60:
        brightness = 1
    elif num <= 200:
        brightness = .1
    else:
        brightness = 0
    return brightness
 
if __name__ == '__main__':
    try:
        while True:
            dist = distance(GPIO_TRIGGER, GPIO_ECHO)
            led.value = ledbrightness(dist)
            
            if 50 < dist < 100: 
                speed = dist/1000
                print("Speed:", speed)
                GPIO_BEEP.beep(speed, speed)

            dist2 = distance(GPIO2_TRIGGER, GPIO2_ECHO)
            led2.value = ledbrightness(dist2)

            print(dist, " : ", dist2)
            time.sleep(0.5)
    except KeyboardInterrupt:
        print("Measurement stopped by User")
        #GPIO.cleanup()
Maybe the buzzer logic should be:
if dist < 100: 
    speed = max(0.5, dist/1000)
    GPIO_BEEP.beep(speed, speed)
else:
    GPIO_BEEP.off()
Reply
#7
I think this got me going, will do more testing. Thanks for all the help
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Python and DMX (aka, light controller) ScottAF 4 2,666 Apr-06-2023, 07:09 PM
Last Post: ScottAF
  How can flask find the controller? 3lnyn0 3 1,321 Jul-08-2022, 10:05 AM
Last Post: Larz60+
  Auto re-pair / re-sync Controller via Script? User3000 2 2,329 Nov-30-2020, 11:42 AM
Last Post: User3000
  Tuning PID controller Sancho_Pansa 4 4,386 Nov-09-2020, 07:51 AM
Last Post: Sancho_Pansa
  Xbox Controller arki 0 1,717 Jun-30-2020, 10:32 AM
Last Post: arki
  Please help! Akai APC20 midi controller script versusliveact 0 2,136 Feb-14-2020, 05:37 AM
Last Post: versusliveact
  Visualize Geo Map/Calculate distance zarize 1 1,897 Dec-05-2019, 08:36 PM
Last Post: Larz60+
  managing command codes for external controller box Oolongtea 0 1,913 Sep-19-2019, 08:32 AM
Last Post: Oolongtea
  euclidean distance jenya56 3 2,814 Mar-29-2019, 02:56 AM
Last Post: scidam
  organizing by distance gonzo620 7 3,921 Oct-16-2018, 01:41 AM
Last Post: stullis

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020