Python Forum
need help with ultrasonic sensor code
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
need help with ultrasonic sensor code
#1
Hello guys. On my raspberry pi I have a hc-sr04 ultrasonic sensor, now I want to run a sh script, when the sensor measurement is below 10cm. Here is my Code, but it doesnt work. It only executes the code when I press ctrl c. PS Iam new to python

#!/usr/bin/env python

import time
import RPi.GPIO as GPIO
import os

GPIOTrigger = 23
GPIOEcho    = 24



def MesseDistanz():
    
    GPIO.output(GPIOTrigger, True)

    
    time.sleep(0.00001)

    
    GPIO.output(GPIOTrigger, False)

    
    StartZeit = time.time()
    StopZeit = StartZeit

    
    while GPIO.input(GPIOEcho) == 0:
        StartZeit = time.time()

   
    while GPIO.input(GPIOEcho) == 1:
        StopZeit = time.time()

    
    SignalLaufzeit = StopZeit - StartZeit
    Distanz = (SignalLaufzeit/2) * 34350

    return [Distanz, (SignalLaufzeit*1000/2)]



def main():


    try:
        while True:
            Ergebnis = MesseDistanz()
            print("Gemessene Entfernung: %.1f cm (Signallaufzeit: %.4fms)" % (Ergebnis[0], Ergebnis[1]))
            time.sleep(1)

   
    except KeyboardInterrupt:
        print("Messung abgebrochen")
        GPIO.cleanup()

if __name__ == '__main__':
    
    GPIO.setmode(GPIO.BCM)

    
    GPIO.setup(GPIOTrigger, GPIO.OUT)
    GPIO.setup(GPIOEcho, GPIO.IN)

    
    GPIO.output(GPIOTrigger, False)

   
    main()


if 0 < 10:
	os.system('. /home/pi/test.sh')
Reply
#2
After you press CTRL+C the while loop at line 46 will break and your function main() will exit. Then come this part:
if 0 < 10:
    os.system('. /home/pi/test.sh')
Where your script is called.
So if you want that the script runs along with the US sensor outputs, it has to be inside the while loop.
PS: This condition of your "if" will be always True.
Reply
#3
(Jun-28-2018, 02:01 PM)gontajones Wrote: After you press CTRL+C the while loop at line 46 will break and your function main() will exit. Then come this part:
if 0 < 10:
    os.system('. /home/pi/test.sh')
Where your script is called.
So if you want that the script runs along with the US sensor outputs, it has to be inside the while loop.
PS: This condition of your "if" will be always True.


thanks for your,what loop do you suggest me, because as far as I know there are only for while and else loops. And the problem is that the sh script can only execute one time so while would work i guess.

(Jun-28-2018, 02:15 PM)mpmm366 Wrote:
(Jun-28-2018, 02:01 PM)gontajones Wrote: After you press CTRL+C the while loop at line 46 will break and your function main() will exit. Then come this part:
if 0 < 10:
    os.system('. /home/pi/test.sh')
Where your script is called.
So if you want that the script runs along with the US sensor outputs, it has to be inside the while loop.
PS: This condition of your "if" will be always True.


thanks for your,what loop do you suggest me, because as far as I know there are only for while and else loops. And the problem is that the sh script can only execute one time so while would work i guess.
would not work*
Reply
#4
Maybe something like this...using a control flag (run_script) to avoid multiple calls of test.sh.

def main():

    try:
        run_script = True
        while True:
            Ergebnis = MesseDistanz()
            print("Gemessene Entfernung: %.1f cm (Signallaufzeit: %.4fms)" % (Ergebnis[0], Ergebnis[1]))
            if Ergebnis[0] < 10 and run_script:
                os.system('/home/pi/test.sh')
                run_script = False
            if Ergebnis[0] >= 10:
                run_script = True
            time.sleep(1)

    except KeyboardInterrupt:
        print("Messung abgebrochen")
        GPIO.cleanup()
Reply
#5
Polling an input will cause jitter. An event detection of a RISING edge should help.
First you assign the sent_time, then you activate the output. Ping is sending now....
After the rising edge has been detected, assign the time to an attribute and set the output to False.

The implementation of it can look like this:

import time
import RPi.GPIO as gpio


class UltraSonicSensor:

    def __init__(self, send_pin, recv_pin):
        self.send_pin = send_pin
        self.recv_pin = recv_pin
        self.ping_received = 0.0
        self.setup()
        
    def __enter__(self):
        return self
    
    def __exit__(self, *args):
        gpio.cleanup()
    
    def setup(self):
        gpio.setmode(gpio.BCM)
        gpio.setup(self.send_pin, gpio.OUT)
        gpio.setup(self.recv_pin, gpio.IN)
        # register an event
        # if the event happens, the callback is called
        gpio.add_event_detect(self.recv_pin, GPIO.RISING, callback=self.received, bouncetime=0)
        # maybe bounctime have to be changed
    
    def received(self, pin):
        self.ping_received = time.time()
        gpio.output(self.send_pin, False)
    
    def ping(self):
        """
        Returns the time in seconds.
        """
        ping_sent = time.time()
        gpio.output(self.send_pin, True)      
        time.sleep(0.5)
        return self.ping_received - ping_sent
Code is not tested and I imported RPi.GPIO as gpio.
I don't like uppercase modules. The important methods are setup and received.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#6
(Jun-28-2018, 02:27 PM)gontajones Wrote: Maybe something like this...using a control flag (run_script) to avoid multiple calls of test.sh.

def main():

    try:
        run_script = True
        while True:
            Ergebnis = MesseDistanz()
            print("Gemessene Entfernung: %.1f cm (Signallaufzeit: %.4fms)" % (Ergebnis[0], Ergebnis[1]))
            if Ergebnis[0] < 10 and run_script:
                os.system('/home/pi/test.sh')
                run_script = False
            if Ergebnis[0] >= 10:
                run_script = True
            time.sleep(1)

    except KeyboardInterrupt:
        print("Messung abgebrochen")
        GPIO.cleanup()
thank you for your help. It works perfect. Another question. How can I add another ultrasoinc sensor to the same thing?
Reply
#7
The best way is to use the @DeaD_EyE class.

To use your code, you can do something like:
#!/usr/bin/env python

import time
import RPi.GPIO as GPIO
import os

US1_GPIOTrigger = 23
US1_GPIOEcho = 24

# Change 0 to the GPIO of the US2
US2_GPIOTrigger = 0
US2_GPIOEcho = 0


def MesseDistanz(GPIOTrigger, GPIOEcho):

    GPIO.output(GPIOTrigger, True)

    time.sleep(0.00001)

    GPIO.output(GPIOTrigger, False)

    StartZeit = time.time()
    StopZeit = StartZeit

    while GPIO.input(GPIOEcho) == 0:
        StartZeit = time.time()

    while GPIO.input(GPIOEcho) == 1:
        StopZeit = time.time()

    SignalLaufzeit = StopZeit - StartZeit
    Distanz = (SignalLaufzeit / 2) * 34350

    return [Distanz, (SignalLaufzeit * 1000 / 2)]


def check_distance(distance, run_script):

    if distance < 10 and run_script:
        os.system('/home/pi/test.sh')
        run_script = False
    if distance >= 10:
        run_script = True

    return run_script


def main():

    try:
        US1_run_script = True
        US2_run_script = True
        while True:
            Ergebnis = MesseDistanz(US1_GPIOTrigger, US1_GPIOEcho)
            print("Gemessene Entfernung 1: %.1f cm (Signallaufzeit: %.4fms)" % (Ergebnis[0], Ergebnis[1]))
            US1_run_script = check_distance(Ergebnis[0], US1_run_script)

            Ergebnis = MesseDistanz(US2_GPIOTrigger, US2_GPIOEcho)
            print("Gemessene Entfernung 2: %.1f cm (Signallaufzeit: %.4fms)" % (Ergebnis[0], Ergebnis[1]))
            US2_run_script = check_distance(Ergebnis[0], US2_run_script)

            time.sleep(1)

    except KeyboardInterrupt:
        print("Messung abgebrochen")
        GPIO.cleanup()


if __name__ == '__main__':

    GPIO.setmode(GPIO.BCM)

    # UltraSonic 1
    GPIO.setup(US1_GPIOTrigger, GPIO.OUT)
    GPIO.setup(US1_GPIOEcho, GPIO.IN)
    GPIO.output(US1_GPIOTrigger, False)

    # UltraSonic 2
    GPIO.setup(US2_GPIOTrigger, GPIO.OUT)
    GPIO.setup(US2_GPIOEcho, GPIO.IN)
    GPIO.output(US2_GPIOTrigger, False)

    main()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  sensor code that starts heater chano 3 3,094 Jun-05-2019, 10:54 AM
Last Post: michalmonday
  Code Wireless Temperature sensor and send sensor readings to google sheet jenkins43 0 2,168 Nov-29-2018, 12:44 PM
Last Post: jenkins43
  RPi with IR Sensor pimlicosnail 1 2,172 Jun-24-2018, 08:53 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

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