Posts: 3
Threads: 1
Joined: Jun 2018
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')
Posts: 333
Threads: 4
Joined: Jun 2018
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.
Posts: 3
Threads: 1
Joined: Jun 2018
Jun-28-2018, 02:15 PM
(This post was last modified: Jun-28-2018, 02:26 PM by mpmm366.)
(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*
Posts: 333
Threads: 4
Joined: Jun 2018
Jun-28-2018, 02:27 PM
(This post was last modified: Jun-28-2018, 02:29 PM by gontajones.)
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()
Posts: 2,125
Threads: 11
Joined: May 2017
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.
Posts: 3
Threads: 1
Joined: Jun 2018
(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?
Posts: 333
Threads: 4
Joined: Jun 2018
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()
|